123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- import Cartesian3 from "./Cartesian3.js";
- import Cartographic from "./Cartographic.js";
- import Check from "./Check.js";
- import defaultValue from "./defaultValue.js";
- import defined from "./defined.js";
- import DeveloperError from "./DeveloperError.js";
- import CesiumMath from "./Math.js";
- import scaleToGeodeticSurface from "./scaleToGeodeticSurface.js";
- function initialize(ellipsoid, x, y, z) {
- x = defaultValue(x, 0.0);
- y = defaultValue(y, 0.0);
- z = defaultValue(z, 0.0);
-
- Check.typeOf.number.greaterThanOrEquals("x", x, 0.0);
- Check.typeOf.number.greaterThanOrEquals("y", y, 0.0);
- Check.typeOf.number.greaterThanOrEquals("z", z, 0.0);
-
- ellipsoid._radii = new Cartesian3(x, y, z);
- ellipsoid._radiiSquared = new Cartesian3(x * x, y * y, z * z);
- ellipsoid._radiiToTheFourth = new Cartesian3(
- x * x * x * x,
- y * y * y * y,
- z * z * z * z
- );
- ellipsoid._oneOverRadii = new Cartesian3(
- x === 0.0 ? 0.0 : 1.0 / x,
- y === 0.0 ? 0.0 : 1.0 / y,
- z === 0.0 ? 0.0 : 1.0 / z
- );
- ellipsoid._oneOverRadiiSquared = new Cartesian3(
- x === 0.0 ? 0.0 : 1.0 / (x * x),
- y === 0.0 ? 0.0 : 1.0 / (y * y),
- z === 0.0 ? 0.0 : 1.0 / (z * z)
- );
- ellipsoid._minimumRadius = Math.min(x, y, z);
- ellipsoid._maximumRadius = Math.max(x, y, z);
- ellipsoid._centerToleranceSquared = CesiumMath.EPSILON1;
- if (ellipsoid._radiiSquared.z !== 0) {
- ellipsoid._squaredXOverSquaredZ =
- ellipsoid._radiiSquared.x / ellipsoid._radiiSquared.z;
- }
- }
- function Ellipsoid(x, y, z) {
- this._radii = undefined;
- this._radiiSquared = undefined;
- this._radiiToTheFourth = undefined;
- this._oneOverRadii = undefined;
- this._oneOverRadiiSquared = undefined;
- this._minimumRadius = undefined;
- this._maximumRadius = undefined;
- this._centerToleranceSquared = undefined;
- this._squaredXOverSquaredZ = undefined;
- initialize(this, x, y, z);
- }
- Object.defineProperties(Ellipsoid.prototype, {
-
- radii: {
- get: function () {
- return this._radii;
- },
- },
-
- radiiSquared: {
- get: function () {
- return this._radiiSquared;
- },
- },
-
- radiiToTheFourth: {
- get: function () {
- return this._radiiToTheFourth;
- },
- },
-
- oneOverRadii: {
- get: function () {
- return this._oneOverRadii;
- },
- },
-
- oneOverRadiiSquared: {
- get: function () {
- return this._oneOverRadiiSquared;
- },
- },
-
- minimumRadius: {
- get: function () {
- return this._minimumRadius;
- },
- },
-
- maximumRadius: {
- get: function () {
- return this._maximumRadius;
- },
- },
- });
- Ellipsoid.clone = function (ellipsoid, result) {
- if (!defined(ellipsoid)) {
- return undefined;
- }
- var radii = ellipsoid._radii;
- if (!defined(result)) {
- return new Ellipsoid(radii.x, radii.y, radii.z);
- }
- Cartesian3.clone(radii, result._radii);
- Cartesian3.clone(ellipsoid._radiiSquared, result._radiiSquared);
- Cartesian3.clone(ellipsoid._radiiToTheFourth, result._radiiToTheFourth);
- Cartesian3.clone(ellipsoid._oneOverRadii, result._oneOverRadii);
- Cartesian3.clone(ellipsoid._oneOverRadiiSquared, result._oneOverRadiiSquared);
- result._minimumRadius = ellipsoid._minimumRadius;
- result._maximumRadius = ellipsoid._maximumRadius;
- result._centerToleranceSquared = ellipsoid._centerToleranceSquared;
- return result;
- };
- Ellipsoid.fromCartesian3 = function (cartesian, result) {
- if (!defined(result)) {
- result = new Ellipsoid();
- }
- if (!defined(cartesian)) {
- return result;
- }
- initialize(result, cartesian.x, cartesian.y, cartesian.z);
- return result;
- };
- Ellipsoid.WGS84 = Object.freeze(
- new Ellipsoid(6378137.0, 6378137.0, 6356752.3142451793)
- );
- Ellipsoid.UNIT_SPHERE = Object.freeze(new Ellipsoid(1.0, 1.0, 1.0));
- Ellipsoid.MOON = Object.freeze(
- new Ellipsoid(
- CesiumMath.LUNAR_RADIUS,
- CesiumMath.LUNAR_RADIUS,
- CesiumMath.LUNAR_RADIUS
- )
- );
- Ellipsoid.prototype.clone = function (result) {
- return Ellipsoid.clone(this, result);
- };
- Ellipsoid.packedLength = Cartesian3.packedLength;
- Ellipsoid.pack = function (value, array, startingIndex) {
-
- Check.typeOf.object("value", value);
- Check.defined("array", array);
-
- startingIndex = defaultValue(startingIndex, 0);
- Cartesian3.pack(value._radii, array, startingIndex);
- return array;
- };
- Ellipsoid.unpack = function (array, startingIndex, result) {
-
- Check.defined("array", array);
-
- startingIndex = defaultValue(startingIndex, 0);
- var radii = Cartesian3.unpack(array, startingIndex);
- return Ellipsoid.fromCartesian3(radii, result);
- };
- Ellipsoid.prototype.geocentricSurfaceNormal = Cartesian3.normalize;
- Ellipsoid.prototype.geodeticSurfaceNormalCartographic = function (
- cartographic,
- result
- ) {
-
- Check.typeOf.object("cartographic", cartographic);
-
- var longitude = cartographic.longitude;
- var latitude = cartographic.latitude;
- var cosLatitude = Math.cos(latitude);
- var x = cosLatitude * Math.cos(longitude);
- var y = cosLatitude * Math.sin(longitude);
- var z = Math.sin(latitude);
- if (!defined(result)) {
- result = new Cartesian3();
- }
- result.x = x;
- result.y = y;
- result.z = z;
- return Cartesian3.normalize(result, result);
- };
- Ellipsoid.prototype.geodeticSurfaceNormal = function (cartesian, result) {
- if (
- Cartesian3.equalsEpsilon(cartesian, Cartesian3.ZERO, CesiumMath.EPSILON14)
- ) {
- return undefined;
- }
- if (!defined(result)) {
- result = new Cartesian3();
- }
- result = Cartesian3.multiplyComponents(
- cartesian,
- this._oneOverRadiiSquared,
- result
- );
- return Cartesian3.normalize(result, result);
- };
- var cartographicToCartesianNormal = new Cartesian3();
- var cartographicToCartesianK = new Cartesian3();
- Ellipsoid.prototype.cartographicToCartesian = function (cartographic, result) {
-
- var n = cartographicToCartesianNormal;
- var k = cartographicToCartesianK;
- this.geodeticSurfaceNormalCartographic(cartographic, n);
- Cartesian3.multiplyComponents(this._radiiSquared, n, k);
- var gamma = Math.sqrt(Cartesian3.dot(n, k));
- Cartesian3.divideByScalar(k, gamma, k);
- Cartesian3.multiplyByScalar(n, cartographic.height, n);
- if (!defined(result)) {
- result = new Cartesian3();
- }
- return Cartesian3.add(k, n, result);
- };
- Ellipsoid.prototype.cartographicArrayToCartesianArray = function (
- cartographics,
- result
- ) {
-
- Check.defined("cartographics", cartographics);
-
- var length = cartographics.length;
- if (!defined(result)) {
- result = new Array(length);
- } else {
- result.length = length;
- }
- for (var i = 0; i < length; i++) {
- result[i] = this.cartographicToCartesian(cartographics[i], result[i]);
- }
- return result;
- };
- var cartesianToCartographicN = new Cartesian3();
- var cartesianToCartographicP = new Cartesian3();
- var cartesianToCartographicH = new Cartesian3();
- Ellipsoid.prototype.cartesianToCartographic = function (cartesian, result) {
-
- var p = this.scaleToGeodeticSurface(cartesian, cartesianToCartographicP);
- if (!defined(p)) {
- return undefined;
- }
- var n = this.geodeticSurfaceNormal(p, cartesianToCartographicN);
- var h = Cartesian3.subtract(cartesian, p, cartesianToCartographicH);
- var longitude = Math.atan2(n.y, n.x);
- var latitude = Math.asin(n.z);
- var height =
- CesiumMath.sign(Cartesian3.dot(h, cartesian)) * Cartesian3.magnitude(h);
- if (!defined(result)) {
- return new Cartographic(longitude, latitude, height);
- }
- result.longitude = longitude;
- result.latitude = latitude;
- result.height = height;
- return result;
- };
- Ellipsoid.prototype.cartesianArrayToCartographicArray = function (
- cartesians,
- result
- ) {
-
- Check.defined("cartesians", cartesians);
-
- var length = cartesians.length;
- if (!defined(result)) {
- result = new Array(length);
- } else {
- result.length = length;
- }
- for (var i = 0; i < length; ++i) {
- result[i] = this.cartesianToCartographic(cartesians[i], result[i]);
- }
- return result;
- };
- Ellipsoid.prototype.scaleToGeodeticSurface = function (cartesian, result) {
- return scaleToGeodeticSurface(
- cartesian,
- this._oneOverRadii,
- this._oneOverRadiiSquared,
- this._centerToleranceSquared,
- result
- );
- };
- Ellipsoid.prototype.scaleToGeocentricSurface = function (cartesian, result) {
-
- Check.typeOf.object("cartesian", cartesian);
-
- if (!defined(result)) {
- result = new Cartesian3();
- }
- var positionX = cartesian.x;
- var positionY = cartesian.y;
- var positionZ = cartesian.z;
- var oneOverRadiiSquared = this._oneOverRadiiSquared;
- var beta =
- 1.0 /
- Math.sqrt(
- positionX * positionX * oneOverRadiiSquared.x +
- positionY * positionY * oneOverRadiiSquared.y +
- positionZ * positionZ * oneOverRadiiSquared.z
- );
- return Cartesian3.multiplyByScalar(cartesian, beta, result);
- };
- Ellipsoid.prototype.transformPositionToScaledSpace = function (
- position,
- result
- ) {
- if (!defined(result)) {
- result = new Cartesian3();
- }
- return Cartesian3.multiplyComponents(position, this._oneOverRadii, result);
- };
- Ellipsoid.prototype.transformPositionFromScaledSpace = function (
- position,
- result
- ) {
- if (!defined(result)) {
- result = new Cartesian3();
- }
- return Cartesian3.multiplyComponents(position, this._radii, result);
- };
- Ellipsoid.prototype.equals = function (right) {
- return (
- this === right ||
- (defined(right) && Cartesian3.equals(this._radii, right._radii))
- );
- };
- Ellipsoid.prototype.toString = function () {
- return this._radii.toString();
- };
- Ellipsoid.prototype.getSurfaceNormalIntersectionWithZAxis = function (
- position,
- buffer,
- result
- ) {
-
- Check.typeOf.object("position", position);
- if (
- !CesiumMath.equalsEpsilon(
- this._radii.x,
- this._radii.y,
- CesiumMath.EPSILON15
- )
- ) {
- throw new DeveloperError(
- "Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y)"
- );
- }
- Check.typeOf.number.greaterThan("Ellipsoid.radii.z", this._radii.z, 0);
-
- buffer = defaultValue(buffer, 0.0);
- var squaredXOverSquaredZ = this._squaredXOverSquaredZ;
- if (!defined(result)) {
- result = new Cartesian3();
- }
- result.x = 0.0;
- result.y = 0.0;
- result.z = position.z * (1 - squaredXOverSquaredZ);
- if (Math.abs(result.z) >= this._radii.z - buffer) {
- return undefined;
- }
- return result;
- };
- var abscissas = [
- 0.14887433898163,
- 0.43339539412925,
- 0.67940956829902,
- 0.86506336668898,
- 0.97390652851717,
- 0.0,
- ];
- var weights = [
- 0.29552422471475,
- 0.26926671930999,
- 0.21908636251598,
- 0.14945134915058,
- 0.066671344308684,
- 0.0,
- ];
- function gaussLegendreQuadrature(a, b, func) {
-
- Check.typeOf.number("a", a);
- Check.typeOf.number("b", b);
- Check.typeOf.func("func", func);
-
-
-
- var xMean = 0.5 * (b + a);
- var xRange = 0.5 * (b - a);
- var sum = 0.0;
- for (var i = 0; i < 5; i++) {
- var dx = xRange * abscissas[i];
- sum += weights[i] * (func(xMean + dx) + func(xMean - dx));
- }
-
- sum *= xRange;
- return sum;
- }
- Ellipsoid.prototype.surfaceArea = function (rectangle) {
-
- Check.typeOf.object("rectangle", rectangle);
-
- var minLongitude = rectangle.west;
- var maxLongitude = rectangle.east;
- var minLatitude = rectangle.south;
- var maxLatitude = rectangle.north;
- while (maxLongitude < minLongitude) {
- maxLongitude += CesiumMath.TWO_PI;
- }
- var radiiSquared = this._radiiSquared;
- var a2 = radiiSquared.x;
- var b2 = radiiSquared.y;
- var c2 = radiiSquared.z;
- var a2b2 = a2 * b2;
- return gaussLegendreQuadrature(minLatitude, maxLatitude, function (lat) {
-
-
- var sinPhi = Math.cos(lat);
- var cosPhi = Math.sin(lat);
- return (
- Math.cos(lat) *
- gaussLegendreQuadrature(minLongitude, maxLongitude, function (lon) {
- var cosTheta = Math.cos(lon);
- var sinTheta = Math.sin(lon);
- return Math.sqrt(
- a2b2 * cosPhi * cosPhi +
- c2 *
- (b2 * cosTheta * cosTheta + a2 * sinTheta * sinTheta) *
- sinPhi *
- sinPhi
- );
- })
- );
- });
- };
- export default Ellipsoid;
|