@anov/gis-skills-cli 0.0.0-stage → 0.3.0
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.
- package/CHANGELOG.md +618 -0
- package/INSTALL.md +478 -0
- package/LICENSE +15 -0
- package/README.md +148 -2
- package/RELEASING.md +160 -0
- package/bin/anov-gis-skills.mjs +408 -0
- package/lib/mcp-config.mjs +273 -0
- package/package.json +42 -4
- package/skills/anovgis-analysis/SKILL.md +585 -0
- package/skills/anovgis-effects/SKILL.md +260 -0
- package/skills/anovgis-imagery-terrain/SKILL.md +505 -0
- package/skills/anovgis-layers/SKILL.md +627 -0
- package/skills/anovgis-materials/SKILL.md +635 -0
- package/skills/anovgis-models-3dtiles/SKILL.md +448 -0
- package/skills/anovgis-pitfalls/SKILL.md +561 -0
- package/skills/anovgis-popup-widget/SKILL.md +474 -0
- package/skills/anovgis-primitives/SKILL.md +482 -0
- package/skills/anovgis-vector-graphics/SKILL.md +602 -0
- package/skills/anovgis-viewer/SKILL.md +618 -0
- package/skills/using-anovgis/DEMO-MAP.md +64 -0
- package/skills/using-anovgis/DEMO-SKILL-MAP.md +248 -0
- package/skills/using-anovgis/DOMAINS.md +183 -0
- package/skills/using-anovgis/REFERENCE.md +114 -0
- package/skills/using-anovgis/SKILL.md +392 -0
- package/skills/using-anovgis/templates/README.md +154 -0
- package/skills/using-anovgis/templates/combo1-vue3-vite.md +295 -0
- package/skills/using-anovgis/templates/combo2-vue2-cli.md +119 -0
- package/skills/using-anovgis/templates/combo3-html-cdn.md +107 -0
- package/skills/using-anovgis/templates/combo4-vanilla-webpack.md +91 -0
- package/skills/using-anovgis/templates/wizard-profiles.md +105 -0
- package/vendor/cesiumjs-skills/LICENSE +201 -0
- package/vendor/cesiumjs-skills/NOTICE +18 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-3d-tiles/SKILL.md +465 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-camera/SKILL.md +500 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-core-utilities/SKILL.md +403 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/REFERENCE.md +397 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/SKILL.md +351 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/01-diffuse-tint.js +38 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/02-texture-swap.js +42 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/03-feature-id-tileset.js +29 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/04-translucent-override.js +37 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/05-vertex-displacement.js +49 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/06-metadata-ramp.js +34 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/07-voxel-shader.js +27 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/README.md +19 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-custom-shader/examples/_sandcastle-template.html +9 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-entities/SKILL.md +389 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-imagery/SKILL.md +471 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-interaction/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-materials-shaders/SKILL.md +292 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-models-particles/SKILL.md +423 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-primitives/SKILL.md +537 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-spatial-math/SKILL.md +358 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-terrain-environment/SKILL.md +401 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-time-properties/SKILL.md +353 -0
- package/vendor/cesiumjs-skills/skills/cesiumjs-viewer-setup/SKILL.md +434 -0
- package/vendor/cesiumjs-skills/skills/using-cesiumjs-skills/SKILL.md +35 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cesiumjs-spatial-math
|
|
3
|
+
description: "CesiumJS spatial math - Cartesian3, Cartographic, Matrix4, Quaternion, Transforms, Ellipsoid, BoundingSphere, projections, coordinate conversions. Use when converting between coordinate systems, computing positions on the ellipsoid, performing spatial intersection tests, building model matrices, or working with geographic projections."
|
|
4
|
+
---
|
|
5
|
+
# CesiumJS Spatial Math & Transforms
|
|
6
|
+
|
|
7
|
+
Version baseline: CesiumJS v1.142 (2026-06-01)
|
|
8
|
+
|
|
9
|
+
Mathematical foundation for every CesiumJS application: coordinate types, unit conversions, ellipsoid geometry, reference frame transforms, bounding volumes, intersection tests, and projections.
|
|
10
|
+
|
|
11
|
+
## Core Concepts
|
|
12
|
+
|
|
13
|
+
CesiumJS uses a right-handed Earth-Centered Earth-Fixed (ECEF) coordinate system:
|
|
14
|
+
|
|
15
|
+
- **Cartesian3** -- ECEF (x, y, z) in meters. Internal representation for all 3D positions.
|
|
16
|
+
- **Cartographic** -- (longitude, latitude, height). Angles are **radians**, height in meters above ellipsoid.
|
|
17
|
+
|
|
18
|
+
All angular values in core math are radians. Use `Math.toRadians()` / `Math.toDegrees()`. Math types use a **static-method-with-result** pattern: pass a `result` parameter to reuse allocations.
|
|
19
|
+
|
|
20
|
+
## Cartesian3 -- Positions and Vectors
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
import { Cartesian3, Math as CesiumMath } from "cesium";
|
|
24
|
+
|
|
25
|
+
// From lon/lat degrees -- most common entry point
|
|
26
|
+
const pos = Cartesian3.fromDegrees(-105.0, 40.0);
|
|
27
|
+
const elevated = Cartesian3.fromDegrees(-105.0, 40.0, 1500.0); // with height
|
|
28
|
+
|
|
29
|
+
// Batch creation: [lon, lat, lon, lat, ...]
|
|
30
|
+
const ring = Cartesian3.fromDegreesArray([-105, 40, -100, 40, -100, 35]);
|
|
31
|
+
|
|
32
|
+
// With heights: [lon, lat, h, lon, lat, h, ...]
|
|
33
|
+
const wall = Cartesian3.fromDegreesArrayHeights([-105, 40, 500, -100, 40, 1000]);
|
|
34
|
+
|
|
35
|
+
// From raw ECEF or from radians
|
|
36
|
+
const raw = new Cartesian3(-1275096.0, -4797180.0, 4075270.0);
|
|
37
|
+
const fromRad = Cartesian3.fromRadians(-1.8326, 0.6981, 1500.0);
|
|
38
|
+
|
|
39
|
+
// Constants
|
|
40
|
+
Cartesian3.ZERO; // (0,0,0)
|
|
41
|
+
Cartesian3.UNIT_X; // (1,0,0)
|
|
42
|
+
Cartesian3.UNIT_Y; // (0,1,0)
|
|
43
|
+
Cartesian3.UNIT_Z; // (0,0,1)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> **Breaking change (1.139, #8359):** `Cartesian2`, `Cartesian3`, and `Cartesian4`
|
|
47
|
+
> are now ES6 classes. Calling `new` on a static **factory** method now throws --
|
|
48
|
+
> `new Cartesian3.fromArray([...])` and `new Cartesian3.fromDegrees(...)` are
|
|
49
|
+
> errors. Drop `new` for factory methods (`Cartesian3.fromArray([...])`); keep it
|
|
50
|
+
> only for the real constructor (`new Cartesian3(x, y, z)`). More classes are
|
|
51
|
+
> migrating to ES6 classes, so apply this rule everywhere.
|
|
52
|
+
|
|
53
|
+
### Vector Operations
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const a = new Cartesian3(1.0, 2.0, 3.0);
|
|
57
|
+
const b = new Cartesian3(4.0, 5.0, 6.0);
|
|
58
|
+
const r = new Cartesian3(); // reusable scratch
|
|
59
|
+
|
|
60
|
+
Cartesian3.add(a, b, r); // a + b
|
|
61
|
+
Cartesian3.subtract(a, b, r); // a - b
|
|
62
|
+
Cartesian3.multiplyByScalar(a, 2.0, r); // a * 2
|
|
63
|
+
Cartesian3.negate(a, r); // -a
|
|
64
|
+
Cartesian3.cross(a, b, r); // cross product
|
|
65
|
+
Cartesian3.normalize(a, r); // unit vector
|
|
66
|
+
Cartesian3.lerp(a, b, 0.5, r); // linear interpolation
|
|
67
|
+
Cartesian3.midpoint(a, b, r); // midpoint
|
|
68
|
+
|
|
69
|
+
const dot = Cartesian3.dot(a, b); // dot product
|
|
70
|
+
const len = Cartesian3.magnitude(a); // ||a||
|
|
71
|
+
const dist = Cartesian3.distance(a, b); // Euclidean distance
|
|
72
|
+
const distSq = Cartesian3.distanceSquared(a, b); // faster for comparisons
|
|
73
|
+
const angle = Cartesian3.angleBetween(a, b); // radians
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Cartographic -- Geographic Coordinates
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
import { Cartographic, Cartesian3, Math as CesiumMath } from "cesium";
|
|
80
|
+
|
|
81
|
+
const carto = Cartographic.fromDegrees(-105.0, 40.0, 1500.0);
|
|
82
|
+
const cartoRad = Cartographic.fromRadians(-1.8326, 0.6981, 1500.0);
|
|
83
|
+
|
|
84
|
+
// Cartesian3 <-> Cartographic
|
|
85
|
+
const position = Cartesian3.fromDegrees(-105.0, 40.0, 1500.0);
|
|
86
|
+
const geo = Cartographic.fromCartesian(position);
|
|
87
|
+
const lonDeg = CesiumMath.toDegrees(geo.longitude); // -105.0
|
|
88
|
+
const latDeg = CesiumMath.toDegrees(geo.latitude); // 40.0
|
|
89
|
+
const backToCart = Cartographic.toCartesian(geo);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## CesiumMath Utilities
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
import { Math as CesiumMath } from "cesium";
|
|
96
|
+
|
|
97
|
+
// Degree/radian conversion
|
|
98
|
+
const rad = CesiumMath.toRadians(90.0); // PI/2
|
|
99
|
+
const deg = CesiumMath.toDegrees(Math.PI); // 180
|
|
100
|
+
|
|
101
|
+
// Constants: PI, TWO_PI, PI_OVER_TWO, PI_OVER_FOUR, RADIANS_PER_DEGREE
|
|
102
|
+
// EPSILON1 (0.1) through EPSILON21 (1e-21)
|
|
103
|
+
|
|
104
|
+
const clamped = CesiumMath.clamp(value, 0.0, 1.0);
|
|
105
|
+
const interp = CesiumMath.lerp(0.0, 100.0, 0.5); // 50
|
|
106
|
+
const norm = CesiumMath.negativePiToPi(angle); // [-PI, PI]
|
|
107
|
+
const pos = CesiumMath.zeroToTwoPi(angle); // [0, 2*PI]
|
|
108
|
+
const safeLon = CesiumMath.convertLongitudeRange(angle); // [-PI, PI)
|
|
109
|
+
const eq = CesiumMath.equalsEpsilon(a, b, CesiumMath.EPSILON7); // float compare
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Ellipsoid
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
import { Ellipsoid, Cartesian3, Cartographic } from "cesium";
|
|
116
|
+
|
|
117
|
+
// Built-in ellipsoids
|
|
118
|
+
Ellipsoid.WGS84; // Earth (default)
|
|
119
|
+
Ellipsoid.UNIT_SPHERE; // radius 1
|
|
120
|
+
Ellipsoid.MOON; // lunar sphere
|
|
121
|
+
Ellipsoid.MARS; // Mars (v1.133+)
|
|
122
|
+
|
|
123
|
+
// Change default (affects Ellipsoid.default everywhere)
|
|
124
|
+
Ellipsoid.default = Ellipsoid.MOON;
|
|
125
|
+
|
|
126
|
+
// Conversions on a specific ellipsoid
|
|
127
|
+
const cart = Ellipsoid.WGS84.cartographicToCartesian(
|
|
128
|
+
Cartographic.fromDegrees(-75.0, 40.0, 100.0),
|
|
129
|
+
);
|
|
130
|
+
const carto = Ellipsoid.WGS84.cartesianToCartographic(cart);
|
|
131
|
+
|
|
132
|
+
// Surface normal at a position
|
|
133
|
+
const normal = Ellipsoid.WGS84.geodeticSurfaceNormal(cart, new Cartesian3());
|
|
134
|
+
|
|
135
|
+
// Project point onto ellipsoid surface
|
|
136
|
+
const onSurface = Ellipsoid.WGS84.scaleToGeodeticSurface(cart, new Cartesian3());
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Transforms -- Reference Frames
|
|
140
|
+
|
|
141
|
+
`Transforms` builds 4x4 matrices relating local frames to ECEF. The most commonly used function is `eastNorthUpToFixedFrame`.
|
|
142
|
+
|
|
143
|
+
### East-North-Up (ENU)
|
|
144
|
+
|
|
145
|
+
ENU: X = east, Y = north, Z = up. Standard frame for placing models on the globe.
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
import { Cartesian3, Transforms, Matrix4 } from "cesium";
|
|
149
|
+
|
|
150
|
+
const origin = Cartesian3.fromDegrees(-105.0, 40.0);
|
|
151
|
+
const enuMatrix = Transforms.eastNorthUpToFixedFrame(origin);
|
|
152
|
+
// Columns: [east, north, up, origin] in ECEF
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Heading-Pitch-Roll Model Matrix
|
|
156
|
+
|
|
157
|
+
Standard way to position and orient a 3D model.
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
import { Cartesian3, Transforms, HeadingPitchRoll, Math as CesiumMath } from "cesium";
|
|
161
|
+
|
|
162
|
+
const position = Cartesian3.fromDegrees(-105.0, 40.0, 0.0);
|
|
163
|
+
const hpr = new HeadingPitchRoll(
|
|
164
|
+
CesiumMath.toRadians(90.0), // heading: 90 deg east
|
|
165
|
+
0.0, // pitch: level
|
|
166
|
+
0.0, // roll: none
|
|
167
|
+
);
|
|
168
|
+
const modelMatrix = Transforms.headingPitchRollToFixedFrame(position, hpr);
|
|
169
|
+
|
|
170
|
+
// Just the orientation quaternion (e.g., for Entity.orientation)
|
|
171
|
+
const orientation = Transforms.headingPitchRollQuaternion(position, hpr);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### HeadingPitchRoll
|
|
175
|
+
|
|
176
|
+
Heading = rotation about -Z (compass bearing, clockwise). Pitch = about -Y. Roll = about +X. Radians.
|
|
177
|
+
|
|
178
|
+
```js
|
|
179
|
+
import { HeadingPitchRoll, Math as CesiumMath } from "cesium";
|
|
180
|
+
const hpr = new HeadingPitchRoll(CesiumMath.toRadians(45.0), CesiumMath.toRadians(-10.0), 0.0);
|
|
181
|
+
const hprDeg = HeadingPitchRoll.fromDegrees(45.0, -10.0, 0.0); // convenience
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Other Local Frames
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
import { Transforms, Cartesian3 } from "cesium";
|
|
188
|
+
const origin = Cartesian3.fromDegrees(-105.0, 40.0);
|
|
189
|
+
|
|
190
|
+
Transforms.northEastDownToFixedFrame(origin); // NED (aviation)
|
|
191
|
+
Transforms.northUpEastToFixedFrame(origin); // NUE
|
|
192
|
+
|
|
193
|
+
// Custom frame from any combo of east|north|up|west|south|down
|
|
194
|
+
const customFn = Transforms.localFrameToFixedFrameGenerator("north", "west");
|
|
195
|
+
const matrix = customFn(origin);
|
|
196
|
+
|
|
197
|
+
// Recover heading/pitch/roll from an existing model matrix
|
|
198
|
+
const hpr = Transforms.fixedFrameToHeadingPitchRoll(modelMatrix);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Matrix4 -- 4x4 Transforms
|
|
202
|
+
|
|
203
|
+
Column-major storage (WebGL convention). Constructor takes row-major for readability.
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
import { Matrix4, Matrix3, Cartesian3, Quaternion } from "cesium";
|
|
207
|
+
|
|
208
|
+
// Factory methods
|
|
209
|
+
Matrix4.fromTranslation(new Cartesian3(10, 20, 30));
|
|
210
|
+
Matrix4.fromRotationTranslation(Matrix3.fromRotationZ(Math.PI / 4), new Cartesian3(100, 0, 0));
|
|
211
|
+
Matrix4.fromTranslationQuaternionRotationScale(
|
|
212
|
+
new Cartesian3(0, 0, 0), Quaternion.IDENTITY, new Cartesian3(2, 2, 2),
|
|
213
|
+
);
|
|
214
|
+
Matrix4.fromUniformScale(5.0);
|
|
215
|
+
|
|
216
|
+
// Combine, transform, invert
|
|
217
|
+
const combined = Matrix4.multiply(matA, matB, new Matrix4());
|
|
218
|
+
const worldPt = Matrix4.multiplyByPoint(enuMatrix, new Cartesian3(100, 0, 0), new Cartesian3());
|
|
219
|
+
const inv = Matrix4.inverseTransformation(enuMatrix, new Matrix4()); // rigid-body only
|
|
220
|
+
|
|
221
|
+
// Decompose
|
|
222
|
+
Matrix4.getTranslation(enuMatrix, new Cartesian3());
|
|
223
|
+
Matrix4.getMatrix3(enuMatrix, new Matrix3());
|
|
224
|
+
Matrix4.getScale(enuMatrix, new Cartesian3());
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Quaternion -- Rotation
|
|
228
|
+
|
|
229
|
+
```js
|
|
230
|
+
import { Quaternion, Cartesian3, HeadingPitchRoll, Math as CesiumMath, Matrix3 } from "cesium";
|
|
231
|
+
|
|
232
|
+
Quaternion.IDENTITY; // (0, 0, 0, 1)
|
|
233
|
+
const q1 = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, CesiumMath.toRadians(45.0));
|
|
234
|
+
const q2 = Quaternion.fromHeadingPitchRoll(new HeadingPitchRoll(CesiumMath.toRadians(90), 0, 0));
|
|
235
|
+
const q3 = Quaternion.fromRotationMatrix(Matrix3.fromRotationZ(Math.PI / 2));
|
|
236
|
+
const mid = Quaternion.slerp(q1, q2, 0.5, new Quaternion()); // interpolate
|
|
237
|
+
const composed = Quaternion.multiply(q1, q2, new Quaternion()); // compose
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Geodesic Distance
|
|
241
|
+
|
|
242
|
+
```js
|
|
243
|
+
import { Cartographic, EllipsoidGeodesic, Cartesian3 } from "cesium";
|
|
244
|
+
|
|
245
|
+
// Surface distance (great-circle via Vincenty)
|
|
246
|
+
const geodesic = new EllipsoidGeodesic(
|
|
247
|
+
Cartographic.fromDegrees(-73.985, 40.758), // New York
|
|
248
|
+
Cartographic.fromDegrees(-0.1276, 51.5074), // London
|
|
249
|
+
);
|
|
250
|
+
const surfaceDist = geodesic.surfaceDistance; // ~5,570 km
|
|
251
|
+
const midCarto = geodesic.interpolateUsingFraction(0.5); // midpoint on surface
|
|
252
|
+
|
|
253
|
+
// Chord (straight-line) distance
|
|
254
|
+
const chord = Cartesian3.distance(Cartesian3.fromDegrees(-105, 40), Cartesian3.fromDegrees(-104, 40));
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## BoundingSphere
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
import { BoundingSphere, Cartesian3 } from "cesium";
|
|
261
|
+
|
|
262
|
+
const sphere = BoundingSphere.fromPoints(
|
|
263
|
+
Cartesian3.fromDegreesArray([-105, 40, -100, 40, -100, 35]),
|
|
264
|
+
); // sphere.center (Cartesian3), sphere.radius (number)
|
|
265
|
+
|
|
266
|
+
const inside = Cartesian3.distance(sphere.center, Cartesian3.fromDegrees(-102, 37.5)) <= sphere.radius;
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Ray and Intersection Tests
|
|
270
|
+
|
|
271
|
+
```js
|
|
272
|
+
import { Ray, IntersectionTests, Plane, Cartesian3, Ellipsoid } from "cesium";
|
|
273
|
+
|
|
274
|
+
const ray = new Ray(new Cartesian3(0, 0, 6378137), new Cartesian3(0, 0, -1)); // auto-normalized
|
|
275
|
+
const ptOnRay = Ray.getPoint(ray, 1000.0, new Cartesian3());
|
|
276
|
+
|
|
277
|
+
// Ray-plane: returns Cartesian3 or undefined
|
|
278
|
+
const plane = Plane.fromPointNormal(Cartesian3.ZERO, Cartesian3.UNIT_Z);
|
|
279
|
+
const hit = IntersectionTests.rayPlane(ray, plane);
|
|
280
|
+
|
|
281
|
+
// Ray-ellipsoid: returns Interval {start, stop} or undefined
|
|
282
|
+
const camRay = new Ray(new Cartesian3(0, 0, 20000000), new Cartesian3(0, 0, -1));
|
|
283
|
+
const interval = IntersectionTests.rayEllipsoid(camRay, Ellipsoid.WGS84);
|
|
284
|
+
if (interval) {
|
|
285
|
+
const nearPt = Ray.getPoint(camRay, interval.start, new Cartesian3());
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Ray-triangle: returns parametric t or undefined
|
|
289
|
+
const t = IntersectionTests.rayTriangleParametric(ray, p0, p1, p2, true);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## SceneTransforms -- World to Screen
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
import { SceneTransforms, Cartesian3 } from "cesium";
|
|
296
|
+
// World -> pixel coordinates (Cartesian2 or undefined if off-screen)
|
|
297
|
+
const winPos = SceneTransforms.worldToWindowCoordinates(viewer.scene, Cartesian3.fromDegrees(-105, 40));
|
|
298
|
+
// High-DPI aware variant
|
|
299
|
+
const bufPos = SceneTransforms.worldToDrawingBufferCoordinates(viewer.scene, worldPos);
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## Geographic Projections
|
|
303
|
+
|
|
304
|
+
```js
|
|
305
|
+
import { GeographicProjection, WebMercatorProjection, Cartographic, Ellipsoid } from "cesium";
|
|
306
|
+
const carto = Cartographic.fromDegrees(-105.0, 40.0);
|
|
307
|
+
|
|
308
|
+
// Plate Carree: project/unproject between Cartographic and Cartesian3
|
|
309
|
+
const geoProj = new GeographicProjection(Ellipsoid.WGS84);
|
|
310
|
+
const xy = geoProj.project(carto); // Cartesian3
|
|
311
|
+
const back = geoProj.unproject(xy); // Cartographic
|
|
312
|
+
|
|
313
|
+
// Web Mercator (EPSG:3857)
|
|
314
|
+
const merc = new WebMercatorProjection(Ellipsoid.WGS84);
|
|
315
|
+
const mercXY = merc.project(carto);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## Common Patterns
|
|
319
|
+
|
|
320
|
+
### Offset a Position in Local ENU
|
|
321
|
+
|
|
322
|
+
```js
|
|
323
|
+
import { Cartesian3, Transforms, Matrix4 } from "cesium";
|
|
324
|
+
|
|
325
|
+
const origin = Cartesian3.fromDegrees(-105.0, 40.0, 0.0);
|
|
326
|
+
const enu = Transforms.eastNorthUpToFixedFrame(origin);
|
|
327
|
+
// Move 500m east, 200m north, 100m up in local frame
|
|
328
|
+
const worldPt = Matrix4.multiplyByPoint(enu, new Cartesian3(500, 200, 100), new Cartesian3());
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Compare Positions with Tolerance
|
|
332
|
+
|
|
333
|
+
```js
|
|
334
|
+
import { Cartesian3, Math as CesiumMath } from "cesium";
|
|
335
|
+
const a = Cartesian3.fromDegrees(-105.0, 40.0);
|
|
336
|
+
const b = Cartesian3.fromDegrees(-105.0001, 40.0001);
|
|
337
|
+
Cartesian3.equalsEpsilon(a, b, CesiumMath.EPSILON7); // preferred over ===
|
|
338
|
+
if (Cartesian3.distance(a, b) < 10.0) { /* within 10m */ }
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Performance Tips
|
|
342
|
+
|
|
343
|
+
1. **Reuse scratch variables.** Pre-allocate `result` objects outside loops to avoid GC pauses.
|
|
344
|
+
2. **Use `distanceSquared`** instead of `distance` when comparing -- avoids `Math.sqrt`.
|
|
345
|
+
3. **Prefer `Cartesian3.fromDegrees`** over manual Cartographic creation then conversion.
|
|
346
|
+
4. **Cache model matrices.** Call `Transforms.eastNorthUpToFixedFrame` once if position is static.
|
|
347
|
+
5. **Use `Matrix4.inverseTransformation`** for rigid-body transforms -- faster and more stable than `inverse`.
|
|
348
|
+
6. **Batch position creation** with `fromDegreesArray` / `fromDegreesArrayHeights` instead of looping `fromDegrees`.
|
|
349
|
+
7. **Guard `Cartesian3.normalize`** -- it throws on zero-length vectors. Check magnitude first.
|
|
350
|
+
8. **Use `equalsEpsilon`** for float comparisons. `CesiumMath.EPSILON7` is a good default tolerance.
|
|
351
|
+
9. **Pre-compute HPR** outside render loops. Convert to quaternion/matrix only when orientation changes.
|
|
352
|
+
10. **Choose the right distance.** `Cartesian3.distance` = chord through Earth. `EllipsoidGeodesic.surfaceDistance` = great-circle.
|
|
353
|
+
|
|
354
|
+
## See Also
|
|
355
|
+
|
|
356
|
+
- **cesiumjs-camera** -- Camera positioning and flight animations that consume these coordinate types
|
|
357
|
+
- **cesiumjs-primitives** -- Geometry and Primitive API that uses model matrices from Transforms
|
|
358
|
+
- **cesiumjs-terrain-environment** -- Terrain height queries and globe surface interactions
|