Ellipsoid.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. import Cartesian3 from './Cartesian3.js';
  2. import Cartographic from './Cartographic.js';
  3. import Check from './Check.js';
  4. import defaultValue from './defaultValue.js';
  5. import defined from './defined.js';
  6. import defineProperties from './defineProperties.js';
  7. import DeveloperError from './DeveloperError.js';
  8. import freezeObject from './freezeObject.js';
  9. import CesiumMath from './Math.js';
  10. import scaleToGeodeticSurface from './scaleToGeodeticSurface.js';
  11. function initialize(ellipsoid, x, y, z) {
  12. x = defaultValue(x, 0.0);
  13. y = defaultValue(y, 0.0);
  14. z = defaultValue(z, 0.0);
  15. //>>includeStart('debug', pragmas.debug);
  16. Check.typeOf.number.greaterThanOrEquals('x', x, 0.0);
  17. Check.typeOf.number.greaterThanOrEquals('y', y, 0.0);
  18. Check.typeOf.number.greaterThanOrEquals('z', z, 0.0);
  19. //>>includeEnd('debug');
  20. ellipsoid._radii = new Cartesian3(x, y, z);
  21. ellipsoid._radiiSquared = new Cartesian3(x * x,
  22. y * y,
  23. z * z);
  24. ellipsoid._radiiToTheFourth = new Cartesian3(x * x * x * x,
  25. y * y * y * y,
  26. z * z * z * z);
  27. ellipsoid._oneOverRadii = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / x,
  28. y === 0.0 ? 0.0 : 1.0 / y,
  29. z === 0.0 ? 0.0 : 1.0 / z);
  30. ellipsoid._oneOverRadiiSquared = new Cartesian3(x === 0.0 ? 0.0 : 1.0 / (x * x),
  31. y === 0.0 ? 0.0 : 1.0 / (y * y),
  32. z === 0.0 ? 0.0 : 1.0 / (z * z));
  33. ellipsoid._minimumRadius = Math.min(x, y, z);
  34. ellipsoid._maximumRadius = Math.max(x, y, z);
  35. ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1;
  36. if (ellipsoid._radiiSquared.z !== 0) {
  37. ellipsoid._squaredXOverSquaredZ = ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z;
  38. }
  39. }
  40. /**
  41. * A quadratic surface defined in Cartesian coordinates by the equation
  42. * <code>(x / a)^2 + (y / b)^2 + (z / c)^2 = 1</code>. Primarily used
  43. * by Cesium to represent the shape of planetary bodies.
  44. *
  45. * Rather than constructing this object directly, one of the provided
  46. * constants is normally used.
  47. * @alias Ellipsoid
  48. * @constructor
  49. *
  50. * @param {Number} [x=0] The radius in the x direction.
  51. * @param {Number} [y=0] The radius in the y direction.
  52. * @param {Number} [z=0] The radius in the z direction.
  53. *
  54. * @exception {DeveloperError} All radii components must be greater than or equal to zero.
  55. *
  56. * @see Ellipsoid.fromCartesian3
  57. * @see Ellipsoid.WGS84
  58. * @see Ellipsoid.UNIT_SPHERE
  59. */
  60. function Ellipsoid(x, y, z) {
  61. this._radii = undefined;
  62. this._radiiSquared = undefined;
  63. this._radiiToTheFourth = undefined;
  64. this._oneOverRadii = undefined;
  65. this._oneOverRadiiSquared = undefined;
  66. this._minimumRadius = undefined;
  67. this._maximumRadius = undefined;
  68. this._centerToleranceSquared = undefined;
  69. this._squaredXOverSquaredZ = undefined;
  70. initialize(this, x, y, z);
  71. }
  72. defineProperties(Ellipsoid.prototype, {
  73. /**
  74. * Gets the radii of the ellipsoid.
  75. * @memberof Ellipsoid.prototype
  76. * @type {Cartesian3}
  77. * @readonly
  78. */
  79. radii : {
  80. get: function() {
  81. return this._radii;
  82. }
  83. },
  84. /**
  85. * Gets the squared radii of the ellipsoid.
  86. * @memberof Ellipsoid.prototype
  87. * @type {Cartesian3}
  88. * @readonly
  89. */
  90. radiiSquared : {
  91. get : function() {
  92. return this._radiiSquared;
  93. }
  94. },
  95. /**
  96. * Gets the radii of the ellipsoid raise to the fourth power.
  97. * @memberof Ellipsoid.prototype
  98. * @type {Cartesian3}
  99. * @readonly
  100. */
  101. radiiToTheFourth : {
  102. get : function() {
  103. return this._radiiToTheFourth;
  104. }
  105. },
  106. /**
  107. * Gets one over the radii of the ellipsoid.
  108. * @memberof Ellipsoid.prototype
  109. * @type {Cartesian3}
  110. * @readonly
  111. */
  112. oneOverRadii : {
  113. get : function() {
  114. return this._oneOverRadii;
  115. }
  116. },
  117. /**
  118. * Gets one over the squared radii of the ellipsoid.
  119. * @memberof Ellipsoid.prototype
  120. * @type {Cartesian3}
  121. * @readonly
  122. */
  123. oneOverRadiiSquared : {
  124. get : function() {
  125. return this._oneOverRadiiSquared;
  126. }
  127. },
  128. /**
  129. * Gets the minimum radius of the ellipsoid.
  130. * @memberof Ellipsoid.prototype
  131. * @type {Number}
  132. * @readonly
  133. */
  134. minimumRadius : {
  135. get : function() {
  136. return this._minimumRadius;
  137. }
  138. },
  139. /**
  140. * Gets the maximum radius of the ellipsoid.
  141. * @memberof Ellipsoid.prototype
  142. * @type {Number}
  143. * @readonly
  144. */
  145. maximumRadius : {
  146. get : function() {
  147. return this._maximumRadius;
  148. }
  149. }
  150. });
  151. /**
  152. * Duplicates an Ellipsoid instance.
  153. *
  154. * @param {Ellipsoid} ellipsoid The ellipsoid to duplicate.
  155. * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new
  156. * instance should be created.
  157. * @returns {Ellipsoid} The cloned Ellipsoid. (Returns undefined if ellipsoid is undefined)
  158. */
  159. Ellipsoid.clone = function(ellipsoid, result) {
  160. if (!defined(ellipsoid)) {
  161. return undefined;
  162. }
  163. var radii = ellipsoid._radii;
  164. if (!defined(result)) {
  165. return new Ellipsoid(radii.x, radii.y, radii.z);
  166. }
  167. Cartesian3.clone(radii, result._radii);
  168. Cartesian3.clone(ellipsoid._radiiSquared, result._radiiSquared);
  169. Cartesian3.clone(ellipsoid._radiiToTheFourth, result._radiiToTheFourth);
  170. Cartesian3.clone(ellipsoid._oneOverRadii, result._oneOverRadii);
  171. Cartesian3.clone(ellipsoid._oneOverRadiiSquared, result._oneOverRadiiSquared);
  172. result._minimumRadius = ellipsoid._minimumRadius;
  173. result._maximumRadius = ellipsoid._maximumRadius;
  174. result._centerToleranceSquared = ellipsoid._centerToleranceSquared;
  175. return result;
  176. };
  177. /**
  178. * Computes an Ellipsoid from a Cartesian specifying the radii in x, y, and z directions.
  179. *
  180. * @param {Cartesian3} [cartesian=Cartesian3.ZERO] The ellipsoid's radius in the x, y, and z directions.
  181. * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new
  182. * instance should be created.
  183. * @returns {Ellipsoid} A new Ellipsoid instance.
  184. *
  185. * @exception {DeveloperError} All radii components must be greater than or equal to zero.
  186. *
  187. * @see Ellipsoid.WGS84
  188. * @see Ellipsoid.UNIT_SPHERE
  189. */
  190. Ellipsoid.fromCartesian3 = function(cartesian, result) {
  191. if (!defined(result)) {
  192. result = new Ellipsoid();
  193. }
  194. if (!defined(cartesian)) {
  195. return result;
  196. }
  197. initialize(result, cartesian.x, cartesian.y, cartesian.z);
  198. return result;
  199. };
  200. /**
  201. * An Ellipsoid instance initialized to the WGS84 standard.
  202. *
  203. * @type {Ellipsoid}
  204. * @constant
  205. */
  206. Ellipsoid.WGS84 = freezeObject(new Ellipsoid(6378137.0, 6378137.0, 6356752.3142451793));
  207. /**
  208. * An Ellipsoid instance initialized to radii of (1.0, 1.0, 1.0).
  209. *
  210. * @type {Ellipsoid}
  211. * @constant
  212. */
  213. Ellipsoid.UNIT_SPHERE = freezeObject(new Ellipsoid(1.0, 1.0, 1.0));
  214. /**
  215. * An Ellipsoid instance initialized to a sphere with the lunar radius.
  216. *
  217. * @type {Ellipsoid}
  218. * @constant
  219. */
  220. Ellipsoid.MOON = freezeObject(new Ellipsoid(CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS, CesiumMath.LUNAR_RADIUS));
  221. /**
  222. * Duplicates an Ellipsoid instance.
  223. *
  224. * @param {Ellipsoid} [result] The object onto which to store the result, or undefined if a new
  225. * instance should be created.
  226. * @returns {Ellipsoid} The cloned Ellipsoid.
  227. */
  228. Ellipsoid.prototype.clone = function(result) {
  229. return Ellipsoid.clone(this, result);
  230. };
  231. /**
  232. * The number of elements used to pack the object into an array.
  233. * @type {Number}
  234. */
  235. Ellipsoid.packedLength = Cartesian3.packedLength;
  236. /**
  237. * Stores the provided instance into the provided array.
  238. *
  239. * @param {Ellipsoid} value The value to pack.
  240. * @param {Number[]} array The array to pack into.
  241. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  242. *
  243. * @returns {Number[]} The array that was packed into
  244. */
  245. Ellipsoid.pack = function(value, array, startingIndex) {
  246. //>>includeStart('debug', pragmas.debug);
  247. Check.typeOf.object('value', value);
  248. Check.defined('array', array);
  249. //>>includeEnd('debug');
  250. startingIndex = defaultValue(startingIndex, 0);
  251. Cartesian3.pack(value._radii, array, startingIndex);
  252. return array;
  253. };
  254. /**
  255. * Retrieves an instance from a packed array.
  256. *
  257. * @param {Number[]} array The packed array.
  258. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  259. * @param {Ellipsoid} [result] The object into which to store the result.
  260. * @returns {Ellipsoid} The modified result parameter or a new Ellipsoid instance if one was not provided.
  261. */
  262. Ellipsoid.unpack = function(array, startingIndex, result) {
  263. //>>includeStart('debug', pragmas.debug);
  264. Check.defined('array', array);
  265. //>>includeEnd('debug');
  266. startingIndex = defaultValue(startingIndex, 0);
  267. var radii = Cartesian3.unpack(array, startingIndex);
  268. return Ellipsoid.fromCartesian3(radii, result);
  269. };
  270. /**
  271. * Computes the unit vector directed from the center of this ellipsoid toward the provided Cartesian position.
  272. * @function
  273. *
  274. * @param {Cartesian3} cartesian The Cartesian for which to to determine the geocentric normal.
  275. * @param {Cartesian3} [result] The object onto which to store the result.
  276. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  277. */
  278. Ellipsoid.prototype.geocentricSurfaceNormal = Cartesian3.normalize;
  279. /**
  280. * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position.
  281. *
  282. * @param {Cartographic} cartographic The cartographic position for which to to determine the geodetic normal.
  283. * @param {Cartesian3} [result] The object onto which to store the result.
  284. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  285. */
  286. Ellipsoid.prototype.geodeticSurfaceNormalCartographic = function(cartographic, result) {
  287. //>>includeStart('debug', pragmas.debug);
  288. Check.typeOf.object('cartographic', cartographic);
  289. //>>includeEnd('debug');
  290. var longitude = cartographic.longitude;
  291. var latitude = cartographic.latitude;
  292. var cosLatitude = Math.cos(latitude);
  293. var x = cosLatitude * Math.cos(longitude);
  294. var y = cosLatitude * Math.sin(longitude);
  295. var z = Math.sin(latitude);
  296. if (!defined(result)) {
  297. result = new Cartesian3();
  298. }
  299. result.x = x;
  300. result.y = y;
  301. result.z = z;
  302. return Cartesian3.normalize(result, result);
  303. };
  304. /**
  305. * Computes the normal of the plane tangent to the surface of the ellipsoid at the provided position.
  306. *
  307. * @param {Cartesian3} cartesian The Cartesian position for which to to determine the surface normal.
  308. * @param {Cartesian3} [result] The object onto which to store the result.
  309. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  310. */
  311. Ellipsoid.prototype.geodeticSurfaceNormal = function(cartesian, result) {
  312. if (!defined(result)) {
  313. result = new Cartesian3();
  314. }
  315. result = Cartesian3.multiplyComponents(cartesian, this._oneOverRadiiSquared, result);
  316. return Cartesian3.normalize(result, result);
  317. };
  318. var cartographicToCartesianNormal = new Cartesian3();
  319. var cartographicToCartesianK = new Cartesian3();
  320. /**
  321. * Converts the provided cartographic to Cartesian representation.
  322. *
  323. * @param {Cartographic} cartographic The cartographic position.
  324. * @param {Cartesian3} [result] The object onto which to store the result.
  325. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  326. *
  327. * @example
  328. * //Create a Cartographic and determine it's Cartesian representation on a WGS84 ellipsoid.
  329. * var position = new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000);
  330. * var cartesianPosition = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position);
  331. */
  332. Ellipsoid.prototype.cartographicToCartesian = function(cartographic, result) {
  333. //`cartographic is required` is thrown from geodeticSurfaceNormalCartographic.
  334. var n = cartographicToCartesianNormal;
  335. var k = cartographicToCartesianK;
  336. this.geodeticSurfaceNormalCartographic(cartographic, n);
  337. Cartesian3.multiplyComponents(this._radiiSquared, n, k);
  338. var gamma = Math.sqrt(Cartesian3.dot(n, k));
  339. Cartesian3.divideByScalar(k, gamma, k);
  340. Cartesian3.multiplyByScalar(n, cartographic.height, n);
  341. if (!defined(result)) {
  342. result = new Cartesian3();
  343. }
  344. return Cartesian3.add(k, n, result);
  345. };
  346. /**
  347. * Converts the provided array of cartographics to an array of Cartesians.
  348. *
  349. * @param {Cartographic[]} cartographics An array of cartographic positions.
  350. * @param {Cartesian3[]} [result] The object onto which to store the result.
  351. * @returns {Cartesian3[]} The modified result parameter or a new Array instance if none was provided.
  352. *
  353. * @example
  354. * //Convert an array of Cartographics and determine their Cartesian representation on a WGS84 ellipsoid.
  355. * var positions = [new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 0),
  356. * new Cesium.Cartographic(Cesium.Math.toRadians(21.321), Cesium.Math.toRadians(78.123), 100),
  357. * new Cesium.Cartographic(Cesium.Math.toRadians(21.645), Cesium.Math.toRadians(78.456), 250)];
  358. * var cartesianPositions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray(positions);
  359. */
  360. Ellipsoid.prototype.cartographicArrayToCartesianArray = function(cartographics, result) {
  361. //>>includeStart('debug', pragmas.debug);
  362. Check.defined('cartographics', cartographics);
  363. //>>includeEnd('debug')
  364. var length = cartographics.length;
  365. if (!defined(result)) {
  366. result = new Array(length);
  367. } else {
  368. result.length = length;
  369. }
  370. for ( var i = 0; i < length; i++) {
  371. result[i] = this.cartographicToCartesian(cartographics[i], result[i]);
  372. }
  373. return result;
  374. };
  375. var cartesianToCartographicN = new Cartesian3();
  376. var cartesianToCartographicP = new Cartesian3();
  377. var cartesianToCartographicH = new Cartesian3();
  378. /**
  379. * Converts the provided cartesian to cartographic representation.
  380. * The cartesian is undefined at the center of the ellipsoid.
  381. *
  382. * @param {Cartesian3} cartesian The Cartesian position to convert to cartographic representation.
  383. * @param {Cartographic} [result] The object onto which to store the result.
  384. * @returns {Cartographic} The modified result parameter, new Cartographic instance if none was provided, or undefined if the cartesian is at the center of the ellipsoid.
  385. *
  386. * @example
  387. * //Create a Cartesian and determine it's Cartographic representation on a WGS84 ellipsoid.
  388. * var position = new Cesium.Cartesian3(17832.12, 83234.52, 952313.73);
  389. * var cartographicPosition = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position);
  390. */
  391. Ellipsoid.prototype.cartesianToCartographic = function(cartesian, result) {
  392. //`cartesian is required.` is thrown from scaleToGeodeticSurface
  393. var p = this.scaleToGeodeticSurface(cartesian, cartesianToCartographicP);
  394. if (!defined(p)) {
  395. return undefined;
  396. }
  397. var n = this.geodeticSurfaceNormal(p, cartesianToCartographicN);
  398. var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH);
  399. var longitude = Math.atan2(n.y, n.x);
  400. var latitude = Math.asin(n.z);
  401. var height = CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h);
  402. if (!defined(result)) {
  403. return new Cartographic(longitude, latitude, height);
  404. }
  405. result.longitude = longitude;
  406. result.latitude = latitude;
  407. result.height = height;
  408. return result;
  409. };
  410. /**
  411. * Converts the provided array of cartesians to an array of cartographics.
  412. *
  413. * @param {Cartesian3[]} cartesians An array of Cartesian positions.
  414. * @param {Cartographic[]} [result] The object onto which to store the result.
  415. * @returns {Cartographic[]} The modified result parameter or a new Array instance if none was provided.
  416. *
  417. * @example
  418. * //Create an array of Cartesians and determine their Cartographic representation on a WGS84 ellipsoid.
  419. * var positions = [new Cesium.Cartesian3(17832.12, 83234.52, 952313.73),
  420. * new Cesium.Cartesian3(17832.13, 83234.53, 952313.73),
  421. * new Cesium.Cartesian3(17832.14, 83234.54, 952313.73)]
  422. * var cartographicPositions = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray(positions);
  423. */
  424. Ellipsoid.prototype.cartesianArrayToCartographicArray = function(cartesians, result) {
  425. //>>includeStart('debug', pragmas.debug);
  426. Check.defined('cartesians', cartesians);
  427. //>>includeEnd('debug');
  428. var length = cartesians.length;
  429. if (!defined(result)) {
  430. result = new Array(length);
  431. } else {
  432. result.length = length;
  433. }
  434. for ( var i = 0; i < length; ++i) {
  435. result[i] = this.cartesianToCartographic(cartesians[i], result[i]);
  436. }
  437. return result;
  438. };
  439. /**
  440. * Scales the provided Cartesian position along the geodetic surface normal
  441. * so that it is on the surface of this ellipsoid. If the position is
  442. * at the center of the ellipsoid, this function returns undefined.
  443. *
  444. * @param {Cartesian3} cartesian The Cartesian position to scale.
  445. * @param {Cartesian3} [result] The object onto which to store the result.
  446. * @returns {Cartesian3} The modified result parameter, a new Cartesian3 instance if none was provided, or undefined if the position is at the center.
  447. */
  448. Ellipsoid.prototype.scaleToGeodeticSurface = function(cartesian, result) {
  449. return scaleToGeodeticSurface(cartesian, this._oneOverRadii, this._oneOverRadiiSquared, this._centerToleranceSquared, result);
  450. };
  451. /**
  452. * Scales the provided Cartesian position along the geocentric surface normal
  453. * so that it is on the surface of this ellipsoid.
  454. *
  455. * @param {Cartesian3} cartesian The Cartesian position to scale.
  456. * @param {Cartesian3} [result] The object onto which to store the result.
  457. * @returns {Cartesian3} The modified result parameter or a new Cartesian3 instance if none was provided.
  458. */
  459. Ellipsoid.prototype.scaleToGeocentricSurface = function(cartesian, result) {
  460. //>>includeStart('debug', pragmas.debug);
  461. Check.typeOf.object('cartesian', cartesian);
  462. //>>includeEnd('debug');
  463. if (!defined(result)) {
  464. result = new Cartesian3();
  465. }
  466. var positionX = cartesian.x;
  467. var positionY = cartesian.y;
  468. var positionZ = cartesian.z;
  469. var oneOverRadiiSquared = this._oneOverRadiiSquared;
  470. var beta = 1.0 / Math.sqrt((positionX * positionX) * oneOverRadiiSquared.x +
  471. (positionY * positionY) * oneOverRadiiSquared.y +
  472. (positionZ * positionZ) * oneOverRadiiSquared.z);
  473. return Cartesian3.multiplyByScalar(cartesian, beta, result);
  474. };
  475. /**
  476. * Transforms a Cartesian X, Y, Z position to the ellipsoid-scaled space by multiplying
  477. * its components by the result of {@link Ellipsoid#oneOverRadii}.
  478. *
  479. * @param {Cartesian3} position The position to transform.
  480. * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and
  481. * return a new instance.
  482. * @returns {Cartesian3} The position expressed in the scaled space. The returned instance is the
  483. * one passed as the result parameter if it is not undefined, or a new instance of it is.
  484. */
  485. Ellipsoid.prototype.transformPositionToScaledSpace = function(position, result) {
  486. if (!defined(result)) {
  487. result = new Cartesian3();
  488. }
  489. return Cartesian3.multiplyComponents(position, this._oneOverRadii, result);
  490. };
  491. /**
  492. * Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying
  493. * its components by the result of {@link Ellipsoid#radii}.
  494. *
  495. * @param {Cartesian3} position The position to transform.
  496. * @param {Cartesian3} [result] The position to which to copy the result, or undefined to create and
  497. * return a new instance.
  498. * @returns {Cartesian3} The position expressed in the unscaled space. The returned instance is the
  499. * one passed as the result parameter if it is not undefined, or a new instance of it is.
  500. */
  501. Ellipsoid.prototype.transformPositionFromScaledSpace = function(position, result) {
  502. if (!defined(result)) {
  503. result = new Cartesian3();
  504. }
  505. return Cartesian3.multiplyComponents(position, this._radii, result);
  506. };
  507. /**
  508. * Compares this Ellipsoid against the provided Ellipsoid componentwise and returns
  509. * <code>true</code> if they are equal, <code>false</code> otherwise.
  510. *
  511. * @param {Ellipsoid} [right] The other Ellipsoid.
  512. * @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
  513. */
  514. Ellipsoid.prototype.equals = function(right) {
  515. return (this === right) ||
  516. (defined(right) &&
  517. Cartesian3.equals(this._radii, right._radii));
  518. };
  519. /**
  520. * Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'.
  521. *
  522. * @returns {String} A string representing this ellipsoid in the format '(radii.x, radii.y, radii.z)'.
  523. */
  524. Ellipsoid.prototype.toString = function() {
  525. return this._radii.toString();
  526. };
  527. /**
  528. * Computes a point which is the intersection of the surface normal with the z-axis.
  529. *
  530. * @param {Cartesian3} position the position. must be on the surface of the ellipsoid.
  531. * @param {Number} [buffer = 0.0] A buffer to subtract from the ellipsoid size when checking if the point is inside the ellipsoid.
  532. * In earth case, with common earth datums, there is no need for this buffer since the intersection point is always (relatively) very close to the center.
  533. * In WGS84 datum, intersection point is at max z = +-42841.31151331382 (0.673% of z-axis).
  534. * Intersection point could be outside the ellipsoid if the ratio of MajorAxis / AxisOfRotation is bigger than the square root of 2
  535. * @param {Cartesian3} [result] The cartesian to which to copy the result, or undefined to create and
  536. * return a new instance.
  537. * @returns {Cartesian3 | undefined} the intersection point if it's inside the ellipsoid, undefined otherwise
  538. *
  539. * @exception {DeveloperError} position is required.
  540. * @exception {DeveloperError} Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y).
  541. * @exception {DeveloperError} Ellipsoid.radii.z must be greater than 0.
  542. */
  543. Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function(position, buffer, result) {
  544. //>>includeStart('debug', pragmas.debug);
  545. Check.typeOf.object('position', position);
  546. if (!CesiumMath.equalsEpsilon(this._radii.x, this._radii.y, CesiumMath.EPSILON15)) {
  547. throw new DeveloperError('Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)');
  548. }
  549. Check.typeOf.number.greaterThan('Ellipsoid.radii.z', this._radii.z, 0);
  550. //>>includeEnd('debug');
  551. buffer = defaultValue(buffer, 0.0);
  552. var squaredXOverSquaredZ = this._squaredXOverSquaredZ;
  553. if (!defined(result)) {
  554. result = new Cartesian3();
  555. }
  556. result.x = 0.0;
  557. result.y = 0.0;
  558. result.z = position.z * (1 - squaredXOverSquaredZ);
  559. if (Math.abs(result.z) >= this._radii.z - buffer) {
  560. return undefined;
  561. }
  562. return result;
  563. };
  564. export default Ellipsoid;