EllipsoidTangentPlane-d42ee682.js 13 KB

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