Skip to content

Commit dfc2ccd

Browse files
committed
Update test fixture
Signed-off-by: Keshav Priyadarshi <[email protected]>
1 parent 83d7476 commit dfc2ccd

File tree

5 files changed

+672
-3410
lines changed

5 files changed

+672
-3410
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
import Cartesian3 from "./Cartesian3.js";
2+
import CesiumMath from "./Math.js";
3+
import Matrix3 from "./Matrix3.js";
4+
import Quaternion from "./Quaternion.js";
5+
6+
const EllipseGeometryLibrary = {};
7+
8+
const rotAxis = new Cartesian3();
9+
const tempVec = new Cartesian3();
10+
const unitQuat = new Quaternion();
11+
const rotMtx = new Matrix3();
12+
13+
function pointOnEllipsoid(
14+
theta,
15+
rotation,
16+
northVec,
17+
eastVec,
18+
aSqr,
19+
ab,
20+
bSqr,
21+
mag,
22+
unitPos,
23+
result,
24+
) {
25+
const azimuth = theta + rotation;
26+
27+
Cartesian3.multiplyByScalar(eastVec, Math.cos(azimuth), rotAxis);
28+
Cartesian3.multiplyByScalar(northVec, Math.sin(azimuth), tempVec);
29+
Cartesian3.add(rotAxis, tempVec, rotAxis);
30+
31+
let cosThetaSquared = Math.cos(theta);
32+
cosThetaSquared = cosThetaSquared * cosThetaSquared;
33+
34+
let sinThetaSquared = Math.sin(theta);
35+
sinThetaSquared = sinThetaSquared * sinThetaSquared;
36+
37+
const radius =
38+
ab / Math.sqrt(bSqr * cosThetaSquared + aSqr * sinThetaSquared);
39+
const angle = radius / mag;
40+
41+
// Create the quaternion to rotate the position vector to the boundary of the ellipse.
42+
Quaternion.fromAxisAngle(rotAxis, angle, unitQuat);
43+
Matrix3.fromQuaternion(unitQuat, rotMtx);
44+
45+
Matrix3.multiplyByVector(rotMtx, unitPos, result);
46+
Cartesian3.normalize(result, result);
47+
Cartesian3.multiplyByScalar(result, mag, result);
48+
return result;
49+
}
50+
51+
const scratchCartesian1 = new Cartesian3();
52+
const scratchCartesian2 = new Cartesian3();
53+
const scratchCartesian3 = new Cartesian3();
54+
const scratchNormal = new Cartesian3();
55+
/**
56+
* Returns the positions raised to the given heights
57+
* @private
58+
*/
59+
EllipseGeometryLibrary.raisePositionsToHeight = function (
60+
positions,
61+
options,
62+
extrude,
63+
) {
64+
const ellipsoid = options.ellipsoid;
65+
const height = options.height;
66+
const extrudedHeight = options.extrudedHeight;
67+
const size = extrude ? (positions.length / 3) * 2 : positions.length / 3;
68+
69+
const finalPositions = new Float64Array(size * 3);
70+
71+
const length = positions.length;
72+
const bottomOffset = extrude ? length : 0;
73+
for (let i = 0; i < length; i += 3) {
74+
const i1 = i + 1;
75+
const i2 = i + 2;
76+
77+
const position = Cartesian3.fromArray(positions, i, scratchCartesian1);
78+
ellipsoid.scaleToGeodeticSurface(position, position);
79+
80+
const extrudedPosition = Cartesian3.clone(position, scratchCartesian2);
81+
const normal = ellipsoid.geodeticSurfaceNormal(position, scratchNormal);
82+
const scaledNormal = Cartesian3.multiplyByScalar(
83+
normal,
84+
height,
85+
scratchCartesian3,
86+
);
87+
Cartesian3.add(position, scaledNormal, position);
88+
89+
if (extrude) {
90+
Cartesian3.multiplyByScalar(normal, extrudedHeight, scaledNormal);
91+
Cartesian3.add(extrudedPosition, scaledNormal, extrudedPosition);
92+
93+
finalPositions[i + bottomOffset] = extrudedPosition.x;
94+
finalPositions[i1 + bottomOffset] = extrudedPosition.y;
95+
finalPositions[i2 + bottomOffset] = extrudedPosition.z;
96+
}
97+
98+
finalPositions[i] = position.x;
99+
finalPositions[i1] = position.y;
100+
finalPositions[i2] = position.z;
101+
}
102+
103+
return finalPositions;
104+
};
105+
106+
const unitPosScratch = new Cartesian3();
107+
const eastVecScratch = new Cartesian3();
108+
const northVecScratch = new Cartesian3();
109+
/**
110+
* Returns an array of positions that make up the ellipse.
111+
* @private
112+
*/
113+
EllipseGeometryLibrary.computeEllipsePositions = function (
114+
options,
115+
addFillPositions,
116+
addEdgePositions,
117+
) {
118+
const semiMinorAxis = options.semiMinorAxis;
119+
const semiMajorAxis = options.semiMajorAxis;
120+
const rotation = options.rotation;
121+
const center = options.center;
122+
123+
// Computing the arc-length of the ellipse is too expensive to be practical. Estimating it using the
124+
// arc length of the sphere is too inaccurate and creates sharp edges when either the semi-major or
125+
// semi-minor axis is much bigger than the other. Instead, scale the angle delta to make
126+
// the distance along the ellipse boundary more closely match the granularity.
127+
const granularity = options.granularity * 8.0;
128+
129+
const aSqr = semiMinorAxis * semiMinorAxis;
130+
const bSqr = semiMajorAxis * semiMajorAxis;
131+
const ab = semiMajorAxis * semiMinorAxis;
132+
133+
const mag = Cartesian3.magnitude(center);
134+
135+
const unitPos = Cartesian3.normalize(center, unitPosScratch);
136+
let eastVec = Cartesian3.cross(Cartesian3.UNIT_Z, center, eastVecScratch);
137+
eastVec = Cartesian3.normalize(eastVec, eastVec);
138+
const northVec = Cartesian3.cross(unitPos, eastVec, northVecScratch);
139+
140+
// The number of points in the first quadrant
141+
let numPts = 1 + Math.ceil(CesiumMath.PI_OVER_TWO / granularity);
142+
143+
const deltaTheta = CesiumMath.PI_OVER_TWO / (numPts - 1);
144+
let theta = CesiumMath.PI_OVER_TWO - numPts * deltaTheta;
145+
if (theta < 0.0) {
146+
numPts -= Math.ceil(Math.abs(theta) / deltaTheta);
147+
}
148+
149+
// If the number of points were three, the ellipse
150+
// would be tessellated like below:
151+
//
152+
// *---*
153+
// / | \ | \
154+
// *---*---*---*
155+
// / | \ | \ | \ | \
156+
// / .*---*---*---*. \
157+
// * ` | \ | \ | \ | `*
158+
// \`.*---*---*---*.`/
159+
// \ | \ | \ | \ | /
160+
// *---*---*---*
161+
// \ | \ | /
162+
// *---*
163+
// The first and last column have one position and fan to connect to the adjacent column.
164+
// Each other vertical column contains an even number of positions.
165+
const size = 2 * (numPts * (numPts + 2));
166+
const positions = addFillPositions ? new Array(size * 3) : undefined;
167+
let positionIndex = 0;
168+
let position = scratchCartesian1;
169+
let reflectedPosition = scratchCartesian2;
170+
171+
const outerPositionsLength = numPts * 4 * 3;
172+
let outerRightIndex = outerPositionsLength - 1;
173+
let outerLeftIndex = 0;
174+
const outerPositions = addEdgePositions
175+
? new Array(outerPositionsLength)
176+
: undefined;
177+
178+
let i;
179+
let j;
180+
let numInterior;
181+
let t;
182+
let interiorPosition;
183+
184+
// Compute points in the 'eastern' half of the ellipse
185+
theta = CesiumMath.PI_OVER_TWO;
186+
position = pointOnEllipsoid(
187+
theta,
188+
rotation,
189+
northVec,
190+
eastVec,
191+
aSqr,
192+
ab,
193+
bSqr,
194+
mag,
195+
unitPos,
196+
position,
197+
);
198+
if (addFillPositions) {
199+
positions[positionIndex++] = position.x;
200+
positions[positionIndex++] = position.y;
201+
positions[positionIndex++] = position.z;
202+
}
203+
if (addEdgePositions) {
204+
outerPositions[outerRightIndex--] = position.z;
205+
outerPositions[outerRightIndex--] = position.y;
206+
outerPositions[outerRightIndex--] = position.x;
207+
}
208+
theta = CesiumMath.PI_OVER_TWO - deltaTheta;
209+
for (i = 1; i < numPts + 1; ++i) {
210+
position = pointOnEllipsoid(
211+
theta,
212+
rotation,
213+
northVec,
214+
eastVec,
215+
aSqr,
216+
ab,
217+
bSqr,
218+
mag,
219+
unitPos,
220+
position,
221+
);
222+
reflectedPosition = pointOnEllipsoid(
223+
Math.PI - theta,
224+
rotation,
225+
northVec,
226+
eastVec,
227+
aSqr,
228+
ab,
229+
bSqr,
230+
mag,
231+
unitPos,
232+
reflectedPosition,
233+
);
234+
235+
if (addFillPositions) {
236+
positions[positionIndex++] = position.x;
237+
positions[positionIndex++] = position.y;
238+
positions[positionIndex++] = position.z;
239+
240+
numInterior = 2 * i + 2;
241+
for (j = 1; j < numInterior - 1; ++j) {
242+
t = j / (numInterior - 1);
243+
interiorPosition = Cartesian3.lerp(
244+
position,
245+
reflectedPosition,
246+
t,
247+
scratchCartesian3,
248+
);
249+
positions[positionIndex++] = interiorPosition.x;
250+
positions[positionIndex++] = interiorPosition.y;
251+
positions[positionIndex++] = interiorPosition.z;
252+
}
253+
254+
positions[positionIndex++] = reflectedPosition.x;
255+
positions[positionIndex++] = reflectedPosition.y;
256+
positions[positionIndex++] = reflectedPosition.z;
257+
}
258+
259+
if (addEdgePositions) {
260+
outerPositions[outerRightIndex--] = position.z;
261+
outerPositions[outerRightIndex--] = position.y;
262+
outerPositions[outerRightIndex--] = position.x;
263+
outerPositions[outerLeftIndex++] = reflectedPosition.x;
264+
outerPositions[outerLeftIndex++] = reflectedPosition.y;
265+
outerPositions[outerLeftIndex++] = reflectedPosition.z;
266+
}
267+
268+
theta = CesiumMath.PI_OVER_TWO - (i + 1) * deltaTheta;
269+
}
270+
271+
// Compute points in the 'western' half of the ellipse
272+
for (i = numPts; i > 1; --i) {
273+
theta = CesiumMath.PI_OVER_TWO - (i - 1) * deltaTheta;
274+
275+
position = pointOnEllipsoid(
276+
-theta,
277+
rotation,
278+
northVec,
279+
eastVec,
280+
aSqr,
281+
ab,
282+
bSqr,
283+
mag,
284+
unitPos,
285+
position,
286+
);
287+
reflectedPosition = pointOnEllipsoid(
288+
theta + Math.PI,
289+
rotation,
290+
northVec,
291+
eastVec,
292+
aSqr,
293+
ab,
294+
bSqr,
295+
mag,
296+
unitPos,
297+
reflectedPosition,
298+
);
299+
300+
if (addFillPositions) {
301+
positions[positionIndex++] = position.x;
302+
positions[positionIndex++] = position.y;
303+
positions[positionIndex++] = position.z;
304+
305+
numInterior = 2 * (i - 1) + 2;
306+
for (j = 1; j < numInterior - 1; ++j) {
307+
t = j / (numInterior - 1);
308+
interiorPosition = Cartesian3.lerp(
309+
position,
310+
reflectedPosition,
311+
t,
312+
scratchCartesian3,
313+
);
314+
positions[positionIndex++] = interiorPosition.x;
315+
positions[positionIndex++] = interiorPosition.y;
316+
positions[positionIndex++] = interiorPosition.z;
317+
}
318+
319+
positions[positionIndex++] = reflectedPosition.x;
320+
positions[positionIndex++] = reflectedPosition.y;
321+
positions[positionIndex++] = reflectedPosition.z;
322+
}
323+
324+
if (addEdgePositions) {
325+
outerPositions[outerRightIndex--] = position.z;
326+
outerPositions[outerRightIndex--] = position.y;
327+
outerPositions[outerRightIndex--] = position.x;
328+
outerPositions[outerLeftIndex++] = reflectedPosition.x;
329+
outerPositions[outerLeftIndex++] = reflectedPosition.y;
330+
outerPositions[outerLeftIndex++] = reflectedPosition.z;
331+
}
332+
}
333+
334+
theta = CesiumMath.PI_OVER_TWO;
335+
position = pointOnEllipsoid(
336+
-theta,
337+
rotation,
338+
northVec,
339+
eastVec,
340+
aSqr,
341+
ab,
342+
bSqr,
343+
mag,
344+
unitPos,
345+
position,
346+
);
347+
348+
const r = {};
349+
if (addFillPositions) {
350+
positions[positionIndex++] = position.x;
351+
positions[positionIndex++] = position.y;
352+
positions[positionIndex++] = position.z;
353+
r.positions = positions;
354+
r.numPts = numPts;
355+
}
356+
if (addEdgePositions) {
357+
outerPositions[outerRightIndex--] = position.z;
358+
outerPositions[outerRightIndex--] = position.y;
359+
outerPositions[outerRightIndex--] = position.x;
360+
r.outerPositions = outerPositions;
361+
}
362+
363+
return r;
364+
};
365+
export default EllipseGeometryLibrary;

Diff for: scanpipe/tests/data/d2d-javascript/symbols/cesium/from_basis_transcoder.js

-21
This file was deleted.

0 commit comments

Comments
 (0)