EllipsoidTangentPlane-46d4d9c2.js 12 KB

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