@math.gl/geospatial
Advanced tools
Comparing version 4.0.0 to 4.0.1
@@ -12,2 +12,1 @@ export declare const WGS84_RADIUS_X = 6378137; | ||
}; | ||
//# sourceMappingURL=constants.d.ts.map |
@@ -0,12 +1,22 @@ | ||
// This file is derived from the Cesium math library under Apache 2 license | ||
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md | ||
export const WGS84_RADIUS_X = 6378137.0; | ||
export const WGS84_RADIUS_Y = 6378137.0; | ||
export const WGS84_RADIUS_Z = 6356752.3142451793; | ||
// Pre-calculated ellipsoid defaults to avoid utils depending on `ellipsoid.js` | ||
export const WGS84_CONSTANTS = { | ||
radii: [WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z], | ||
radiiSquared: [WGS84_RADIUS_X * WGS84_RADIUS_X, WGS84_RADIUS_Y * WGS84_RADIUS_Y, WGS84_RADIUS_Z * WGS84_RADIUS_Z], | ||
oneOverRadii: [1.0 / WGS84_RADIUS_X, 1.0 / WGS84_RADIUS_Y, 1.0 / WGS84_RADIUS_Z], | ||
oneOverRadiiSquared: [1.0 / (WGS84_RADIUS_X * WGS84_RADIUS_X), 1.0 / (WGS84_RADIUS_Y * WGS84_RADIUS_Y), 1.0 / (WGS84_RADIUS_Z * WGS84_RADIUS_Z)], | ||
maximumRadius: Math.max(WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z), | ||
centerToleranceSquared: 1e-1 | ||
radii: [WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z], | ||
radiiSquared: [ | ||
WGS84_RADIUS_X * WGS84_RADIUS_X, | ||
WGS84_RADIUS_Y * WGS84_RADIUS_Y, | ||
WGS84_RADIUS_Z * WGS84_RADIUS_Z | ||
], | ||
oneOverRadii: [1.0 / WGS84_RADIUS_X, 1.0 / WGS84_RADIUS_Y, 1.0 / WGS84_RADIUS_Z], | ||
oneOverRadiiSquared: [ | ||
1.0 / (WGS84_RADIUS_X * WGS84_RADIUS_X), | ||
1.0 / (WGS84_RADIUS_Y * WGS84_RADIUS_Y), | ||
1.0 / (WGS84_RADIUS_Z * WGS84_RADIUS_Z) | ||
], | ||
maximumRadius: Math.max(WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z), | ||
centerToleranceSquared: 1e-1 // EPSILON1; | ||
}; | ||
//# sourceMappingURL=constants.js.map |
import { Vector3, Matrix4, NumericArray } from '@math.gl/core'; | ||
import type { AxisDirection } from './helpers/ellipsoid-transform'; | ||
import type { AxisDirection } from "./helpers/ellipsoid-transform.js"; | ||
/** | ||
@@ -69,2 +69,1 @@ * A quadratic surface defined in Cartesian coordinates by the equation | ||
} | ||
//# sourceMappingURL=ellipsoid.d.ts.map |
@@ -1,2 +0,4 @@ | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
// This file is derived from the Cesium math library under Apache 2 license | ||
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md | ||
/* eslint-disable */ | ||
import { Vector3, Matrix4, assert, equals, _MathUtils, vec3 } from '@math.gl/core'; | ||
@@ -13,141 +15,127 @@ import { WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z } from "../constants.js"; | ||
const scratchCartesian = new Vector3(); | ||
/** | ||
* A quadratic surface defined in Cartesian coordinates by the equation | ||
* `(x / a)^2 + (y / b)^2 + (z / c)^2 = 1`. Primarily used | ||
* to represent the shape of planetary bodies. | ||
*/ | ||
export class Ellipsoid { | ||
constructor(x = 0.0, y = 0.0, z = 0.0) { | ||
_defineProperty(this, "radii", void 0); | ||
_defineProperty(this, "radiiSquared", void 0); | ||
_defineProperty(this, "radiiToTheFourth", void 0); | ||
_defineProperty(this, "oneOverRadii", void 0); | ||
_defineProperty(this, "oneOverRadiiSquared", void 0); | ||
_defineProperty(this, "minimumRadius", void 0); | ||
_defineProperty(this, "maximumRadius", void 0); | ||
_defineProperty(this, "centerToleranceSquared", _MathUtils.EPSILON1); | ||
_defineProperty(this, "squaredXOverSquaredZ", void 0); | ||
assert(x >= 0.0); | ||
assert(y >= 0.0); | ||
assert(z >= 0.0); | ||
this.radii = new Vector3(x, y, z); | ||
this.radiiSquared = new Vector3(x * x, y * y, z * z); | ||
this.radiiToTheFourth = new Vector3(x * x * x * x, y * y * y * y, z * z * z * z); | ||
this.oneOverRadii = new Vector3(x === 0.0 ? 0.0 : 1.0 / x, y === 0.0 ? 0.0 : 1.0 / y, z === 0.0 ? 0.0 : 1.0 / z); | ||
this.oneOverRadiiSquared = new Vector3(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)); | ||
this.minimumRadius = Math.min(x, y, z); | ||
this.maximumRadius = Math.max(x, y, z); | ||
if (this.radiiSquared.z !== 0) { | ||
this.squaredXOverSquaredZ = this.radiiSquared.x / this.radiiSquared.z; | ||
constructor(x = 0.0, y = 0.0, z = 0.0) { | ||
this.centerToleranceSquared = _MathUtils.EPSILON1; | ||
assert(x >= 0.0); | ||
assert(y >= 0.0); | ||
assert(z >= 0.0); | ||
this.radii = new Vector3(x, y, z); | ||
this.radiiSquared = new Vector3(x * x, y * y, z * z); | ||
this.radiiToTheFourth = new Vector3(x * x * x * x, y * y * y * y, z * z * z * z); | ||
this.oneOverRadii = new Vector3(x === 0.0 ? 0.0 : 1.0 / x, y === 0.0 ? 0.0 : 1.0 / y, z === 0.0 ? 0.0 : 1.0 / z); | ||
this.oneOverRadiiSquared = new Vector3(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)); | ||
this.minimumRadius = Math.min(x, y, z); | ||
this.maximumRadius = Math.max(x, y, z); | ||
if (this.radiiSquared.z !== 0) { | ||
this.squaredXOverSquaredZ = this.radiiSquared.x / this.radiiSquared.z; | ||
} | ||
Object.freeze(this); | ||
} | ||
Object.freeze(this); | ||
} | ||
equals(right) { | ||
return this === right || Boolean(right && this.radii.equals(right.radii)); | ||
} | ||
toString() { | ||
return this.radii.toString(); | ||
} | ||
cartographicToCartesian(cartographic, result = [0, 0, 0]) { | ||
const normal = scratchNormal; | ||
const k = scratchK; | ||
const [,, height] = cartographic; | ||
this.geodeticSurfaceNormalCartographic(cartographic, normal); | ||
k.copy(this.radiiSquared).scale(normal); | ||
const gamma = Math.sqrt(normal.dot(k)); | ||
k.scale(1 / gamma); | ||
normal.scale(height); | ||
k.add(normal); | ||
return k.to(result); | ||
} | ||
cartesianToCartographic(cartesian, result = [0, 0, 0]) { | ||
scratchCartesian.from(cartesian); | ||
const point = this.scaleToGeodeticSurface(scratchCartesian, scratchPosition); | ||
if (!point) { | ||
return undefined; | ||
/** Compares this Ellipsoid against the provided Ellipsoid componentwise */ | ||
equals(right) { | ||
return this === right || Boolean(right && this.radii.equals(right.radii)); | ||
} | ||
const normal = this.geodeticSurfaceNormal(point, scratchNormal); | ||
const h = scratchHeight; | ||
h.copy(scratchCartesian).subtract(point); | ||
const longitude = Math.atan2(normal.y, normal.x); | ||
const latitude = Math.asin(normal.z); | ||
const height = Math.sign(vec3.dot(h, scratchCartesian)) * vec3.length(h); | ||
return toCartographicFromRadians([longitude, latitude, height], result); | ||
} | ||
eastNorthUpToFixedFrame(origin, result = new Matrix4()) { | ||
return localFrameToFixedFrame(this, 'east', 'north', 'up', origin, result); | ||
} | ||
localFrameToFixedFrame(firstAxis, secondAxis, thirdAxis, origin, result = new Matrix4()) { | ||
return localFrameToFixedFrame(this, firstAxis, secondAxis, thirdAxis, origin, result); | ||
} | ||
geocentricSurfaceNormal(cartesian, result = [0, 0, 0]) { | ||
return scratchVector.from(cartesian).normalize().to(result); | ||
} | ||
geodeticSurfaceNormalCartographic(cartographic, result = [0, 0, 0]) { | ||
const cartographicVectorRadians = fromCartographicToRadians(cartographic); | ||
const longitude = cartographicVectorRadians[0]; | ||
const latitude = cartographicVectorRadians[1]; | ||
const cosLatitude = Math.cos(latitude); | ||
scratchVector.set(cosLatitude * Math.cos(longitude), cosLatitude * Math.sin(longitude), Math.sin(latitude)).normalize(); | ||
return scratchVector.to(result); | ||
} | ||
geodeticSurfaceNormal(cartesian, result = [0, 0, 0]) { | ||
return scratchVector.from(cartesian).scale(this.oneOverRadiiSquared).normalize().to(result); | ||
} | ||
scaleToGeodeticSurface(cartesian, result) { | ||
return scaleToGeodeticSurface(cartesian, this, result); | ||
} | ||
scaleToGeocentricSurface(cartesian, result = [0, 0, 0]) { | ||
scratchPosition.from(cartesian); | ||
const positionX = scratchPosition.x; | ||
const positionY = scratchPosition.y; | ||
const positionZ = scratchPosition.z; | ||
const oneOverRadiiSquared = this.oneOverRadiiSquared; | ||
const beta = 1.0 / Math.sqrt(positionX * positionX * oneOverRadiiSquared.x + positionY * positionY * oneOverRadiiSquared.y + positionZ * positionZ * oneOverRadiiSquared.z); | ||
return scratchPosition.multiplyScalar(beta).to(result); | ||
} | ||
transformPositionToScaledSpace(position, result = [0, 0, 0]) { | ||
return scratchPosition.from(position).scale(this.oneOverRadii).to(result); | ||
} | ||
transformPositionFromScaledSpace(position, result = [0, 0, 0]) { | ||
return scratchPosition.from(position).scale(this.radii).to(result); | ||
} | ||
getSurfaceNormalIntersectionWithZAxis(position, buffer = 0, result = [0, 0, 0]) { | ||
assert(equals(this.radii.x, this.radii.y, _MathUtils.EPSILON15)); | ||
assert(this.radii.z > 0); | ||
scratchPosition.from(position); | ||
const z = scratchPosition.z * (1 - this.squaredXOverSquaredZ); | ||
if (Math.abs(z) >= this.radii.z - buffer) { | ||
return undefined; | ||
/** Creates a string representing this Ellipsoid in the format '(radii.x, radii.y, radii.z)'. */ | ||
toString() { | ||
return this.radii.toString(); | ||
} | ||
return scratchPosition.set(0.0, 0.0, z).to(result); | ||
} | ||
cartographicToCartesian(cartographic, result = [0, 0, 0]) { | ||
const normal = scratchNormal; | ||
const k = scratchK; | ||
const [, , height] = cartographic; | ||
this.geodeticSurfaceNormalCartographic(cartographic, normal); | ||
k.copy(this.radiiSquared).scale(normal); | ||
const gamma = Math.sqrt(normal.dot(k)); | ||
k.scale(1 / gamma); | ||
normal.scale(height); | ||
k.add(normal); | ||
return k.to(result); | ||
} | ||
cartesianToCartographic(cartesian, result = [0, 0, 0]) { | ||
scratchCartesian.from(cartesian); | ||
const point = this.scaleToGeodeticSurface(scratchCartesian, scratchPosition); | ||
if (!point) { | ||
return undefined; | ||
} | ||
const normal = this.geodeticSurfaceNormal(point, scratchNormal); | ||
const h = scratchHeight; | ||
h.copy(scratchCartesian).subtract(point); | ||
const longitude = Math.atan2(normal.y, normal.x); | ||
const latitude = Math.asin(normal.z); | ||
const height = Math.sign(vec3.dot(h, scratchCartesian)) * vec3.length(h); | ||
return toCartographicFromRadians([longitude, latitude, height], result); | ||
} | ||
eastNorthUpToFixedFrame(origin, result = new Matrix4()) { | ||
return localFrameToFixedFrame(this, 'east', 'north', 'up', origin, result); | ||
} | ||
// Computes a 4x4 transformation matrix from a reference frame centered at | ||
// the provided origin to the ellipsoid's fixed reference frame. | ||
localFrameToFixedFrame(firstAxis, secondAxis, thirdAxis, origin, result = new Matrix4()) { | ||
return localFrameToFixedFrame(this, firstAxis, secondAxis, thirdAxis, origin, result); | ||
} | ||
geocentricSurfaceNormal(cartesian, result = [0, 0, 0]) { | ||
return scratchVector.from(cartesian).normalize().to(result); | ||
} | ||
geodeticSurfaceNormalCartographic(cartographic, result = [0, 0, 0]) { | ||
const cartographicVectorRadians = fromCartographicToRadians(cartographic); | ||
const longitude = cartographicVectorRadians[0]; | ||
const latitude = cartographicVectorRadians[1]; | ||
const cosLatitude = Math.cos(latitude); | ||
scratchVector | ||
.set(cosLatitude * Math.cos(longitude), cosLatitude * Math.sin(longitude), Math.sin(latitude)) | ||
.normalize(); | ||
return scratchVector.to(result); | ||
} | ||
geodeticSurfaceNormal(cartesian, result = [0, 0, 0]) { | ||
return scratchVector.from(cartesian).scale(this.oneOverRadiiSquared).normalize().to(result); | ||
} | ||
/** Scales the provided Cartesian position along the geodetic surface normal | ||
* so that it is on the surface of this ellipsoid. If the position is | ||
* at the center of the ellipsoid, this function returns undefined. */ | ||
scaleToGeodeticSurface(cartesian, result) { | ||
return scaleToGeodeticSurface(cartesian, this, result); | ||
} | ||
/** Scales the provided Cartesian position along the geocentric surface normal | ||
* so that it is on the surface of this ellipsoid. */ | ||
scaleToGeocentricSurface(cartesian, result = [0, 0, 0]) { | ||
scratchPosition.from(cartesian); | ||
const positionX = scratchPosition.x; | ||
const positionY = scratchPosition.y; | ||
const positionZ = scratchPosition.z; | ||
const oneOverRadiiSquared = this.oneOverRadiiSquared; | ||
const beta = 1.0 / | ||
Math.sqrt(positionX * positionX * oneOverRadiiSquared.x + | ||
positionY * positionY * oneOverRadiiSquared.y + | ||
positionZ * positionZ * oneOverRadiiSquared.z); | ||
return scratchPosition.multiplyScalar(beta).to(result); | ||
} | ||
/** Transforms a Cartesian X, Y, Z position to the ellipsoid-scaled space by multiplying | ||
* its components by the result of `Ellipsoid#oneOverRadii` */ | ||
transformPositionToScaledSpace(position, result = [0, 0, 0]) { | ||
return scratchPosition.from(position).scale(this.oneOverRadii).to(result); | ||
} | ||
/** Transforms a Cartesian X, Y, Z position from the ellipsoid-scaled space by multiplying | ||
* its components by the result of `Ellipsoid#radii`. */ | ||
transformPositionFromScaledSpace(position, result = [0, 0, 0]) { | ||
return scratchPosition.from(position).scale(this.radii).to(result); | ||
} | ||
/** Computes a point which is the intersection of the surface normal with the z-axis. */ | ||
getSurfaceNormalIntersectionWithZAxis(position, buffer = 0, result = [0, 0, 0]) { | ||
// Ellipsoid must be an ellipsoid of revolution (radii.x == radii.y) | ||
assert(equals(this.radii.x, this.radii.y, _MathUtils.EPSILON15)); | ||
assert(this.radii.z > 0); | ||
scratchPosition.from(position); | ||
const z = scratchPosition.z * (1 - this.squaredXOverSquaredZ); | ||
if (Math.abs(z) >= this.radii.z - buffer) { | ||
return undefined; | ||
} | ||
return scratchPosition.set(0.0, 0.0, z).to(result); | ||
} | ||
} | ||
_defineProperty(Ellipsoid, "WGS84", new Ellipsoid(WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z)); | ||
//# sourceMappingURL=ellipsoid.js.map | ||
/** An Ellipsoid instance initialized to the WGS84 standard. */ | ||
Ellipsoid.WGS84 = new Ellipsoid(WGS84_RADIUS_X, WGS84_RADIUS_Y, WGS84_RADIUS_Z); |
import { NumericArray } from '@math.gl/core'; | ||
import type { Ellipsoid } from '../ellipsoid'; | ||
export declare type AxisDirection = 'up' | 'down' | 'north' | 'east' | 'south' | 'west'; | ||
import type { Ellipsoid } from "../ellipsoid.js"; | ||
export type AxisDirection = 'up' | 'down' | 'north' | 'east' | 'south' | 'west'; | ||
export declare function localFrameToFixedFrame(ellipsoid: Ellipsoid, firstAxis: AxisDirection, secondAxis: AxisDirection, thirdAxis: AxisDirection, cartesianOrigin: Readonly<NumericArray>, result: number[]): number[]; | ||
//# sourceMappingURL=ellipsoid-transform.d.ts.map |
import { Vector3, assert, equals as equalsEpsilon } from '@math.gl/core'; | ||
const EPSILON14 = 1e-14; | ||
const scratchOrigin = new Vector3(); | ||
// Caclulate third axis from given two axii | ||
const VECTOR_PRODUCT_LOCAL_FRAME = { | ||
up: { | ||
south: 'east', | ||
north: 'west', | ||
west: 'south', | ||
east: 'north' | ||
}, | ||
down: { | ||
south: 'west', | ||
north: 'east', | ||
west: 'north', | ||
east: 'south' | ||
}, | ||
south: { | ||
up: 'west', | ||
down: 'east', | ||
west: 'down', | ||
east: 'up' | ||
}, | ||
north: { | ||
up: 'east', | ||
down: 'west', | ||
west: 'up', | ||
east: 'down' | ||
}, | ||
west: { | ||
up: 'north', | ||
down: 'south', | ||
north: 'down', | ||
south: 'up' | ||
}, | ||
east: { | ||
up: 'south', | ||
down: 'north', | ||
north: 'up', | ||
south: 'down' | ||
} | ||
up: { | ||
south: 'east', | ||
north: 'west', | ||
west: 'south', | ||
east: 'north' | ||
}, | ||
down: { | ||
south: 'west', | ||
north: 'east', | ||
west: 'north', | ||
east: 'south' | ||
}, | ||
south: { | ||
up: 'west', | ||
down: 'east', | ||
west: 'down', | ||
east: 'up' | ||
}, | ||
north: { | ||
up: 'east', | ||
down: 'west', | ||
west: 'up', | ||
east: 'down' | ||
}, | ||
west: { | ||
up: 'north', | ||
down: 'south', | ||
north: 'down', | ||
south: 'up' | ||
}, | ||
east: { | ||
up: 'south', | ||
down: 'north', | ||
north: 'up', | ||
south: 'down' | ||
} | ||
}; | ||
const degeneratePositionLocalFrame = { | ||
north: [-1, 0, 0], | ||
east: [0, 1, 0], | ||
up: [0, 0, 1], | ||
south: [1, 0, 0], | ||
west: [0, -1, 0], | ||
down: [0, 0, -1] | ||
north: [-1, 0, 0], | ||
east: [0, 1, 0], | ||
up: [0, 0, 1], | ||
south: [1, 0, 0], | ||
west: [0, -1, 0], | ||
down: [0, 0, -1] | ||
}; | ||
const scratchAxisVectors = { | ||
east: new Vector3(), | ||
north: new Vector3(), | ||
up: new Vector3(), | ||
west: new Vector3(), | ||
south: new Vector3(), | ||
down: new Vector3() | ||
east: new Vector3(), | ||
north: new Vector3(), | ||
up: new Vector3(), | ||
west: new Vector3(), | ||
south: new Vector3(), | ||
down: new Vector3() | ||
}; | ||
@@ -61,70 +62,64 @@ const scratchVector1 = new Vector3(); | ||
const scratchVector3 = new Vector3(); | ||
// Computes a 4x4 transformation matrix from a reference frame | ||
// centered at the provided origin to the provided ellipsoid's fixed reference frame. | ||
// eslint-disable-next-line max-statements, max-params, complexity | ||
export function localFrameToFixedFrame(ellipsoid, firstAxis, secondAxis, thirdAxis, cartesianOrigin, result) { | ||
const thirdAxisInferred = VECTOR_PRODUCT_LOCAL_FRAME[firstAxis] && VECTOR_PRODUCT_LOCAL_FRAME[firstAxis][secondAxis]; | ||
assert(thirdAxisInferred && (!thirdAxis || thirdAxis === thirdAxisInferred)); | ||
let firstAxisVector; | ||
let secondAxisVector; | ||
let thirdAxisVector; | ||
const origin = scratchOrigin.copy(cartesianOrigin); | ||
const atPole = equalsEpsilon(origin.x, 0.0, EPSILON14) && equalsEpsilon(origin.y, 0.0, EPSILON14); | ||
if (atPole) { | ||
const sign = Math.sign(origin.z); | ||
firstAxisVector = scratchVector1.fromArray(degeneratePositionLocalFrame[firstAxis]); | ||
if (firstAxis !== 'east' && firstAxis !== 'west') { | ||
firstAxisVector.scale(sign); | ||
const thirdAxisInferred = VECTOR_PRODUCT_LOCAL_FRAME[firstAxis] && VECTOR_PRODUCT_LOCAL_FRAME[firstAxis][secondAxis]; | ||
// firstAxis and secondAxis must be east, north, up, west, south or down.'); | ||
assert(thirdAxisInferred && (!thirdAxis || thirdAxis === thirdAxisInferred)); | ||
let firstAxisVector; | ||
let secondAxisVector; | ||
let thirdAxisVector; | ||
const origin = scratchOrigin.copy(cartesianOrigin); | ||
// If x and y are zero, assume origin is at a pole, which is a special case. | ||
const atPole = equalsEpsilon(origin.x, 0.0, EPSILON14) && equalsEpsilon(origin.y, 0.0, EPSILON14); | ||
if (atPole) { | ||
// Look up axis value and adjust | ||
const sign = Math.sign(origin.z); | ||
firstAxisVector = scratchVector1.fromArray(degeneratePositionLocalFrame[firstAxis]); | ||
if (firstAxis !== 'east' && firstAxis !== 'west') { | ||
firstAxisVector.scale(sign); | ||
} | ||
secondAxisVector = scratchVector2.fromArray(degeneratePositionLocalFrame[secondAxis]); | ||
if (secondAxis !== 'east' && secondAxis !== 'west') { | ||
secondAxisVector.scale(sign); | ||
} | ||
thirdAxisVector = scratchVector3.fromArray(degeneratePositionLocalFrame[thirdAxis]); | ||
if (thirdAxis !== 'east' && thirdAxis !== 'west') { | ||
thirdAxisVector.scale(sign); | ||
} | ||
} | ||
secondAxisVector = scratchVector2.fromArray(degeneratePositionLocalFrame[secondAxis]); | ||
if (secondAxis !== 'east' && secondAxis !== 'west') { | ||
secondAxisVector.scale(sign); | ||
else { | ||
// Calculate all axis | ||
const { up, east, north } = scratchAxisVectors; | ||
east.set(-origin.y, origin.x, 0.0).normalize(); | ||
ellipsoid.geodeticSurfaceNormal(origin, up); | ||
north.copy(up).cross(east); | ||
const { down, west, south } = scratchAxisVectors; | ||
down.copy(up).scale(-1); | ||
west.copy(east).scale(-1); | ||
south.copy(north).scale(-1); | ||
// Pick three axis based on desired orientation | ||
firstAxisVector = scratchAxisVectors[firstAxis]; | ||
secondAxisVector = scratchAxisVectors[secondAxis]; | ||
thirdAxisVector = scratchAxisVectors[thirdAxis]; | ||
} | ||
thirdAxisVector = scratchVector3.fromArray(degeneratePositionLocalFrame[thirdAxis]); | ||
if (thirdAxis !== 'east' && thirdAxis !== 'west') { | ||
thirdAxisVector.scale(sign); | ||
} | ||
} else { | ||
const { | ||
up, | ||
east, | ||
north | ||
} = scratchAxisVectors; | ||
east.set(-origin.y, origin.x, 0.0).normalize(); | ||
ellipsoid.geodeticSurfaceNormal(origin, up); | ||
north.copy(up).cross(east); | ||
const { | ||
down, | ||
west, | ||
south | ||
} = scratchAxisVectors; | ||
down.copy(up).scale(-1); | ||
west.copy(east).scale(-1); | ||
south.copy(north).scale(-1); | ||
firstAxisVector = scratchAxisVectors[firstAxis]; | ||
secondAxisVector = scratchAxisVectors[secondAxis]; | ||
thirdAxisVector = scratchAxisVectors[thirdAxis]; | ||
} | ||
result[0] = firstAxisVector.x; | ||
result[1] = firstAxisVector.y; | ||
result[2] = firstAxisVector.z; | ||
result[3] = 0.0; | ||
result[4] = secondAxisVector.x; | ||
result[5] = secondAxisVector.y; | ||
result[6] = secondAxisVector.z; | ||
result[7] = 0.0; | ||
result[8] = thirdAxisVector.x; | ||
result[9] = thirdAxisVector.y; | ||
result[10] = thirdAxisVector.z; | ||
result[11] = 0.0; | ||
result[12] = origin.x; | ||
result[13] = origin.y; | ||
result[14] = origin.z; | ||
result[15] = 1.0; | ||
return result; | ||
// TODO - assuming the result is column-major | ||
result[0] = firstAxisVector.x; | ||
result[1] = firstAxisVector.y; | ||
result[2] = firstAxisVector.z; | ||
result[3] = 0.0; | ||
result[4] = secondAxisVector.x; | ||
result[5] = secondAxisVector.y; | ||
result[6] = secondAxisVector.z; | ||
result[7] = 0.0; | ||
result[8] = thirdAxisVector.x; | ||
result[9] = thirdAxisVector.y; | ||
result[10] = thirdAxisVector.z; | ||
result[11] = 0.0; | ||
result[12] = origin.x; | ||
result[13] = origin.y; | ||
result[14] = origin.z; | ||
result[15] = 1.0; | ||
return result; | ||
} | ||
//# sourceMappingURL=ellipsoid-transform.js.map |
@@ -1,3 +0,2 @@ | ||
import type { Ellipsoid } from '../ellipsoid'; | ||
import type { Ellipsoid } from "../ellipsoid.js"; | ||
export declare function scaleToGeodeticSurface(cartesian: number[], ellipsoid: Ellipsoid, result?: number[]): number[]; | ||
//# sourceMappingURL=scale-to-geodetic-surface.d.ts.map |
@@ -0,1 +1,2 @@ | ||
/* eslint-disable */ | ||
import { Vector3, _MathUtils } from '@math.gl/core'; | ||
@@ -5,63 +6,66 @@ const scratchVector = new Vector3(); | ||
const scaleToGeodeticSurfaceGradient = new Vector3(); | ||
// Scales the provided Cartesian position along the geodetic surface normal | ||
// so that it is on the surface of this ellipsoid. If the position is | ||
// at the center of the ellipsoid, this function returns undefined. | ||
export function scaleToGeodeticSurface(cartesian, ellipsoid, result = []) { | ||
const { | ||
oneOverRadii, | ||
oneOverRadiiSquared, | ||
centerToleranceSquared | ||
} = ellipsoid; | ||
scratchVector.from(cartesian); | ||
const positionX = scratchVector.x; | ||
const positionY = scratchVector.y; | ||
const positionZ = scratchVector.z; | ||
const oneOverRadiiX = oneOverRadii.x; | ||
const oneOverRadiiY = oneOverRadii.y; | ||
const oneOverRadiiZ = oneOverRadii.z; | ||
const x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX; | ||
const y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY; | ||
const z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ; | ||
const squaredNorm = x2 + y2 + z2; | ||
const ratio = Math.sqrt(1.0 / squaredNorm); | ||
if (!Number.isFinite(ratio)) { | ||
return undefined; | ||
} | ||
const intersection = scaleToGeodeticSurfaceIntersection; | ||
intersection.copy(cartesian).scale(ratio); | ||
if (squaredNorm < centerToleranceSquared) { | ||
return intersection.to(result); | ||
} | ||
const oneOverRadiiSquaredX = oneOverRadiiSquared.x; | ||
const oneOverRadiiSquaredY = oneOverRadiiSquared.y; | ||
const oneOverRadiiSquaredZ = oneOverRadiiSquared.z; | ||
const gradient = scaleToGeodeticSurfaceGradient; | ||
gradient.set(intersection.x * oneOverRadiiSquaredX * 2.0, intersection.y * oneOverRadiiSquaredY * 2.0, intersection.z * oneOverRadiiSquaredZ * 2.0); | ||
let lambda = (1.0 - ratio) * scratchVector.len() / (0.5 * gradient.len()); | ||
let correction = 0.0; | ||
let xMultiplier; | ||
let yMultiplier; | ||
let zMultiplier; | ||
let func; | ||
do { | ||
lambda -= correction; | ||
xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX); | ||
yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY); | ||
zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ); | ||
const xMultiplier2 = xMultiplier * xMultiplier; | ||
const yMultiplier2 = yMultiplier * yMultiplier; | ||
const zMultiplier2 = zMultiplier * zMultiplier; | ||
const xMultiplier3 = xMultiplier2 * xMultiplier; | ||
const yMultiplier3 = yMultiplier2 * yMultiplier; | ||
const zMultiplier3 = zMultiplier2 * zMultiplier; | ||
func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0; | ||
const denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + y2 * yMultiplier3 * oneOverRadiiSquaredY + z2 * zMultiplier3 * oneOverRadiiSquaredZ; | ||
const derivative = -2.0 * denominator; | ||
correction = func / derivative; | ||
} while (Math.abs(func) > _MathUtils.EPSILON12); | ||
return scratchVector.scale([xMultiplier, yMultiplier, zMultiplier]).to(result); | ||
const { oneOverRadii, oneOverRadiiSquared, centerToleranceSquared } = ellipsoid; | ||
scratchVector.from(cartesian); | ||
const positionX = scratchVector.x; | ||
const positionY = scratchVector.y; | ||
const positionZ = scratchVector.z; | ||
const oneOverRadiiX = oneOverRadii.x; | ||
const oneOverRadiiY = oneOverRadii.y; | ||
const oneOverRadiiZ = oneOverRadii.z; | ||
const x2 = positionX * positionX * oneOverRadiiX * oneOverRadiiX; | ||
const y2 = positionY * positionY * oneOverRadiiY * oneOverRadiiY; | ||
const z2 = positionZ * positionZ * oneOverRadiiZ * oneOverRadiiZ; | ||
// Compute the squared ellipsoid norm. | ||
const squaredNorm = x2 + y2 + z2; | ||
const ratio = Math.sqrt(1.0 / squaredNorm); | ||
// When very close to center or at center | ||
if (!Number.isFinite(ratio)) { | ||
return undefined; | ||
} | ||
// As an initial approximation, assume that the radial intersection is the projection point. | ||
const intersection = scaleToGeodeticSurfaceIntersection; | ||
intersection.copy(cartesian).scale(ratio); | ||
// If the position is near the center, the iteration will not converge. | ||
if (squaredNorm < centerToleranceSquared) { | ||
return intersection.to(result); | ||
} | ||
const oneOverRadiiSquaredX = oneOverRadiiSquared.x; | ||
const oneOverRadiiSquaredY = oneOverRadiiSquared.y; | ||
const oneOverRadiiSquaredZ = oneOverRadiiSquared.z; | ||
// Use the gradient at the intersection point in place of the true unit normal. | ||
// The difference in magnitude will be absorbed in the multiplier. | ||
const gradient = scaleToGeodeticSurfaceGradient; | ||
gradient.set(intersection.x * oneOverRadiiSquaredX * 2.0, intersection.y * oneOverRadiiSquaredY * 2.0, intersection.z * oneOverRadiiSquaredZ * 2.0); | ||
// Compute the initial guess at the normal vector multiplier, lambda. | ||
let lambda = ((1.0 - ratio) * scratchVector.len()) / (0.5 * gradient.len()); | ||
let correction = 0.0; | ||
let xMultiplier; | ||
let yMultiplier; | ||
let zMultiplier; | ||
let func; | ||
do { | ||
lambda -= correction; | ||
xMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredX); | ||
yMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredY); | ||
zMultiplier = 1.0 / (1.0 + lambda * oneOverRadiiSquaredZ); | ||
const xMultiplier2 = xMultiplier * xMultiplier; | ||
const yMultiplier2 = yMultiplier * yMultiplier; | ||
const zMultiplier2 = zMultiplier * zMultiplier; | ||
const xMultiplier3 = xMultiplier2 * xMultiplier; | ||
const yMultiplier3 = yMultiplier2 * yMultiplier; | ||
const zMultiplier3 = zMultiplier2 * zMultiplier; | ||
func = x2 * xMultiplier2 + y2 * yMultiplier2 + z2 * zMultiplier2 - 1.0; | ||
// "denominator" here refers to the use of this expression in the velocity and acceleration | ||
// computations in the sections to follow. | ||
const denominator = x2 * xMultiplier3 * oneOverRadiiSquaredX + | ||
y2 * yMultiplier3 * oneOverRadiiSquaredY + | ||
z2 * zMultiplier3 * oneOverRadiiSquaredZ; | ||
const derivative = -2.0 * denominator; | ||
correction = func / derivative; | ||
} while (Math.abs(func) > _MathUtils.EPSILON12); | ||
return scratchVector.scale([xMultiplier, yMultiplier, zMultiplier]).to(result); | ||
} | ||
//# sourceMappingURL=scale-to-geodetic-surface.js.map |
@@ -1,3 +0,2 @@ | ||
export { Ellipsoid } from './ellipsoid/ellipsoid'; | ||
export { isWGS84 } from './type-utils'; | ||
//# sourceMappingURL=index.d.ts.map | ||
export { Ellipsoid } from "./ellipsoid/ellipsoid.js"; | ||
export { isWGS84 } from "./type-utils.js"; |
export { Ellipsoid } from "./ellipsoid/ellipsoid.js"; | ||
export { isWGS84 } from "./type-utils.js"; | ||
//# sourceMappingURL=index.js.map |
import type { NumericArray } from '@math.gl/core'; | ||
declare type LngLatHeightObject = { | ||
type LngLatHeightObject = { | ||
longitude: number; | ||
@@ -7,3 +7,3 @@ latitude: number; | ||
}; | ||
declare type XYZObject = { | ||
type XYZObject = { | ||
x: number; | ||
@@ -13,3 +13,3 @@ y: number; | ||
}; | ||
declare type Cartographic = LngLatHeightObject | XYZObject | NumericArray; | ||
type Cartographic = LngLatHeightObject | XYZObject | NumericArray; | ||
export declare function fromCartographic(cartographic: Readonly<Cartographic>): number[]; | ||
@@ -26,2 +26,1 @@ export declare function fromCartographic<NumArrayT>(cartographic: Readonly<Cartographic>, result: NumArrayT, map?: (x: number) => number): NumArrayT; | ||
export {}; | ||
//# sourceMappingURL=type-utils.d.ts.map |
@@ -0,70 +1,96 @@ | ||
// This file is derived from the Cesium math library under Apache 2 license | ||
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md | ||
import { Vector3, toRadians, toDegrees, config } from '@math.gl/core'; | ||
import { WGS84_CONSTANTS } from "./constants.js"; | ||
function identity(x) { | ||
return x; | ||
return x; | ||
} | ||
const scratchVector = new Vector3(); | ||
export function fromCartographic(cartographic, result = [], map = identity) { | ||
if ('longitude' in cartographic) { | ||
result[0] = map(cartographic.longitude); | ||
result[1] = map(cartographic.latitude); | ||
result[2] = cartographic.height; | ||
} else if ('x' in cartographic) { | ||
result[0] = map(cartographic.x); | ||
result[1] = map(cartographic.y); | ||
result[2] = cartographic.z; | ||
} else { | ||
result[0] = map(cartographic[0]); | ||
result[1] = map(cartographic[1]); | ||
result[2] = cartographic[2]; | ||
} | ||
return result; | ||
if ('longitude' in cartographic) { | ||
result[0] = map(cartographic.longitude); | ||
result[1] = map(cartographic.latitude); | ||
result[2] = cartographic.height; | ||
} | ||
else if ('x' in cartographic) { | ||
result[0] = map(cartographic.x); | ||
result[1] = map(cartographic.y); | ||
result[2] = cartographic.z; | ||
} | ||
else { | ||
result[0] = map(cartographic[0]); | ||
result[1] = map(cartographic[1]); | ||
result[2] = cartographic[2]; | ||
} | ||
return result; | ||
} | ||
export function fromCartographicToRadians(cartographic, vector = []) { | ||
return fromCartographic(cartographic, vector, config._cartographicRadians ? identity : toRadians); | ||
return fromCartographic(cartographic, vector, config._cartographicRadians ? identity : toRadians); | ||
} | ||
export function fromCartographicToDegrees(cartographic, vector = []) { | ||
return fromCartographic(cartographic, vector, config._cartographicRadians ? toDegrees : identity); | ||
return fromCartographic(cartographic, vector, config._cartographicRadians ? toDegrees : identity); | ||
} | ||
export function toCartographic(vector, cartographic, map = identity) { | ||
if ('longitude' in cartographic) { | ||
cartographic.longitude = map(vector[0]); | ||
cartographic.latitude = map(vector[1]); | ||
cartographic.height = vector[2]; | ||
} else if ('x' in cartographic) { | ||
cartographic.x = map(vector[0]); | ||
cartographic.y = map(vector[1]); | ||
cartographic.z = vector[2]; | ||
} else { | ||
cartographic[0] = map(vector[0]); | ||
cartographic[1] = map(vector[1]); | ||
cartographic[2] = vector[2]; | ||
} | ||
return cartographic; | ||
if ('longitude' in cartographic) { | ||
cartographic.longitude = map(vector[0]); | ||
cartographic.latitude = map(vector[1]); | ||
cartographic.height = vector[2]; | ||
} | ||
else if ('x' in cartographic) { | ||
cartographic.x = map(vector[0]); | ||
cartographic.y = map(vector[1]); | ||
cartographic.z = vector[2]; | ||
} | ||
else { | ||
cartographic[0] = map(vector[0]); | ||
cartographic[1] = map(vector[1]); | ||
cartographic[2] = vector[2]; | ||
} | ||
return cartographic; | ||
} | ||
export function toCartographicFromRadians(vector, cartographic) { | ||
return toCartographic(vector, cartographic, config._cartographicRadians ? identity : toDegrees); | ||
return toCartographic(vector, cartographic, config._cartographicRadians ? identity : toDegrees); | ||
} | ||
export function toCartographicFromDegrees(vector, cartographic) { | ||
return toCartographic(vector, cartographic, config._cartographicRadians ? toRadians : identity); | ||
return toCartographic(vector, cartographic, config._cartographicRadians ? toRadians : identity); | ||
} | ||
// Estimates if a vector is close to the surface of the WGS84 Ellipsoid | ||
export function isWGS84(vector) { | ||
if (!vector) { | ||
return false; | ||
} | ||
if (!vector) { | ||
return false; | ||
} | ||
scratchVector.from(vector); | ||
const { oneOverRadiiSquared, centerToleranceSquared } = WGS84_CONSTANTS; | ||
const x2 = vector[0] * vector[0] * oneOverRadiiSquared[0]; | ||
const y2 = vector[1] * vector[1] * oneOverRadiiSquared[1]; | ||
const z2 = vector[2] * vector[2] * oneOverRadiiSquared[2]; | ||
return Math.abs(x2 + y2 + z2 - 1) < centerToleranceSquared; | ||
} | ||
/* | ||
scratchVector.from(vector); | ||
const { | ||
oneOverRadiiSquared, | ||
centerToleranceSquared | ||
} = WGS84_CONSTANTS; | ||
const x2 = vector[0] * vector[0] * oneOverRadiiSquared[0]; | ||
const y2 = vector[1] * vector[1] * oneOverRadiiSquared[1]; | ||
const z2 = vector[2] * vector[2] * oneOverRadiiSquared[2]; | ||
return Math.abs(x2 + y2 + z2 - 1) < centerToleranceSquared; | ||
} | ||
//# sourceMappingURL=type-utils.js.map | ||
export function fromCartographic(cartographic: Cartographic, result?: number[]): number[]; | ||
export function fromCartographic(cartographic: Cartographic, result: TypedArray): TypedArray; | ||
export function fromCartographicToRadians(cartographic: Cartographic, result?: number[]): number[]; | ||
export function fromCartographicToRadians( | ||
cartographic: Cartographic, | ||
result: TypedArray | ||
): TypedArray; | ||
export function fromCartographicToDegrees(cartographic: Cartographic, result?: number[]): number[]; | ||
export function fromCartographicToDegrees( | ||
cartographic: Cartographic, | ||
result: TypedArray | ||
): TypedArray; | ||
export function toCartographic(vector: number[] | TypedArray, result: Cartographic): number[]; | ||
export function toCartographicFromRadians( | ||
vector: number[] | TypedArray, | ||
result: Cartographic | ||
): number[]; | ||
export function toCartographicFromDegrees( | ||
vector: number[] | TypedArray, | ||
result: Cartographic | ||
): number[]; | ||
// Estimates if a vector is close to the surface of the WGS84 Ellipsoid | ||
export function isWGS84(vector: number[] | TypedArray): boolean; | ||
*/ |
@@ -9,3 +9,3 @@ { | ||
}, | ||
"version": "4.0.0", | ||
"version": "4.0.1", | ||
"keywords": [ | ||
@@ -33,5 +33,5 @@ "webgl", | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.js", | ||
"require": "./dist/index.cjs", | ||
"types": "./dist/index.d.ts" | ||
"require": "./dist/index.cjs" | ||
} | ||
@@ -44,6 +44,5 @@ }, | ||
"dependencies": { | ||
"@babel/runtime": "^7.12.0", | ||
"@math.gl/core": "4.0.0" | ||
"@math.gl/core": "4.0.1" | ||
}, | ||
"gitHead": "b7af99a25965af5112307552084fbaf5d4d53b7d" | ||
"gitHead": "33f369ba3a259f79acc3fa8181190c9da8841648" | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1
1537
102127
23
+ Added@math.gl/core@4.0.1(transitive)
+ Added@math.gl/types@4.0.1(transitive)
- Removed@babel/runtime@^7.12.0
- Removed@babel/runtime@7.26.0(transitive)
- Removed@math.gl/core@4.0.0(transitive)
- Removed@math.gl/types@4.0.0(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
Updated@math.gl/core@4.0.1