EllipsoidTangentPlane-2abe082d.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /**
  2. * Cesium - https://github.com/CesiumGS/cesium
  3. *
  4. * Copyright 2011-2020 Cesium Contributors
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Columbus View (Pat. Pend.)
  19. *
  20. * Portions licensed separately.
  21. * See https://github.com/CesiumGS/cesium/blob/main/LICENSE.md for full licensing details.
  22. */
  23. define(['exports', './AxisAlignedBoundingBox-7b93960a', './Matrix2-d35cf4b5', './RuntimeError-8952249c', './defaultValue-81eec7ed', './IntersectionTests-a25e058d', './Plane-24f22488', './Transforms-f0a54c7b'], (function (exports, AxisAlignedBoundingBox, Matrix2, RuntimeError, defaultValue, IntersectionTests, Plane, Transforms) { 'use strict';
  24. const scratchCart4 = new Matrix2.Cartesian4();
  25. /**
  26. * A plane tangent to the provided ellipsoid at the provided origin.
  27. * If origin is not on the surface of the ellipsoid, it's surface projection will be used.
  28. * If origin is at the center of the ellipsoid, an exception will be thrown.
  29. * @alias EllipsoidTangentPlane
  30. * @constructor
  31. *
  32. * @param {Cartesian3} origin The point on the surface of the ellipsoid where the tangent plane touches.
  33. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use.
  34. *
  35. * @exception {DeveloperError} origin must not be at the center of the ellipsoid.
  36. */
  37. function EllipsoidTangentPlane(origin, ellipsoid) {
  38. //>>includeStart('debug', pragmas.debug);
  39. RuntimeError.Check.defined("origin", origin);
  40. //>>includeEnd('debug');
  41. ellipsoid = defaultValue.defaultValue(ellipsoid, Matrix2.Ellipsoid.WGS84);
  42. origin = ellipsoid.scaleToGeodeticSurface(origin);
  43. //>>includeStart('debug', pragmas.debug);
  44. if (!defaultValue.defined(origin)) {
  45. throw new RuntimeError.DeveloperError(
  46. "origin must not be at the center of the ellipsoid."
  47. );
  48. }
  49. //>>includeEnd('debug');
  50. const eastNorthUp = Transforms.Transforms.eastNorthUpToFixedFrame(origin, ellipsoid);
  51. this._ellipsoid = ellipsoid;
  52. this._origin = origin;
  53. this._xAxis = Matrix2.Cartesian3.fromCartesian4(
  54. Matrix2.Matrix4.getColumn(eastNorthUp, 0, scratchCart4)
  55. );
  56. this._yAxis = Matrix2.Cartesian3.fromCartesian4(
  57. Matrix2.Matrix4.getColumn(eastNorthUp, 1, scratchCart4)
  58. );
  59. const normal = Matrix2.Cartesian3.fromCartesian4(
  60. Matrix2.Matrix4.getColumn(eastNorthUp, 2, scratchCart4)
  61. );
  62. this._plane = Plane.Plane.fromPointNormal(origin, normal);
  63. }
  64. Object.defineProperties(EllipsoidTangentPlane.prototype, {
  65. /**
  66. * Gets the ellipsoid.
  67. * @memberof EllipsoidTangentPlane.prototype
  68. * @type {Ellipsoid}
  69. */
  70. ellipsoid: {
  71. get: function () {
  72. return this._ellipsoid;
  73. },
  74. },
  75. /**
  76. * Gets the origin.
  77. * @memberof EllipsoidTangentPlane.prototype
  78. * @type {Cartesian3}
  79. */
  80. origin: {
  81. get: function () {
  82. return this._origin;
  83. },
  84. },
  85. /**
  86. * Gets the plane which is tangent to the ellipsoid.
  87. * @memberof EllipsoidTangentPlane.prototype
  88. * @readonly
  89. * @type {Plane}
  90. */
  91. plane: {
  92. get: function () {
  93. return this._plane;
  94. },
  95. },
  96. /**
  97. * Gets the local X-axis (east) of the tangent plane.
  98. * @memberof EllipsoidTangentPlane.prototype
  99. * @readonly
  100. * @type {Cartesian3}
  101. */
  102. xAxis: {
  103. get: function () {
  104. return this._xAxis;
  105. },
  106. },
  107. /**
  108. * Gets the local Y-axis (north) of the tangent plane.
  109. * @memberof EllipsoidTangentPlane.prototype
  110. * @readonly
  111. * @type {Cartesian3}
  112. */
  113. yAxis: {
  114. get: function () {
  115. return this._yAxis;
  116. },
  117. },
  118. /**
  119. * Gets the local Z-axis (up) of the tangent plane.
  120. * @memberof EllipsoidTangentPlane.prototype
  121. * @readonly
  122. * @type {Cartesian3}
  123. */
  124. zAxis: {
  125. get: function () {
  126. return this._plane.normal;
  127. },
  128. },
  129. });
  130. const tmp = new AxisAlignedBoundingBox.AxisAlignedBoundingBox();
  131. /**
  132. * Creates a new instance from the provided ellipsoid and the center
  133. * point of the provided Cartesians.
  134. *
  135. * @param {Cartesian3[]} cartesians The list of positions surrounding the center point.
  136. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid to use.
  137. * @returns {EllipsoidTangentPlane} The new instance of EllipsoidTangentPlane.
  138. */
  139. EllipsoidTangentPlane.fromPoints = function (cartesians, ellipsoid) {
  140. //>>includeStart('debug', pragmas.debug);
  141. RuntimeError.Check.defined("cartesians", cartesians);
  142. //>>includeEnd('debug');
  143. const box = AxisAlignedBoundingBox.AxisAlignedBoundingBox.fromPoints(cartesians, tmp);
  144. return new EllipsoidTangentPlane(box.center, ellipsoid);
  145. };
  146. const scratchProjectPointOntoPlaneRay = new IntersectionTests.Ray();
  147. const scratchProjectPointOntoPlaneCartesian3 = new Matrix2.Cartesian3();
  148. /**
  149. * Computes the projection of the provided 3D position onto the 2D plane, radially outward from the {@link EllipsoidTangentPlane.ellipsoid} coordinate system origin.
  150. *
  151. * @param {Cartesian3} cartesian The point to project.
  152. * @param {Cartesian2} [result] The object onto which to store the result.
  153. * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided. Undefined if there is no intersection point
  154. */
  155. EllipsoidTangentPlane.prototype.projectPointOntoPlane = function (
  156. cartesian,
  157. result
  158. ) {
  159. //>>includeStart('debug', pragmas.debug);
  160. RuntimeError.Check.defined("cartesian", cartesian);
  161. //>>includeEnd('debug');
  162. const ray = scratchProjectPointOntoPlaneRay;
  163. ray.origin = cartesian;
  164. Matrix2.Cartesian3.normalize(cartesian, ray.direction);
  165. let intersectionPoint = IntersectionTests.IntersectionTests.rayPlane(
  166. ray,
  167. this._plane,
  168. scratchProjectPointOntoPlaneCartesian3
  169. );
  170. if (!defaultValue.defined(intersectionPoint)) {
  171. Matrix2.Cartesian3.negate(ray.direction, ray.direction);
  172. intersectionPoint = IntersectionTests.IntersectionTests.rayPlane(
  173. ray,
  174. this._plane,
  175. scratchProjectPointOntoPlaneCartesian3
  176. );
  177. }
  178. if (defaultValue.defined(intersectionPoint)) {
  179. const v = Matrix2.Cartesian3.subtract(
  180. intersectionPoint,
  181. this._origin,
  182. intersectionPoint
  183. );
  184. const x = Matrix2.Cartesian3.dot(this._xAxis, v);
  185. const y = Matrix2.Cartesian3.dot(this._yAxis, v);
  186. if (!defaultValue.defined(result)) {
  187. return new Matrix2.Cartesian2(x, y);
  188. }
  189. result.x = x;
  190. result.y = y;
  191. return result;
  192. }
  193. return undefined;
  194. };
  195. /**
  196. * Computes the projection of the provided 3D positions onto the 2D plane (where possible), radially outward from the global origin.
  197. * The resulting array may be shorter than the input array - if a single projection is impossible it will not be included.
  198. *
  199. * @see EllipsoidTangentPlane.projectPointOntoPlane
  200. *
  201. * @param {Cartesian3[]} cartesians The array of points to project.
  202. * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results.
  203. * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided.
  204. */
  205. EllipsoidTangentPlane.prototype.projectPointsOntoPlane = function (
  206. cartesians,
  207. result
  208. ) {
  209. //>>includeStart('debug', pragmas.debug);
  210. RuntimeError.Check.defined("cartesians", cartesians);
  211. //>>includeEnd('debug');
  212. if (!defaultValue.defined(result)) {
  213. result = [];
  214. }
  215. let count = 0;
  216. const length = cartesians.length;
  217. for (let i = 0; i < length; i++) {
  218. const p = this.projectPointOntoPlane(cartesians[i], result[count]);
  219. if (defaultValue.defined(p)) {
  220. result[count] = p;
  221. count++;
  222. }
  223. }
  224. result.length = count;
  225. return result;
  226. };
  227. /**
  228. * Computes the projection of the provided 3D position onto the 2D plane, along the plane normal.
  229. *
  230. * @param {Cartesian3} cartesian The point to project.
  231. * @param {Cartesian2} [result] The object onto which to store the result.
  232. * @returns {Cartesian2} The modified result parameter or a new Cartesian2 instance if none was provided.
  233. */
  234. EllipsoidTangentPlane.prototype.projectPointToNearestOnPlane = function (
  235. cartesian,
  236. result
  237. ) {
  238. //>>includeStart('debug', pragmas.debug);
  239. RuntimeError.Check.defined("cartesian", cartesian);
  240. //>>includeEnd('debug');
  241. if (!defaultValue.defined(result)) {
  242. result = new Matrix2.Cartesian2();
  243. }
  244. const ray = scratchProjectPointOntoPlaneRay;
  245. ray.origin = cartesian;
  246. Matrix2.Cartesian3.clone(this._plane.normal, ray.direction);
  247. let intersectionPoint = IntersectionTests.IntersectionTests.rayPlane(
  248. ray,
  249. this._plane,
  250. scratchProjectPointOntoPlaneCartesian3
  251. );
  252. if (!defaultValue.defined(intersectionPoint)) {
  253. Matrix2.Cartesian3.negate(ray.direction, ray.direction);
  254. intersectionPoint = IntersectionTests.IntersectionTests.rayPlane(
  255. ray,
  256. this._plane,
  257. scratchProjectPointOntoPlaneCartesian3
  258. );
  259. }
  260. const v = Matrix2.Cartesian3.subtract(
  261. intersectionPoint,
  262. this._origin,
  263. intersectionPoint
  264. );
  265. const x = Matrix2.Cartesian3.dot(this._xAxis, v);
  266. const y = Matrix2.Cartesian3.dot(this._yAxis, v);
  267. result.x = x;
  268. result.y = y;
  269. return result;
  270. };
  271. /**
  272. * Computes the projection of the provided 3D positions onto the 2D plane, along the plane normal.
  273. *
  274. * @see EllipsoidTangentPlane.projectPointToNearestOnPlane
  275. *
  276. * @param {Cartesian3[]} cartesians The array of points to project.
  277. * @param {Cartesian2[]} [result] The array of Cartesian2 instances onto which to store results.
  278. * @returns {Cartesian2[]} The modified result parameter or a new array of Cartesian2 instances if none was provided. This will have the same length as <code>cartesians</code>.
  279. */
  280. EllipsoidTangentPlane.prototype.projectPointsToNearestOnPlane = function (
  281. cartesians,
  282. result
  283. ) {
  284. //>>includeStart('debug', pragmas.debug);
  285. RuntimeError.Check.defined("cartesians", cartesians);
  286. //>>includeEnd('debug');
  287. if (!defaultValue.defined(result)) {
  288. result = [];
  289. }
  290. const length = cartesians.length;
  291. result.length = length;
  292. for (let i = 0; i < length; i++) {
  293. result[i] = this.projectPointToNearestOnPlane(cartesians[i], result[i]);
  294. }
  295. return result;
  296. };
  297. const projectPointsOntoEllipsoidScratch = new Matrix2.Cartesian3();
  298. /**
  299. * Computes the projection of the provided 2D position onto the 3D ellipsoid.
  300. *
  301. * @param {Cartesian2} cartesian The points to project.
  302. * @param {Cartesian3} [result] The Cartesian3 instance to store result.
  303. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  304. */
  305. EllipsoidTangentPlane.prototype.projectPointOntoEllipsoid = function (
  306. cartesian,
  307. result
  308. ) {
  309. //>>includeStart('debug', pragmas.debug);
  310. RuntimeError.Check.defined("cartesian", cartesian);
  311. //>>includeEnd('debug');
  312. if (!defaultValue.defined(result)) {
  313. result = new Matrix2.Cartesian3();
  314. }
  315. const ellipsoid = this._ellipsoid;
  316. const origin = this._origin;
  317. const xAxis = this._xAxis;
  318. const yAxis = this._yAxis;
  319. const tmp = projectPointsOntoEllipsoidScratch;
  320. Matrix2.Cartesian3.multiplyByScalar(xAxis, cartesian.x, tmp);
  321. result = Matrix2.Cartesian3.add(origin, tmp, result);
  322. Matrix2.Cartesian3.multiplyByScalar(yAxis, cartesian.y, tmp);
  323. Matrix2.Cartesian3.add(result, tmp, result);
  324. ellipsoid.scaleToGeocentricSurface(result, result);
  325. return result;
  326. };
  327. /**
  328. * Computes the projection of the provided 2D positions onto the 3D ellipsoid.
  329. *
  330. * @param {Cartesian2[]} cartesians The array of points to project.
  331. * @param {Cartesian3[]} [result] The array of Cartesian3 instances onto which to store results.
  332. * @returns {Cartesian3[]} The modified result parameter or a new array of Cartesian3 instances if none was provided.
  333. */
  334. EllipsoidTangentPlane.prototype.projectPointsOntoEllipsoid = function (
  335. cartesians,
  336. result
  337. ) {
  338. //>>includeStart('debug', pragmas.debug);
  339. RuntimeError.Check.defined("cartesians", cartesians);
  340. //>>includeEnd('debug');
  341. const length = cartesians.length;
  342. if (!defaultValue.defined(result)) {
  343. result = new Array(length);
  344. } else {
  345. result.length = length;
  346. }
  347. for (let i = 0; i < length; ++i) {
  348. result[i] = this.projectPointOntoEllipsoid(cartesians[i], result[i]);
  349. }
  350. return result;
  351. };
  352. exports.EllipsoidTangentPlane = EllipsoidTangentPlane;
  353. }));
  354. //# sourceMappingURL=EllipsoidTangentPlane-2abe082d.js.map