@math.gl/core 5.0.0-alpha.12 → 5.0.0-alpha.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,139 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // dist/local-frame.js
20
+ var local_frame_exports = {};
21
+ __export(local_frame_exports, {
22
+ createLocalFrameBasis: () => createLocalFrameBasis,
23
+ eastNorthUpBasis: () => eastNorthUpBasis,
24
+ eastNorthUpBasisFromDirections: () => eastNorthUpBasisFromDirections,
25
+ fixedToLocal: () => fixedToLocal,
26
+ localFrameToMatrix: () => localFrameToMatrix,
27
+ localToFixed: () => localToFixed
28
+ });
29
+ module.exports = __toCommonJS(local_frame_exports);
30
+ function createLocalFrameBasis() {
31
+ return { eastX: 0, eastY: 1, northZ: 1, upX: 1, upY: 0, upZ: 0 };
32
+ }
33
+ function eastNorthUpBasis(longitude, latitude, result) {
34
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude) || Math.abs(latitude) > Math.PI / 2)
35
+ return false;
36
+ const sl = Math.sin(longitude), cl = Math.cos(longitude);
37
+ const sp = Math.sin(latitude), cp = Math.cos(latitude);
38
+ return commitBasis(result, -sl, cl, cp, cp * cl, cp * sl, sp);
39
+ }
40
+ function eastNorthUpBasisFromDirections(east, up, result) {
41
+ const ex = east.x, ey = east.y, ez = east.z;
42
+ const ux = up.x, uy = up.y, uz = up.z;
43
+ if (ez !== 0)
44
+ return false;
45
+ return commitBasis(result, ex, ey, ux * ey - uy * ex, ux, uy, uz);
46
+ }
47
+ function localToFixed(point, basis, result = point) {
48
+ const sl = -basis.eastX, cl = basis.eastY, sp = basis.upZ, cp = basis.northZ;
49
+ const east = point.x, north = point.y, up = point.z;
50
+ const radial = up * cp - north * sp;
51
+ return commitPoint(result, radial * cl - east * sl, radial * sl + east * cl, up * sp + north * cp);
52
+ }
53
+ function fixedToLocal(point, basis, result = point) {
54
+ const ex = basis.eastX, ey = basis.eastY, nz = basis.northZ;
55
+ const ux = basis.upX, uy = basis.upY, uz = basis.upZ;
56
+ const x = point.x, y = point.y, z = point.z;
57
+ return commitPoint(result, x * ex + y * ey, -x * uz * ey + y * uz * ex + z * nz, x * ux + y * uy + z * uz);
58
+ }
59
+ function localFrameToMatrix(basis, origin, firstAxis, secondAxis, thirdAxis, result) {
60
+ const first = axisCode(firstAxis), second = axisCode(secondAxis), third = axisCode(thirdAxis);
61
+ const a = Math.abs(first), b = Math.abs(second), c = Math.abs(third);
62
+ if (!a || !b || !c || a === b || a === c || b === c)
63
+ return false;
64
+ const parity = a % 3 + 1 === b ? 1 : -1;
65
+ if (parity * Math.sign(first * second * third) !== 1 || !Array.isArray(result) && result.length < 16)
66
+ return false;
67
+ const ex = basis.eastX, ey = basis.eastY, nz = basis.northZ;
68
+ const ux = basis.upX, uy = basis.upY, uz = basis.upZ;
69
+ const nx = -uz * ey, ny = uz * ex;
70
+ const x = origin.x, y = origin.y, z = origin.z;
71
+ const ax = (a === 1 ? ex : a === 2 ? nx : ux) * Math.sign(first);
72
+ const ay = (a === 1 ? ey : a === 2 ? ny : uy) * Math.sign(first);
73
+ const az = (a === 1 ? 0 : a === 2 ? nz : uz) * Math.sign(first);
74
+ const bx = (b === 1 ? ex : b === 2 ? nx : ux) * Math.sign(second);
75
+ const by = (b === 1 ? ey : b === 2 ? ny : uy) * Math.sign(second);
76
+ const bz = (b === 1 ? 0 : b === 2 ? nz : uz) * Math.sign(second);
77
+ const cx = (c === 1 ? ex : c === 2 ? nx : ux) * Math.sign(third);
78
+ const cy = (c === 1 ? ey : c === 2 ? ny : uy) * Math.sign(third);
79
+ const cz = (c === 1 ? 0 : c === 2 ? nz : uz) * Math.sign(third);
80
+ if (!Number.isFinite(ax) || !Number.isFinite(ay) || !Number.isFinite(az) || !Number.isFinite(bx) || !Number.isFinite(by) || !Number.isFinite(bz) || !Number.isFinite(cx) || !Number.isFinite(cy) || !Number.isFinite(cz) || !Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z))
81
+ return false;
82
+ if (result instanceof Float32Array && (!Number.isFinite(Math.fround(ax)) || !Number.isFinite(Math.fround(ay)) || !Number.isFinite(Math.fround(az)) || !Number.isFinite(Math.fround(bx)) || !Number.isFinite(Math.fround(by)) || !Number.isFinite(Math.fround(bz)) || !Number.isFinite(Math.fround(cx)) || !Number.isFinite(Math.fround(cy)) || !Number.isFinite(Math.fround(cz)) || !Number.isFinite(Math.fround(x)) || !Number.isFinite(Math.fround(y)) || !Number.isFinite(Math.fround(z))))
83
+ return false;
84
+ result[0] = ax;
85
+ result[1] = ay;
86
+ result[2] = az;
87
+ result[3] = 0;
88
+ result[4] = bx;
89
+ result[5] = by;
90
+ result[6] = bz;
91
+ result[7] = 0;
92
+ result[8] = cx;
93
+ result[9] = cy;
94
+ result[10] = cz;
95
+ result[11] = 0;
96
+ result[12] = x;
97
+ result[13] = y;
98
+ result[14] = z;
99
+ result[15] = 1;
100
+ return true;
101
+ }
102
+ function axisCode(axis) {
103
+ switch (axis) {
104
+ case "east":
105
+ return 1;
106
+ case "west":
107
+ return -1;
108
+ case "north":
109
+ return 2;
110
+ case "south":
111
+ return -2;
112
+ case "up":
113
+ return 3;
114
+ case "down":
115
+ return -3;
116
+ default:
117
+ return 0;
118
+ }
119
+ }
120
+ function commitBasis(result, ex, ey, nz, ux, uy, uz) {
121
+ if (!Number.isFinite(ex) || !Number.isFinite(ey) || !Number.isFinite(nz) || !Number.isFinite(ux) || !Number.isFinite(uy) || !Number.isFinite(uz))
122
+ return false;
123
+ result.eastX = ex;
124
+ result.eastY = ey;
125
+ result.northZ = nz;
126
+ result.upX = ux;
127
+ result.upY = uy;
128
+ result.upZ = uz;
129
+ return true;
130
+ }
131
+ function commitPoint(result, x, y, z) {
132
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z))
133
+ return false;
134
+ result.x = x;
135
+ result.y = y;
136
+ result.z = z;
137
+ return true;
138
+ }
139
+ //# sourceMappingURL=local-frame.cjs.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/local-frame.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }
@@ -0,0 +1,39 @@
1
+ import type { NumericArray } from '@math.gl/types';
2
+ export type LocalFramePoint = {
3
+ x: number;
4
+ y: number;
5
+ z: number;
6
+ };
7
+ export type LocalFrameAxis = 'east' | 'north' | 'up' | 'west' | 'south' | 'down';
8
+ /** East has zero Z. North is up × east; northZ is its horizontal radial factor. */
9
+ export type LocalFrameBasis = {
10
+ eastX: number;
11
+ eastY: number;
12
+ northZ: number;
13
+ upX: number;
14
+ upY: number;
15
+ upZ: number;
16
+ };
17
+ /** Setup-time scratch, initially the ENU basis at longitude/latitude zero. */
18
+ export declare function createLocalFrameBasis(): LocalFrameBasis;
19
+ /** Angles in radians. Longitude is periodic; latitude must be within ±π/2. */
20
+ export declare function eastNorthUpBasis(longitude: number, latitude: number, result: LocalFrameBasis): boolean;
21
+ /**
22
+ * Caller supplies finite unit east/up directions, east.z=0, mutually perpendicular,
23
+ * and an up direction whose horizontal component points radially outward.
24
+ * This form preserves supplied up components rather than inferring a geodetic footpoint.
25
+ * Finiteness is checked; orthonormality is a caller precondition, not certified here.
26
+ */
27
+ export declare function eastNorthUpBasisFromDirections(east: LocalFramePoint, up: LocalFramePoint, result: LocalFrameBasis): boolean;
28
+ /** Rotate ENU offsets/velocities to fixed XYZ. Distances retain the input unit. */
29
+ export declare function localToFixed(point: LocalFramePoint, basis: LocalFrameBasis, result?: LocalFramePoint): boolean;
30
+ /** Transpose rotation, valid for the orthonormal ENU basis precondition. */
31
+ export declare function fixedToLocal(point: LocalFramePoint, basis: LocalFrameBasis, result?: LocalFramePoint): boolean;
32
+ /**
33
+ * Column-major affine matrix, with explicit signed local axes and fixed-space origin.
34
+ * Axis triples must be right handed (e.g. east/north/up or north/east/down).
35
+ * Translation uses the origin's distance unit. The basis itself has no origin.
36
+ * A failure leaves output unchanged; caller owns writable storage (a growable number array or a typed array of length ≥16).
37
+ */
38
+ export declare function localFrameToMatrix(basis: LocalFrameBasis, origin: LocalFramePoint, firstAxis: LocalFrameAxis, secondAxis: LocalFrameAxis, thirdAxis: LocalFrameAxis, result: NumericArray): boolean;
39
+ //# sourceMappingURL=local-frame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-frame.d.ts","sourceRoot":"","sources":["../src/local-frame.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAEjD,MAAM,MAAM,eAAe,GAAG;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAChE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AACjF,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,qBAAqB,IAAI,eAAe,CAEvD;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,eAAe,GACtB,OAAO,CAQT;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,eAAe,EACrB,EAAE,EAAE,eAAe,EACnB,MAAM,EAAE,eAAe,GACtB,OAAO,CAST;AAED,mFAAmF;AACnF,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,eAAe,EACtB,MAAM,GAAE,eAAuB,GAC9B,OAAO,CAgBT;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,eAAe,EACtB,MAAM,GAAE,eAAuB,GAC9B,OAAO,CAgBT;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,cAAc,EACzB,UAAU,EAAE,cAAc,EAC1B,SAAS,EAAE,cAAc,EACzB,MAAM,EAAE,YAAY,GACnB,OAAO,CAmFT"}
@@ -0,0 +1,157 @@
1
+ /** Setup-time scratch, initially the ENU basis at longitude/latitude zero. */
2
+ export function createLocalFrameBasis() {
3
+ return { eastX: 0, eastY: 1, northZ: 1, upX: 1, upY: 0, upZ: 0 };
4
+ }
5
+ /** Angles in radians. Longitude is periodic; latitude must be within ±π/2. */
6
+ export function eastNorthUpBasis(longitude, latitude, result) {
7
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude) || Math.abs(latitude) > Math.PI / 2)
8
+ return false;
9
+ const sl = Math.sin(longitude), cl = Math.cos(longitude);
10
+ const sp = Math.sin(latitude), cp = Math.cos(latitude);
11
+ return commitBasis(result, -sl, cl, cp, cp * cl, cp * sl, sp);
12
+ }
13
+ /**
14
+ * Caller supplies finite unit east/up directions, east.z=0, mutually perpendicular,
15
+ * and an up direction whose horizontal component points radially outward.
16
+ * This form preserves supplied up components rather than inferring a geodetic footpoint.
17
+ * Finiteness is checked; orthonormality is a caller precondition, not certified here.
18
+ */
19
+ export function eastNorthUpBasisFromDirections(east, up, result) {
20
+ const ex = east.x, ey = east.y, ez = east.z;
21
+ const ux = up.x, uy = up.y, uz = up.z;
22
+ if (ez !== 0)
23
+ return false;
24
+ return commitBasis(result, ex, ey, ux * ey - uy * ex, ux, uy, uz);
25
+ }
26
+ /** Rotate ENU offsets/velocities to fixed XYZ. Distances retain the input unit. */
27
+ export function localToFixed(point, basis, result = point) {
28
+ const sl = -basis.eastX, cl = basis.eastY, sp = basis.upZ, cp = basis.northZ;
29
+ const east = point.x, north = point.y, up = point.z;
30
+ // Retain the factored rotation order used by deformation; no intermediate vector.
31
+ const radial = up * cp - north * sp;
32
+ return commitPoint(result, radial * cl - east * sl, radial * sl + east * cl, up * sp + north * cp);
33
+ }
34
+ /** Transpose rotation, valid for the orthonormal ENU basis precondition. */
35
+ export function fixedToLocal(point, basis, result = point) {
36
+ const ex = basis.eastX, ey = basis.eastY, nz = basis.northZ;
37
+ const ux = basis.upX, uy = basis.upY, uz = basis.upZ;
38
+ const x = point.x, y = point.y, z = point.z;
39
+ return commitPoint(result, x * ex + y * ey, -x * uz * ey + y * uz * ex + z * nz, x * ux + y * uy + z * uz);
40
+ }
41
+ /**
42
+ * Column-major affine matrix, with explicit signed local axes and fixed-space origin.
43
+ * Axis triples must be right handed (e.g. east/north/up or north/east/down).
44
+ * Translation uses the origin's distance unit. The basis itself has no origin.
45
+ * A failure leaves output unchanged; caller owns writable storage (a growable number array or a typed array of length ≥16).
46
+ */
47
+ export function localFrameToMatrix(basis, origin, firstAxis, secondAxis, thirdAxis, result) {
48
+ const first = axisCode(firstAxis), second = axisCode(secondAxis), third = axisCode(thirdAxis);
49
+ const a = Math.abs(first), b = Math.abs(second), c = Math.abs(third);
50
+ if (!a || !b || !c || a === b || a === c || b === c)
51
+ return false;
52
+ const parity = (a % 3) + 1 === b ? 1 : -1;
53
+ if (parity * Math.sign(first * second * third) !== 1 ||
54
+ (!Array.isArray(result) && result.length < 16))
55
+ return false;
56
+ const ex = basis.eastX, ey = basis.eastY, nz = basis.northZ;
57
+ const ux = basis.upX, uy = basis.upY, uz = basis.upZ;
58
+ const nx = -uz * ey, ny = uz * ex;
59
+ const x = origin.x, y = origin.y, z = origin.z;
60
+ const ax = (a === 1 ? ex : a === 2 ? nx : ux) * Math.sign(first);
61
+ const ay = (a === 1 ? ey : a === 2 ? ny : uy) * Math.sign(first);
62
+ const az = (a === 1 ? 0 : a === 2 ? nz : uz) * Math.sign(first);
63
+ const bx = (b === 1 ? ex : b === 2 ? nx : ux) * Math.sign(second);
64
+ const by = (b === 1 ? ey : b === 2 ? ny : uy) * Math.sign(second);
65
+ const bz = (b === 1 ? 0 : b === 2 ? nz : uz) * Math.sign(second);
66
+ const cx = (c === 1 ? ex : c === 2 ? nx : ux) * Math.sign(third);
67
+ const cy = (c === 1 ? ey : c === 2 ? ny : uy) * Math.sign(third);
68
+ const cz = (c === 1 ? 0 : c === 2 ? nz : uz) * Math.sign(third);
69
+ if (!Number.isFinite(ax) ||
70
+ !Number.isFinite(ay) ||
71
+ !Number.isFinite(az) ||
72
+ !Number.isFinite(bx) ||
73
+ !Number.isFinite(by) ||
74
+ !Number.isFinite(bz) ||
75
+ !Number.isFinite(cx) ||
76
+ !Number.isFinite(cy) ||
77
+ !Number.isFinite(cz) ||
78
+ !Number.isFinite(x) ||
79
+ !Number.isFinite(y) ||
80
+ !Number.isFinite(z))
81
+ return false;
82
+ if (result instanceof Float32Array &&
83
+ (!Number.isFinite(Math.fround(ax)) ||
84
+ !Number.isFinite(Math.fround(ay)) ||
85
+ !Number.isFinite(Math.fround(az)) ||
86
+ !Number.isFinite(Math.fround(bx)) ||
87
+ !Number.isFinite(Math.fround(by)) ||
88
+ !Number.isFinite(Math.fround(bz)) ||
89
+ !Number.isFinite(Math.fround(cx)) ||
90
+ !Number.isFinite(Math.fround(cy)) ||
91
+ !Number.isFinite(Math.fround(cz)) ||
92
+ !Number.isFinite(Math.fround(x)) ||
93
+ !Number.isFinite(Math.fround(y)) ||
94
+ !Number.isFinite(Math.fround(z))))
95
+ return false;
96
+ // Snapshot every component before application setters can recursively change scratch.
97
+ result[0] = ax;
98
+ result[1] = ay;
99
+ result[2] = az;
100
+ result[3] = 0;
101
+ result[4] = bx;
102
+ result[5] = by;
103
+ result[6] = bz;
104
+ result[7] = 0;
105
+ result[8] = cx;
106
+ result[9] = cy;
107
+ result[10] = cz;
108
+ result[11] = 0;
109
+ result[12] = x;
110
+ result[13] = y;
111
+ result[14] = z;
112
+ result[15] = 1;
113
+ return true;
114
+ }
115
+ function axisCode(axis) {
116
+ switch (axis) {
117
+ case 'east':
118
+ return 1;
119
+ case 'west':
120
+ return -1;
121
+ case 'north':
122
+ return 2;
123
+ case 'south':
124
+ return -2;
125
+ case 'up':
126
+ return 3;
127
+ case 'down':
128
+ return -3;
129
+ default:
130
+ return 0;
131
+ }
132
+ }
133
+ function commitBasis(result, ex, ey, nz, ux, uy, uz) {
134
+ if (!Number.isFinite(ex) ||
135
+ !Number.isFinite(ey) ||
136
+ !Number.isFinite(nz) ||
137
+ !Number.isFinite(ux) ||
138
+ !Number.isFinite(uy) ||
139
+ !Number.isFinite(uz))
140
+ return false;
141
+ result.eastX = ex;
142
+ result.eastY = ey;
143
+ result.northZ = nz;
144
+ result.upX = ux;
145
+ result.upY = uy;
146
+ result.upZ = uz;
147
+ return true;
148
+ }
149
+ function commitPoint(result, x, y, z) {
150
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z))
151
+ return false;
152
+ result.x = x;
153
+ result.y = y;
154
+ result.z = z;
155
+ return true;
156
+ }
157
+ //# sourceMappingURL=local-frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-frame.js","sourceRoot":"","sources":["../src/local-frame.ts"],"names":[],"mappings":"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C,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CA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"}
package/dist/spheroid.cjs CHANGED
@@ -44,6 +44,9 @@ function cartesianToSpheroid(point, geometry, result = point) {
44
44
  return commit(result, p === 0 ? 0 : Math.atan2(y, x), Math.atan2(z, p), rr - a);
45
45
  if (p === 0)
46
46
  return commit(result, 0, Math.sign(z) * Math.PI / 2, Math.abs(z) - b);
47
+ const horizontal = p / a, vertical = z / b;
48
+ if (horizontal * horizontal + vertical * vertical < 1 - 16 * Number.EPSILON)
49
+ return interiorInverse(x, y, z, p, a, b, result);
47
50
  if (es >= 0.9)
48
51
  return exteriorInverse(x, y, z, p, a, b, result);
49
52
  const ct = z / rr, st = p / rr;
@@ -65,6 +68,67 @@ function cartesianToSpheroid(point, geometry, result = point) {
65
68
  }
66
69
  return exteriorInverse(x, y, z, p, a, b, result);
67
70
  }
71
+ function interiorInverse(x, y, z, p, a, b, result) {
72
+ const ratio = b / a, ratio2 = ratio * ratio;
73
+ const horizontal = p / a, vertical = z / a, delta = 1 - ratio2;
74
+ if (!(ratio2 > 0) || ratio > 1)
75
+ return false;
76
+ if (z === 0) {
77
+ if (horizontal < delta)
78
+ return false;
79
+ return commit(result, Math.atan2(y, x), 0, p - a);
80
+ }
81
+ const aa = a * a, bb = b * b;
82
+ const ratioError = Number.isFinite(aa) && aa > 0 ? (bb - ratio2 * aa + productError(b, b, bb) - ratio2 * productError(a, a, aa) - productError(ratio2, aa, ratio2 * aa)) / aa : 0;
83
+ const pp = p * p, xx = x * x, yy = y * y, sum = xx + yy;
84
+ const radiusError = Number.isFinite(pp) && pp > 0 ? (sum - pp + sumError(xx, yy, sum) + productError(x, x, xx) + productError(y, y, yy) - productError(p, p, pp)) / (2 * p) : 0;
85
+ const shift = a * ratio2, base = p - a + shift;
86
+ const correction = radiusError + sumError(p - a, shift, base) + productError(a, ratio2, shift) + a * ratioError;
87
+ const weighted = Math.abs(vertical) * ratio;
88
+ if (!(weighted > 0))
89
+ return false;
90
+ let lower = 0, upper = ratio2;
91
+ let t = Math.max(weighted, horizontal - delta);
92
+ if (!(t > lower && t < upper))
93
+ t = upper / 2;
94
+ for (let i = 0; i < 128; i++) {
95
+ const equatorial = delta + t;
96
+ const u = horizontal / equatorial, v = weighted / t;
97
+ const at = a * t, difference = base - at;
98
+ const offset = (difference + (sumError(base, -at, difference) + correction - productError(a, t, at))) / (a * equatorial);
99
+ const term = offset * (u + 1);
100
+ const residual = term + v * v;
101
+ if (Math.abs(residual) <= 4 * Number.EPSILON * (Math.abs(term) + v * v) || upper - lower <= 4 * Number.EPSILON * t) {
102
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
103
+ const sin = Math.sin(latitude), cos = Math.cos(latitude);
104
+ return commit(result, Math.atan2(y, x), latitude, p * cos + z * sin - a * Math.hypot(cos, ratio * sin));
105
+ }
106
+ if (residual > 0)
107
+ lower = t;
108
+ else
109
+ upper = t;
110
+ const derivative = -2 * (u * u / equatorial + v * v / t);
111
+ const next = t - residual / derivative;
112
+ const candidate = Number.isFinite(next) && next > lower && next < upper ? next : lower + (upper - lower) / 2;
113
+ if (candidate === t) {
114
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
115
+ return commit(result, Math.atan2(y, x), latitude, p * Math.cos(latitude) + z * Math.sin(latitude) - a * Math.hypot(Math.cos(latitude), ratio * Math.sin(latitude)));
116
+ }
117
+ t = candidate;
118
+ }
119
+ return false;
120
+ }
121
+ function sumError(x, y, sum) {
122
+ const part = sum - x;
123
+ return x - (sum - part) + (y - part);
124
+ }
125
+ function productError(x, y, product) {
126
+ const sx = 134217729 * x, sy = 134217729 * y;
127
+ if (!Number.isFinite(sx) || !Number.isFinite(sy))
128
+ return 0;
129
+ const hx = sx - (sx - x), hy = sy - (sy - y), lx = x - hx, ly = y - hy;
130
+ return hx * hy - product + hx * ly + lx * hy + lx * ly;
131
+ }
68
132
  function exteriorInverse(x, y, z, p, a, b, result) {
69
133
  const ratio = b / a, ratio2 = ratio * ratio, horizontal = p / a, vertical = z / a;
70
134
  const norm = Math.hypot(horizontal, z / b);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/spheroid.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
@@ -12,8 +12,9 @@ export type SpheroidPoint = {
12
12
  export declare function spheroidToCartesian(point: SpheroidPoint, geometry: SpheroidGeometry, result?: SpheroidPoint): boolean;
13
13
  /**
14
14
  * Bounded inverse. Sphere is analytic; ordinary spheroids use the retained Hannover
15
- * iteration. Very flat/exterior failures use a safeguarded normal-footpoint solve.
16
- * false leaves output untouched. Interior ambiguity is not resolved by this API.
15
+ * iteration on exterior points. Interiors use a safeguarded nearest-footpoint solve.
16
+ * Equatorial interiors below the evolute cusp have two nearest normals: reject.
17
+ * false leaves output untouched, including the center and unresolved binary64 cases.
17
18
  * Only exact poles canonicalize longitude; adapters may retain other conventions.
18
19
  */
19
20
  export declare function cartesianToSpheroid(point: SpheroidPoint, geometry: SpheroidGeometry, result?: SpheroidPoint): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"spheroid.d.ts","sourceRoot":"","sources":["../src/spheroid.ts"],"names":[],"mappings":"AAMA,kGAAkG;AAClG,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAC,CAAC;AAC3F,MAAM,MAAM,aAAa,GAAG;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D,6FAA6F;AAC7F,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,GAAE,aAAqB,GAC5B,OAAO,CAcT;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,GAAE,aAAqB,GAC5B,OAAO,CA+BT"}
1
+ {"version":3,"file":"spheroid.d.ts","sourceRoot":"","sources":["../src/spheroid.ts"],"names":[],"mappings":"AAMA,kGAAkG;AAClG,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AACvD,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG;IAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAA;CAAC,CAAC;AAC3F,MAAM,MAAM,aAAa,GAAG;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC;AAE9D,6FAA6F;AAC7F,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,GAAE,aAAqB,GAC5B,OAAO,CAcT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,GAAE,aAAqB,GAC5B,OAAO,CAmCT"}
package/dist/spheroid.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // SPDX-FileCopyrightText: 2014 Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf (proj4js)
4
4
  // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
5
- // SPDX-FileComment: Forward geocentric equations and Hannover inverse moved/adapted from math.gl projection's proj4js 2.22.0 datumUtils.js port. See ../PROJ4-LICENSE.md. Safeguarded exterior inverse and numeric output commit are original math.gl code.
5
+ // SPDX-FileComment: Forward geocentric equations and Hannover inverse moved/adapted from math.gl projection's proj4js 2.22.0 datumUtils.js port. See ../PROJ4-LICENSE.md. Safeguarded nearest-footpoint inverse and numeric output commit are original math.gl code.
6
6
  /** Caller supplies validated positive finite axes and eccentricity. No latitude wrapping. */
7
7
  export function spheroidToCartesian(point, geometry, result = point) {
8
8
  const longitude = point.x, latitude = point.y, height = point.z;
@@ -18,8 +18,9 @@ export function spheroidToCartesian(point, geometry, result = point) {
18
18
  }
19
19
  /**
20
20
  * Bounded inverse. Sphere is analytic; ordinary spheroids use the retained Hannover
21
- * iteration. Very flat/exterior failures use a safeguarded normal-footpoint solve.
22
- * false leaves output untouched. Interior ambiguity is not resolved by this API.
21
+ * iteration on exterior points. Interiors use a safeguarded nearest-footpoint solve.
22
+ * Equatorial interiors below the evolute cusp have two nearest normals: reject.
23
+ * false leaves output untouched, including the center and unresolved binary64 cases.
23
24
  * Only exact poles canonicalize longitude; adapters may retain other conventions.
24
25
  */
25
26
  export function cartesianToSpheroid(point, geometry, result = point) {
@@ -32,6 +33,9 @@ export function cartesianToSpheroid(point, geometry, result = point) {
32
33
  return commit(result, p === 0 ? 0 : Math.atan2(y, x), Math.atan2(z, p), rr - a);
33
34
  if (p === 0)
34
35
  return commit(result, 0, (Math.sign(z) * Math.PI) / 2, Math.abs(z) - b);
36
+ const horizontal = p / a, vertical = z / b;
37
+ if (horizontal * horizontal + vertical * vertical < 1 - 16 * Number.EPSILON)
38
+ return interiorInverse(x, y, z, p, a, b, result);
35
39
  if (es >= 0.9)
36
40
  return exteriorInverse(x, y, z, p, a, b, result);
37
41
  const ct = z / rr, st = p / rr;
@@ -53,6 +57,92 @@ export function cartesianToSpheroid(point, geometry, result = point) {
53
57
  }
54
58
  return exteriorInverse(x, y, z, p, a, b, result);
55
59
  }
60
+ /** Original nearest-normal solve in t = (lambda + b²)/a², avoiding interior cancellation.
61
+ * The positive interval selects the globally nearest branch, rather than a stationary normal.
62
+ */
63
+ function interiorInverse(x, y, z, p, a, b, result) {
64
+ const ratio = b / a, ratio2 = ratio * ratio;
65
+ const horizontal = p / a, vertical = z / a, delta = 1 - ratio2;
66
+ if (!(ratio2 > 0) || ratio > 1)
67
+ return false;
68
+ if (z === 0) {
69
+ if (horizontal < delta)
70
+ return false;
71
+ return commit(result, Math.atan2(y, x), 0, p - a);
72
+ }
73
+ const aa = a * a, bb = b * b;
74
+ const ratioError = Number.isFinite(aa) && aa > 0
75
+ ? (bb -
76
+ ratio2 * aa +
77
+ productError(b, b, bb) -
78
+ ratio2 * productError(a, a, aa) -
79
+ productError(ratio2, aa, ratio2 * aa)) /
80
+ aa
81
+ : 0;
82
+ const pp = p * p, xx = x * x, yy = y * y, sum = xx + yy;
83
+ const radiusError = Number.isFinite(pp) && pp > 0
84
+ ? (sum -
85
+ pp +
86
+ sumError(xx, yy, sum) +
87
+ productError(x, x, xx) +
88
+ productError(y, y, yy) -
89
+ productError(p, p, pp)) /
90
+ (2 * p)
91
+ : 0;
92
+ const shift = a * ratio2, base = p - a + shift;
93
+ const correction = radiusError + sumError(p - a, shift, base) + productError(a, ratio2, shift) + a * ratioError;
94
+ const weighted = Math.abs(vertical) * ratio;
95
+ if (!(weighted > 0))
96
+ return false;
97
+ let lower = 0, upper = ratio2;
98
+ // A lower bound near the short-axis singularity prevents thousands of bisections
99
+ // for deep, nearly equatorial interiors. No subtraction of lambda and -b².
100
+ let t = Math.max(weighted, horizontal - delta);
101
+ if (!(t > lower && t < upper))
102
+ t = upper / 2;
103
+ for (let i = 0; i < 128; i++) {
104
+ const equatorial = delta + t;
105
+ const u = horizontal / equatorial, v = weighted / t;
106
+ const at = a * t, difference = base - at;
107
+ const offset = (difference + (sumError(base, -at, difference) + correction - productError(a, t, at))) /
108
+ (a * equatorial);
109
+ const term = offset * (u + 1);
110
+ const residual = term + v * v;
111
+ if (Math.abs(residual) <= 4 * Number.EPSILON * (Math.abs(term) + v * v) ||
112
+ upper - lower <= 4 * Number.EPSILON * t) {
113
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
114
+ const sin = Math.sin(latitude), cos = Math.cos(latitude);
115
+ return commit(result, Math.atan2(y, x), latitude, p * cos + z * sin - a * Math.hypot(cos, ratio * sin));
116
+ }
117
+ if (residual > 0)
118
+ lower = t;
119
+ else
120
+ upper = t;
121
+ const derivative = -2 * ((u * u) / equatorial + (v * v) / t);
122
+ const next = t - residual / derivative;
123
+ const candidate = Number.isFinite(next) && next > lower && next < upper ? next : lower + (upper - lower) / 2;
124
+ if (candidate === t) {
125
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
126
+ return commit(result, Math.atan2(y, x), latitude, p * Math.cos(latitude) +
127
+ z * Math.sin(latitude) -
128
+ a * Math.hypot(Math.cos(latitude), ratio * Math.sin(latitude)));
129
+ }
130
+ t = candidate;
131
+ }
132
+ return false;
133
+ }
134
+ /** Error-free transforms on the finite squared-axis domain used by geometry adapters. */
135
+ function sumError(x, y, sum) {
136
+ const part = sum - x;
137
+ return x - (sum - part) + (y - part);
138
+ }
139
+ function productError(x, y, product) {
140
+ const sx = 134217729 * x, sy = 134217729 * y;
141
+ if (!Number.isFinite(sx) || !Number.isFinite(sy))
142
+ return 0;
143
+ const hx = sx - (sx - x), hy = sy - (sy - y), lx = x - hx, ly = y - hy;
144
+ return hx * hy - product + hx * ly + lx * hy + lx * ly;
145
+ }
56
146
  /** Original dimensionless Lagrange-multiplier solve, restricted to surface/exterior. */
57
147
  function exteriorInverse(x, y, z, p, a, b, result) {
58
148
  const ratio = b / a, ratio2 = ratio * ratio, horizontal = p / a, vertical = z / a;
@@ -1 +1 @@
1
- {"version":3,"file":"spheroid.js","sourceRoot":"","sources":["../src/spheroid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spheroid.js","sourceRoot":"","sources":["../src/spheroid.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
9
- "version": "5.0.0-alpha.12",
9
+ "version": "5.0.0-alpha.14",
10
10
  "keywords": [
11
11
  "webgl",
12
12
  "javascript",
@@ -66,6 +66,11 @@
66
66
  "import": "./dist/vec4.js",
67
67
  "require": "./dist/vec4.cjs"
68
68
  },
69
+ "./local-frame": {
70
+ "types": "./dist/local-frame.d.ts",
71
+ "import": "./dist/local-frame.js",
72
+ "require": "./dist/local-frame.cjs"
73
+ },
69
74
  "./spheroid": {
70
75
  "types": "./dist/spheroid.d.ts",
71
76
  "import": "./dist/spheroid.js",
@@ -81,7 +86,7 @@
81
86
  "./src/lib/common.js"
82
87
  ],
83
88
  "dependencies": {
84
- "@math.gl/types": "5.0.0-alpha.12"
89
+ "@math.gl/types": "5.0.0-alpha.14"
85
90
  },
86
- "gitHead": "9f9ed72b110b898a5e2df55984b6cff67f8feab2"
91
+ "gitHead": "c4f1cbdd7fc9136a873efc511356cace8ff0001a"
87
92
  }
@@ -0,0 +1,253 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
4
+ // SPDX-FileComment: Original factored ENU/NED basis, rotations and matrix commits. No CesiumJS or PROJ source is copied.
5
+ import type {NumericArray} from '@math.gl/types';
6
+
7
+ export type LocalFramePoint = {x: number; y: number; z: number};
8
+ export type LocalFrameAxis = 'east' | 'north' | 'up' | 'west' | 'south' | 'down';
9
+ /** East has zero Z. North is up × east; northZ is its horizontal radial factor. */
10
+ export type LocalFrameBasis = {
11
+ eastX: number;
12
+ eastY: number;
13
+ northZ: number;
14
+ upX: number;
15
+ upY: number;
16
+ upZ: number;
17
+ };
18
+
19
+ /** Setup-time scratch, initially the ENU basis at longitude/latitude zero. */
20
+ export function createLocalFrameBasis(): LocalFrameBasis {
21
+ return {eastX: 0, eastY: 1, northZ: 1, upX: 1, upY: 0, upZ: 0};
22
+ }
23
+
24
+ /** Angles in radians. Longitude is periodic; latitude must be within ±π/2. */
25
+ export function eastNorthUpBasis(
26
+ longitude: number,
27
+ latitude: number,
28
+ result: LocalFrameBasis
29
+ ): boolean {
30
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude) || Math.abs(latitude) > Math.PI / 2)
31
+ return false;
32
+ const sl = Math.sin(longitude),
33
+ cl = Math.cos(longitude);
34
+ const sp = Math.sin(latitude),
35
+ cp = Math.cos(latitude);
36
+ return commitBasis(result, -sl, cl, cp, cp * cl, cp * sl, sp);
37
+ }
38
+
39
+ /**
40
+ * Caller supplies finite unit east/up directions, east.z=0, mutually perpendicular,
41
+ * and an up direction whose horizontal component points radially outward.
42
+ * This form preserves supplied up components rather than inferring a geodetic footpoint.
43
+ * Finiteness is checked; orthonormality is a caller precondition, not certified here.
44
+ */
45
+ export function eastNorthUpBasisFromDirections(
46
+ east: LocalFramePoint,
47
+ up: LocalFramePoint,
48
+ result: LocalFrameBasis
49
+ ): boolean {
50
+ const ex = east.x,
51
+ ey = east.y,
52
+ ez = east.z;
53
+ const ux = up.x,
54
+ uy = up.y,
55
+ uz = up.z;
56
+ if (ez !== 0) return false;
57
+ return commitBasis(result, ex, ey, ux * ey - uy * ex, ux, uy, uz);
58
+ }
59
+
60
+ /** Rotate ENU offsets/velocities to fixed XYZ. Distances retain the input unit. */
61
+ export function localToFixed(
62
+ point: LocalFramePoint,
63
+ basis: LocalFrameBasis,
64
+ result: LocalFramePoint = point
65
+ ): boolean {
66
+ const sl = -basis.eastX,
67
+ cl = basis.eastY,
68
+ sp = basis.upZ,
69
+ cp = basis.northZ;
70
+ const east = point.x,
71
+ north = point.y,
72
+ up = point.z;
73
+ // Retain the factored rotation order used by deformation; no intermediate vector.
74
+ const radial = up * cp - north * sp;
75
+ return commitPoint(
76
+ result,
77
+ radial * cl - east * sl,
78
+ radial * sl + east * cl,
79
+ up * sp + north * cp
80
+ );
81
+ }
82
+
83
+ /** Transpose rotation, valid for the orthonormal ENU basis precondition. */
84
+ export function fixedToLocal(
85
+ point: LocalFramePoint,
86
+ basis: LocalFrameBasis,
87
+ result: LocalFramePoint = point
88
+ ): boolean {
89
+ const ex = basis.eastX,
90
+ ey = basis.eastY,
91
+ nz = basis.northZ;
92
+ const ux = basis.upX,
93
+ uy = basis.upY,
94
+ uz = basis.upZ;
95
+ const x = point.x,
96
+ y = point.y,
97
+ z = point.z;
98
+ return commitPoint(
99
+ result,
100
+ x * ex + y * ey,
101
+ -x * uz * ey + y * uz * ex + z * nz,
102
+ x * ux + y * uy + z * uz
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Column-major affine matrix, with explicit signed local axes and fixed-space origin.
108
+ * Axis triples must be right handed (e.g. east/north/up or north/east/down).
109
+ * Translation uses the origin's distance unit. The basis itself has no origin.
110
+ * A failure leaves output unchanged; caller owns writable storage (a growable number array or a typed array of length ≥16).
111
+ */
112
+ export function localFrameToMatrix(
113
+ basis: LocalFrameBasis,
114
+ origin: LocalFramePoint,
115
+ firstAxis: LocalFrameAxis,
116
+ secondAxis: LocalFrameAxis,
117
+ thirdAxis: LocalFrameAxis,
118
+ result: NumericArray
119
+ ): boolean {
120
+ const first = axisCode(firstAxis),
121
+ second = axisCode(secondAxis),
122
+ third = axisCode(thirdAxis);
123
+ const a = Math.abs(first),
124
+ b = Math.abs(second),
125
+ c = Math.abs(third);
126
+ if (!a || !b || !c || a === b || a === c || b === c) return false;
127
+ const parity = (a % 3) + 1 === b ? 1 : -1;
128
+ if (
129
+ parity * Math.sign(first * second * third) !== 1 ||
130
+ (!Array.isArray(result) && result.length < 16)
131
+ )
132
+ return false;
133
+ const ex = basis.eastX,
134
+ ey = basis.eastY,
135
+ nz = basis.northZ;
136
+ const ux = basis.upX,
137
+ uy = basis.upY,
138
+ uz = basis.upZ;
139
+ const nx = -uz * ey,
140
+ ny = uz * ex;
141
+ const x = origin.x,
142
+ y = origin.y,
143
+ z = origin.z;
144
+ const ax = (a === 1 ? ex : a === 2 ? nx : ux) * Math.sign(first);
145
+ const ay = (a === 1 ? ey : a === 2 ? ny : uy) * Math.sign(first);
146
+ const az = (a === 1 ? 0 : a === 2 ? nz : uz) * Math.sign(first);
147
+ const bx = (b === 1 ? ex : b === 2 ? nx : ux) * Math.sign(second);
148
+ const by = (b === 1 ? ey : b === 2 ? ny : uy) * Math.sign(second);
149
+ const bz = (b === 1 ? 0 : b === 2 ? nz : uz) * Math.sign(second);
150
+ const cx = (c === 1 ? ex : c === 2 ? nx : ux) * Math.sign(third);
151
+ const cy = (c === 1 ? ey : c === 2 ? ny : uy) * Math.sign(third);
152
+ const cz = (c === 1 ? 0 : c === 2 ? nz : uz) * Math.sign(third);
153
+ if (
154
+ !Number.isFinite(ax) ||
155
+ !Number.isFinite(ay) ||
156
+ !Number.isFinite(az) ||
157
+ !Number.isFinite(bx) ||
158
+ !Number.isFinite(by) ||
159
+ !Number.isFinite(bz) ||
160
+ !Number.isFinite(cx) ||
161
+ !Number.isFinite(cy) ||
162
+ !Number.isFinite(cz) ||
163
+ !Number.isFinite(x) ||
164
+ !Number.isFinite(y) ||
165
+ !Number.isFinite(z)
166
+ )
167
+ return false;
168
+ if (
169
+ result instanceof Float32Array &&
170
+ (!Number.isFinite(Math.fround(ax)) ||
171
+ !Number.isFinite(Math.fround(ay)) ||
172
+ !Number.isFinite(Math.fround(az)) ||
173
+ !Number.isFinite(Math.fround(bx)) ||
174
+ !Number.isFinite(Math.fround(by)) ||
175
+ !Number.isFinite(Math.fround(bz)) ||
176
+ !Number.isFinite(Math.fround(cx)) ||
177
+ !Number.isFinite(Math.fround(cy)) ||
178
+ !Number.isFinite(Math.fround(cz)) ||
179
+ !Number.isFinite(Math.fround(x)) ||
180
+ !Number.isFinite(Math.fround(y)) ||
181
+ !Number.isFinite(Math.fround(z)))
182
+ )
183
+ return false;
184
+ // Snapshot every component before application setters can recursively change scratch.
185
+ result[0] = ax;
186
+ result[1] = ay;
187
+ result[2] = az;
188
+ result[3] = 0;
189
+ result[4] = bx;
190
+ result[5] = by;
191
+ result[6] = bz;
192
+ result[7] = 0;
193
+ result[8] = cx;
194
+ result[9] = cy;
195
+ result[10] = cz;
196
+ result[11] = 0;
197
+ result[12] = x;
198
+ result[13] = y;
199
+ result[14] = z;
200
+ result[15] = 1;
201
+ return true;
202
+ }
203
+ function axisCode(axis: LocalFrameAxis): number {
204
+ switch (axis) {
205
+ case 'east':
206
+ return 1;
207
+ case 'west':
208
+ return -1;
209
+ case 'north':
210
+ return 2;
211
+ case 'south':
212
+ return -2;
213
+ case 'up':
214
+ return 3;
215
+ case 'down':
216
+ return -3;
217
+ default:
218
+ return 0;
219
+ }
220
+ }
221
+ function commitBasis(
222
+ result: LocalFrameBasis,
223
+ ex: number,
224
+ ey: number,
225
+ nz: number,
226
+ ux: number,
227
+ uy: number,
228
+ uz: number
229
+ ): boolean {
230
+ if (
231
+ !Number.isFinite(ex) ||
232
+ !Number.isFinite(ey) ||
233
+ !Number.isFinite(nz) ||
234
+ !Number.isFinite(ux) ||
235
+ !Number.isFinite(uy) ||
236
+ !Number.isFinite(uz)
237
+ )
238
+ return false;
239
+ result.eastX = ex;
240
+ result.eastY = ey;
241
+ result.northZ = nz;
242
+ result.upX = ux;
243
+ result.upY = uy;
244
+ result.upZ = uz;
245
+ return true;
246
+ }
247
+ function commitPoint(result: LocalFramePoint, x: number, y: number, z: number): boolean {
248
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) return false;
249
+ result.x = x;
250
+ result.y = y;
251
+ result.z = z;
252
+ return true;
253
+ }
package/src/spheroid.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // SPDX-FileCopyrightText: 2014 Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf (proj4js)
4
4
  // SPDX-FileCopyrightText: Copyright (c) vis.gl contributors
5
- // SPDX-FileComment: Forward geocentric equations and Hannover inverse moved/adapted from math.gl projection's proj4js 2.22.0 datumUtils.js port. See ../PROJ4-LICENSE.md. Safeguarded exterior inverse and numeric output commit are original math.gl code.
5
+ // SPDX-FileComment: Forward geocentric equations and Hannover inverse moved/adapted from math.gl projection's proj4js 2.22.0 datumUtils.js port. See ../PROJ4-LICENSE.md. Safeguarded nearest-footpoint inverse and numeric output commit are original math.gl code.
6
6
 
7
7
  /** Numeric leaf: angles in radians, distances in axis units; no CRS, global config or scratch. */
8
8
  import type {SpheroidParameters} from '@math.gl/types';
@@ -32,8 +32,9 @@ export function spheroidToCartesian(
32
32
 
33
33
  /**
34
34
  * Bounded inverse. Sphere is analytic; ordinary spheroids use the retained Hannover
35
- * iteration. Very flat/exterior failures use a safeguarded normal-footpoint solve.
36
- * false leaves output untouched. Interior ambiguity is not resolved by this API.
35
+ * iteration on exterior points. Interiors use a safeguarded nearest-footpoint solve.
36
+ * Equatorial interiors below the evolute cusp have two nearest normals: reject.
37
+ * false leaves output untouched, including the center and unresolved binary64 cases.
37
38
  * Only exact poles canonicalize longitude; adapters may retain other conventions.
38
39
  */
39
40
  export function cartesianToSpheroid(
@@ -50,6 +51,10 @@ export function cartesianToSpheroid(
50
51
  if (!(rr > 0) || !Number.isFinite(rr)) return false;
51
52
  if (es === 0) return commit(result, p === 0 ? 0 : Math.atan2(y, x), Math.atan2(z, p), rr - a);
52
53
  if (p === 0) return commit(result, 0, (Math.sign(z) * Math.PI) / 2, Math.abs(z) - b);
54
+ const horizontal = p / a,
55
+ vertical = z / b;
56
+ if (horizontal * horizontal + vertical * vertical < 1 - 16 * Number.EPSILON)
57
+ return interiorInverse(x, y, z, p, a, b, result);
53
58
  if (es >= 0.9) return exteriorInverse(x, y, z, p, a, b, result);
54
59
  const ct = z / rr,
55
60
  st = p / rr;
@@ -73,6 +78,128 @@ export function cartesianToSpheroid(
73
78
  return exteriorInverse(x, y, z, p, a, b, result);
74
79
  }
75
80
 
81
+ /** Original nearest-normal solve in t = (lambda + b²)/a², avoiding interior cancellation.
82
+ * The positive interval selects the globally nearest branch, rather than a stationary normal.
83
+ */
84
+ function interiorInverse(
85
+ x: number,
86
+ y: number,
87
+ z: number,
88
+ p: number,
89
+ a: number,
90
+ b: number,
91
+ result: SpheroidPoint
92
+ ): boolean {
93
+ const ratio = b / a,
94
+ ratio2 = ratio * ratio;
95
+ const horizontal = p / a,
96
+ vertical = z / a,
97
+ delta = 1 - ratio2;
98
+ if (!(ratio2 > 0) || ratio > 1) return false;
99
+ if (z === 0) {
100
+ if (horizontal < delta) return false;
101
+ return commit(result, Math.atan2(y, x), 0, p - a);
102
+ }
103
+ const aa = a * a,
104
+ bb = b * b;
105
+ const ratioError =
106
+ Number.isFinite(aa) && aa > 0
107
+ ? (bb -
108
+ ratio2 * aa +
109
+ productError(b, b, bb) -
110
+ ratio2 * productError(a, a, aa) -
111
+ productError(ratio2, aa, ratio2 * aa)) /
112
+ aa
113
+ : 0;
114
+ const pp = p * p,
115
+ xx = x * x,
116
+ yy = y * y,
117
+ sum = xx + yy;
118
+ const radiusError =
119
+ Number.isFinite(pp) && pp > 0
120
+ ? (sum -
121
+ pp +
122
+ sumError(xx, yy, sum) +
123
+ productError(x, x, xx) +
124
+ productError(y, y, yy) -
125
+ productError(p, p, pp)) /
126
+ (2 * p)
127
+ : 0;
128
+ const shift = a * ratio2,
129
+ base = p - a + shift;
130
+ const correction =
131
+ radiusError + sumError(p - a, shift, base) + productError(a, ratio2, shift) + a * ratioError;
132
+ const weighted = Math.abs(vertical) * ratio;
133
+ if (!(weighted > 0)) return false;
134
+ let lower = 0,
135
+ upper = ratio2;
136
+ // A lower bound near the short-axis singularity prevents thousands of bisections
137
+ // for deep, nearly equatorial interiors. No subtraction of lambda and -b².
138
+ let t = Math.max(weighted, horizontal - delta);
139
+ if (!(t > lower && t < upper)) t = upper / 2;
140
+ for (let i = 0; i < 128; i++) {
141
+ const equatorial = delta + t;
142
+ const u = horizontal / equatorial,
143
+ v = weighted / t;
144
+ const at = a * t,
145
+ difference = base - at;
146
+ const offset =
147
+ (difference + (sumError(base, -at, difference) + correction - productError(a, t, at))) /
148
+ (a * equatorial);
149
+ const term = offset * (u + 1);
150
+ const residual = term + v * v;
151
+ if (
152
+ Math.abs(residual) <= 4 * Number.EPSILON * (Math.abs(term) + v * v) ||
153
+ upper - lower <= 4 * Number.EPSILON * t
154
+ ) {
155
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
156
+ const sin = Math.sin(latitude),
157
+ cos = Math.cos(latitude);
158
+ return commit(
159
+ result,
160
+ Math.atan2(y, x),
161
+ latitude,
162
+ p * cos + z * sin - a * Math.hypot(cos, ratio * sin)
163
+ );
164
+ }
165
+ if (residual > 0) lower = t;
166
+ else upper = t;
167
+ const derivative = -2 * ((u * u) / equatorial + (v * v) / t);
168
+ const next = t - residual / derivative;
169
+ const candidate =
170
+ Number.isFinite(next) && next > lower && next < upper ? next : lower + (upper - lower) / 2;
171
+ if (candidate === t) {
172
+ const latitude = Math.atan2(vertical / t, horizontal / equatorial);
173
+ return commit(
174
+ result,
175
+ Math.atan2(y, x),
176
+ latitude,
177
+ p * Math.cos(latitude) +
178
+ z * Math.sin(latitude) -
179
+ a * Math.hypot(Math.cos(latitude), ratio * Math.sin(latitude))
180
+ );
181
+ }
182
+ t = candidate;
183
+ }
184
+ return false;
185
+ }
186
+
187
+ /** Error-free transforms on the finite squared-axis domain used by geometry adapters. */
188
+ function sumError(x: number, y: number, sum: number): number {
189
+ const part = sum - x;
190
+ return x - (sum - part) + (y - part);
191
+ }
192
+ function productError(x: number, y: number, product: number): number {
193
+ const sx = 134217729 * x,
194
+ sy = 134217729 * y;
195
+ if (!Number.isFinite(sx) || !Number.isFinite(sy)) return 0;
196
+ const hx = sx - (sx - x),
197
+ hy = sy - (sy - y),
198
+ lx = x - hx,
199
+ ly = y - hy;
200
+ return hx * hy - product + hx * ly + lx * hy + lx * ly;
201
+ }
202
+
76
203
  /** Original dimensionless Lagrange-multiplier solve, restricted to surface/exterior. */
77
204
  function exteriorInverse(
78
205
  x: number,