@itwin/core-geometry 4.0.0-dev.63 → 4.0.0-dev.68
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/lib/cjs/Geometry.d.ts +367 -243
- package/lib/cjs/Geometry.d.ts.map +1 -1
- package/lib/cjs/Geometry.js +481 -311
- package/lib/cjs/Geometry.js.map +1 -1
- package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts +6 -4
- package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
- package/lib/cjs/clipping/ConvexClipPlaneSet.js +9 -7
- package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts +5 -3
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js +4 -2
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.d.ts +4 -4
- package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js +17 -9
- package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
- package/lib/cjs/geometry3d/Point2dVector2d.js +2 -2
- package/lib/cjs/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.d.ts +13 -7
- package/lib/cjs/geometry3d/Point3dVector3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Point3dVector3d.js +19 -18
- package/lib/cjs/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/cjs/geometry4d/Point4d.d.ts +1 -1
- package/lib/cjs/geometry4d/Point4d.d.ts.map +1 -1
- package/lib/cjs/geometry4d/Point4d.js +12 -13
- package/lib/cjs/geometry4d/Point4d.js.map +1 -1
- package/lib/esm/Geometry.d.ts +367 -243
- package/lib/esm/Geometry.d.ts.map +1 -1
- package/lib/esm/Geometry.js +481 -311
- package/lib/esm/Geometry.js.map +1 -1
- package/lib/esm/clipping/ConvexClipPlaneSet.d.ts +6 -4
- package/lib/esm/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
- package/lib/esm/clipping/ConvexClipPlaneSet.js +9 -7
- package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts +5 -3
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js +4 -2
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.d.ts +4 -4
- package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.d.ts.map +1 -1
- package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js +17 -9
- package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
- package/lib/esm/geometry3d/Point2dVector2d.js +2 -2
- package/lib/esm/geometry3d/Point2dVector2d.js.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.d.ts +13 -7
- package/lib/esm/geometry3d/Point3dVector3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Point3dVector3d.js +19 -18
- package/lib/esm/geometry3d/Point3dVector3d.js.map +1 -1
- package/lib/esm/geometry4d/Point4d.d.ts +1 -1
- package/lib/esm/geometry4d/Point4d.d.ts.map +1 -1
- package/lib/esm/geometry4d/Point4d.js +12 -13
- package/lib/esm/geometry4d/Point4d.js.map +1 -1
- package/package.json +3 -3
package/lib/cjs/Geometry.js
CHANGED
|
@@ -11,7 +11,7 @@ const Point3dVector3d_1 = require("./geometry3d/Point3dVector3d");
|
|
|
11
11
|
/**
|
|
12
12
|
* Enumeration of the 6 possible orderings of XYZ axis order
|
|
13
13
|
* * **Note:** There are 3 axis order with right hand system (XYZ = 0, YZX = 1, ZXY = 2) and 3 axis order with
|
|
14
|
-
* left hand system (XZY = 4, YXZ = 5, ZYX = 6). Note that AxisOrder is encoding the handedness as well. Cross
|
|
14
|
+
* left hand system (XZY = 4, YXZ = 5, ZYX = 6). Note that `AxisOrder` is encoding the handedness as well. Cross
|
|
15
15
|
* product of the i_th axis in an ordering (i=0,1,2), with the i+1_th in that ordering, will produce the i+2_th
|
|
16
16
|
* axis in that ordering.
|
|
17
17
|
* @public
|
|
@@ -44,7 +44,8 @@ var AxisIndex;
|
|
|
44
44
|
/** 2 axis is index 2 */
|
|
45
45
|
AxisIndex[AxisIndex["Z"] = 2] = "Z";
|
|
46
46
|
})(AxisIndex = exports.AxisIndex || (exports.AxisIndex = {}));
|
|
47
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Standard views. Used in `Matrix3d.createStandardViewAxes(index: StandardViewIndex, invert: boolean)`
|
|
48
49
|
* @public
|
|
49
50
|
*/
|
|
50
51
|
var StandardViewIndex;
|
|
@@ -53,20 +54,21 @@ var StandardViewIndex;
|
|
|
53
54
|
StandardViewIndex[StandardViewIndex["Top"] = 1] = "Top";
|
|
54
55
|
/** X to right, negative Y up */
|
|
55
56
|
StandardViewIndex[StandardViewIndex["Bottom"] = 2] = "Bottom";
|
|
56
|
-
/**
|
|
57
|
+
/** Negative Y to right, Z up */
|
|
57
58
|
StandardViewIndex[StandardViewIndex["Left"] = 3] = "Left";
|
|
58
|
-
/**
|
|
59
|
+
/** Y to right, Z up */
|
|
59
60
|
StandardViewIndex[StandardViewIndex["Right"] = 4] = "Right";
|
|
60
61
|
/** X to right, Z up */
|
|
61
62
|
StandardViewIndex[StandardViewIndex["Front"] = 5] = "Front";
|
|
62
|
-
/**
|
|
63
|
+
/** Negative X to right, Z up */
|
|
63
64
|
StandardViewIndex[StandardViewIndex["Back"] = 6] = "Back";
|
|
64
|
-
/**
|
|
65
|
+
/** Isometric: view towards origin from (-1,-1,1) */
|
|
65
66
|
StandardViewIndex[StandardViewIndex["Iso"] = 7] = "Iso";
|
|
66
|
-
/**
|
|
67
|
+
/** Right isometric: view towards origin from (1,-1,1) */
|
|
67
68
|
StandardViewIndex[StandardViewIndex["RightIso"] = 8] = "RightIso";
|
|
68
69
|
})(StandardViewIndex = exports.StandardViewIndex || (exports.StandardViewIndex = {}));
|
|
69
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Enumeration among choice for how a coordinate transformation should incorporate scaling.
|
|
70
72
|
* @public
|
|
71
73
|
*/
|
|
72
74
|
var AxisScaleSelect;
|
|
@@ -78,7 +80,8 @@ var AxisScaleSelect;
|
|
|
78
80
|
/** On each axis, the vector length matches he length of the corresponding edge of the range. */
|
|
79
81
|
AxisScaleSelect[AxisScaleSelect["NonUniformRangeContainment"] = 2] = "NonUniformRangeContainment";
|
|
80
82
|
})(AxisScaleSelect = exports.AxisScaleSelect || (exports.AxisScaleSelect = {}));
|
|
81
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* Enumeration of possible locations of a point in the plane of a polygon.
|
|
82
85
|
* @public
|
|
83
86
|
*/
|
|
84
87
|
var PolygonLocation;
|
|
@@ -111,18 +114,26 @@ var PolygonLocation;
|
|
|
111
114
|
* @public
|
|
112
115
|
*/
|
|
113
116
|
class Geometry {
|
|
114
|
-
/** Test if absolute value of x is
|
|
115
|
-
|
|
117
|
+
/** Test if absolute value of x is large (larger than `Geometry.largeCoordinateResult`) */
|
|
118
|
+
static isLargeCoordinateResult(x) {
|
|
119
|
+
return x > this.largeCoordinateResult || x < -this.largeCoordinateResult;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Test if absolute value of x is large (larger than `Geometry.largeCoordinateResult`).
|
|
123
|
+
* @deprecated in 4.x. Use `isLargeCoordinateResult`.
|
|
116
124
|
*/
|
|
117
125
|
static isHugeCoordinate(x) {
|
|
118
|
-
return
|
|
126
|
+
return Geometry.isLargeCoordinateResult(x);
|
|
119
127
|
}
|
|
120
|
-
/** Test if a number is odd
|
|
121
|
-
*/
|
|
128
|
+
/** Test if a number is odd */
|
|
122
129
|
static isOdd(x) {
|
|
123
|
-
return (x & (0x01)) === 1;
|
|
130
|
+
return (x & (0x01)) === 1; // bitwise operation
|
|
124
131
|
}
|
|
125
|
-
/**
|
|
132
|
+
/**
|
|
133
|
+
* Correct distance to zero.
|
|
134
|
+
* * If `distance` magnitude is `undefined` or smaller than `smallMetricDistance`, then return `replacement`
|
|
135
|
+
* (or 0 if replacement is not passed). Otherwise return `distance`.
|
|
136
|
+
*/
|
|
126
137
|
static correctSmallMetricDistance(distance, replacement = 0.0) {
|
|
127
138
|
if (distance === undefined || Math.abs(distance) < Geometry.smallMetricDistance) {
|
|
128
139
|
return replacement;
|
|
@@ -130,64 +141,119 @@ class Geometry {
|
|
|
130
141
|
return distance;
|
|
131
142
|
}
|
|
132
143
|
/**
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
144
|
+
* Correct `fraction` to `replacement` if `fraction` is undefined or too small.
|
|
145
|
+
* @param fraction number to test
|
|
146
|
+
* @param replacement value to return if `fraction` is too small
|
|
147
|
+
* @returns `fraction` if its absolute value is at least `Geometry.smallFraction`; otherwise returns `replacement`
|
|
148
|
+
*/
|
|
149
|
+
static correctSmallFraction(fraction, replacement = 0.0) {
|
|
150
|
+
if (fraction === undefined || Math.abs(fraction) < Geometry.smallFraction) {
|
|
151
|
+
return replacement;
|
|
152
|
+
}
|
|
153
|
+
return fraction;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Return the inverse of `distance`.
|
|
157
|
+
* * If `distance` magnitude is smaller than `smallMetricDistance` (i.e. distance is large enough for safe division),
|
|
158
|
+
* then return `1/distance`. Otherwise return `undefined`.
|
|
159
|
+
*/
|
|
160
|
+
static inverseMetricDistance(distance) {
|
|
161
|
+
return (Math.abs(distance) <= Geometry.smallMetricDistance) ? undefined : 1.0 / distance;
|
|
138
162
|
}
|
|
139
163
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
164
|
+
* Return the inverse of `distanceSquared`.
|
|
165
|
+
* * If `distanceSquared ` magnitude is smaller than `smallMetricDistanceSquared` (i.e. distanceSquared is large
|
|
166
|
+
* enough for safe division), then return `1/distanceSquared `. Otherwise return `undefined`.
|
|
142
167
|
*/
|
|
143
|
-
static inverseMetricDistanceSquared(
|
|
144
|
-
return (Math.abs(
|
|
168
|
+
static inverseMetricDistanceSquared(distanceSquared) {
|
|
169
|
+
return (Math.abs(distanceSquared) <= Geometry.smallMetricDistanceSquared) ? undefined : 1.0 / distanceSquared;
|
|
145
170
|
}
|
|
146
171
|
/**
|
|
147
|
-
* Boolean test for metric coordinate near-equality (i.e., if x and y are almost equal)
|
|
148
|
-
* `Geometry.smallMetricDistance` is used
|
|
172
|
+
* Boolean test for metric coordinate near-equality (i.e., if `x` and `y` are almost equal) using `tolerance`.
|
|
173
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
149
174
|
*/
|
|
150
|
-
static isSameCoordinate(x, y,
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
175
|
+
static isSameCoordinate(x, y, tolerance = Geometry.smallMetricDistance) {
|
|
176
|
+
let d = x - y;
|
|
177
|
+
if (d < 0)
|
|
178
|
+
d = -d;
|
|
179
|
+
return d <= tolerance;
|
|
154
180
|
}
|
|
155
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* Boolean test for metric coordinate near-equality (i.e., if `x` and `y` are almost equal) using
|
|
183
|
+
* `tolerance = toleranceFactor * smallMetricDistance`
|
|
184
|
+
* */
|
|
156
185
|
static isSameCoordinateWithToleranceFactor(x, y, toleranceFactor) {
|
|
157
186
|
return Geometry.isSameCoordinate(x, y, toleranceFactor * Geometry.smallMetricDistance);
|
|
158
187
|
}
|
|
159
|
-
/**
|
|
160
|
-
|
|
188
|
+
/**
|
|
189
|
+
* Boolean test for metric coordinate pair near-equality (i.e., if `x0` and `x1` are almost equal
|
|
190
|
+
* and `y0` and `y1` are almost equal) using `tolerance`.
|
|
191
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
192
|
+
*/
|
|
193
|
+
static isSameCoordinateXY(x0, y0, x1, y1, tolerance = Geometry.smallMetricDistance) {
|
|
161
194
|
let d = x1 - x0;
|
|
162
195
|
if (d < 0)
|
|
163
196
|
d = -d;
|
|
164
|
-
if (d >
|
|
197
|
+
if (d > tolerance)
|
|
165
198
|
return false;
|
|
166
199
|
d = y1 - y0;
|
|
167
200
|
if (d < 0)
|
|
168
201
|
d = -d;
|
|
169
|
-
return d
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
static
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
return d <= tolerance;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Boolean test for squared metric coordinate near-equality (i.e., if `sqrt(x)` and `sqrt(y)` are
|
|
206
|
+
* almost equal) using `tolerance`.
|
|
207
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
208
|
+
*/
|
|
209
|
+
static isSameCoordinateSquared(x, y, tolerance = Geometry.smallMetricDistance) {
|
|
210
|
+
return Math.abs(Math.sqrt(x) - Math.sqrt(y)) <= tolerance;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Boolean test for small `dataA.distance(dataB)` within `tolerance`.
|
|
214
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
215
|
+
*/
|
|
216
|
+
static isSamePoint3d(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
217
|
+
return dataA.distance(dataB) <= tolerance;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Boolean test for small xyz-distance within `tolerance`.
|
|
221
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
222
|
+
* * Note that Point3d and Vector3d are both derived from XYZ, so this method tolerates mixed types.
|
|
223
|
+
*/
|
|
224
|
+
static isSameXYZ(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
225
|
+
return dataA.distance(dataB) <= tolerance;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Boolean test for small xy-distance (ignoring z) within `tolerance`.
|
|
229
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
230
|
+
*/
|
|
231
|
+
static isSamePoint3dXY(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
232
|
+
return dataA.distanceXY(dataB) <= tolerance;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Boolean test for small xyz-distance within `tolerance`.
|
|
236
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
237
|
+
*/
|
|
238
|
+
static isSameVector3d(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
239
|
+
return dataA.distance(dataB) <= tolerance;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Boolean test for small xy-distance within `tolerance`.
|
|
243
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
244
|
+
*/
|
|
245
|
+
static isSamePoint2d(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
246
|
+
return dataA.distance(dataB) <= tolerance;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Boolean test for small xy-distance within `tolerance`.
|
|
250
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
251
|
+
*/
|
|
252
|
+
static isSameVector2d(dataA, dataB, tolerance = Geometry.smallMetricDistance) {
|
|
253
|
+
return dataA.distance(dataB) <= tolerance;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Lexical comparison of (a.x, a.y) and (b.x, b.y) with x as first test and y as second (z is ignored).
|
|
191
257
|
* * This is appropriate for a horizontal sweep in the plane.
|
|
192
258
|
*/
|
|
193
259
|
static lexicalXYLessThan(a, b) {
|
|
@@ -202,7 +268,7 @@ class Geometry {
|
|
|
202
268
|
return 0;
|
|
203
269
|
}
|
|
204
270
|
/**
|
|
205
|
-
* Lexical comparison of (a.x,a.y) (b.x,b.y) with y as first test
|
|
271
|
+
* Lexical comparison of (a.x, a.y) and (b.x, b.y) with y as first test and x as second (z is ignored).
|
|
206
272
|
* * This is appropriate for a vertical sweep in the plane.
|
|
207
273
|
*/
|
|
208
274
|
static lexicalYXLessThan(a, b) {
|
|
@@ -216,9 +282,7 @@ class Geometry {
|
|
|
216
282
|
return 1;
|
|
217
283
|
return 0;
|
|
218
284
|
}
|
|
219
|
-
/**
|
|
220
|
-
* Lexical test, based on x first, y second, z third.
|
|
221
|
-
*/
|
|
285
|
+
/** Lexical comparison of (a.x, a.y, a.z) and (b.x, b.y, b.z) with x as first test, y as second, and z as third. */
|
|
222
286
|
static lexicalXYZLessThan(a, b) {
|
|
223
287
|
if (a.x < b.x)
|
|
224
288
|
return -1;
|
|
@@ -234,19 +298,21 @@ class Geometry {
|
|
|
234
298
|
return 1;
|
|
235
299
|
return 0;
|
|
236
300
|
}
|
|
237
|
-
/**
|
|
301
|
+
/**
|
|
302
|
+
* Test if `value` is small compared to `smallFraction`.
|
|
238
303
|
* * This is appropriate if `value` is know to be a typical 0..1 fraction.
|
|
239
304
|
*/
|
|
240
305
|
static isSmallRelative(value) {
|
|
241
|
-
return Math.abs(value) < Geometry.
|
|
306
|
+
return Math.abs(value) < Geometry.smallFraction;
|
|
242
307
|
}
|
|
243
308
|
/** Test if `value` is small compared to `smallAngleRadians` */
|
|
244
309
|
static isSmallAngleRadians(value) {
|
|
245
310
|
return Math.abs(value) < Geometry.smallAngleRadians;
|
|
246
311
|
}
|
|
247
|
-
/**
|
|
248
|
-
*
|
|
249
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Returns `true` if both values are `undefined` or if both are defined and almost equal within tolerance.
|
|
314
|
+
* If one is `undefined` and the other is not, then `false` is returned.
|
|
315
|
+
*/
|
|
250
316
|
static isAlmostEqualOptional(a, b, tolerance) {
|
|
251
317
|
if (a !== undefined && b !== undefined) {
|
|
252
318
|
if (Math.abs(a - b) > tolerance)
|
|
@@ -258,44 +324,43 @@ class Geometry {
|
|
|
258
324
|
}
|
|
259
325
|
return true;
|
|
260
326
|
}
|
|
261
|
-
/**
|
|
262
|
-
*
|
|
263
|
-
|
|
264
|
-
|
|
327
|
+
/**
|
|
328
|
+
* Toleranced equality test using tolerance `tolerance * ( 1 + abs(a) + abs(b) )`.
|
|
329
|
+
* * `Geometry.smallAngleRadians` is used if tolerance is `undefined`.
|
|
330
|
+
*/
|
|
331
|
+
static isAlmostEqualNumber(a, b, tolerance = Geometry.smallAngleRadians) {
|
|
265
332
|
const sumAbs = 1.0 + Math.abs(a) + Math.abs(b);
|
|
266
|
-
return Math.abs(a - b) <=
|
|
333
|
+
return Math.abs(a - b) <= tolerance * sumAbs;
|
|
267
334
|
}
|
|
268
|
-
/**
|
|
269
|
-
*
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
const
|
|
274
|
-
return Math.abs(a.x - b.x) <=
|
|
335
|
+
/**
|
|
336
|
+
* Toleranced equality test using tolerance `tolerance * ( 1 + abs(a.x) + abs(a.y) + abs(b.x) + abs(b.y) )`.
|
|
337
|
+
* * `Geometry.smallAngleRadians` is used if tolerance is `undefined`.
|
|
338
|
+
*/
|
|
339
|
+
static isAlmostEqualXAndY(a, b, tolerance = Geometry.smallAngleRadians) {
|
|
340
|
+
const tol = tolerance * (1.0 + Math.abs(a.x) + Math.abs(b.x) + Math.abs(a.y) + Math.abs(b.y));
|
|
341
|
+
return (Math.abs(a.x - b.x) <= tol) && (Math.abs(a.y - b.y) <= tol);
|
|
275
342
|
}
|
|
276
343
|
/**
|
|
277
|
-
* Toleranced equality test
|
|
278
|
-
*
|
|
344
|
+
* Toleranced equality test using caller-supplied `tolerance`.
|
|
345
|
+
* * `Geometry.smallMetricDistance` is used if tolerance is `undefined`.
|
|
279
346
|
*/
|
|
280
|
-
static isDistanceWithinTol(distance,
|
|
281
|
-
|
|
282
|
-
return Math.abs(distance) <= Math.abs(tol);
|
|
283
|
-
return Math.abs(distance) <= Geometry.smallMetricDistance;
|
|
347
|
+
static isDistanceWithinTol(distance, tolerance = Geometry.smallMetricDistance) {
|
|
348
|
+
return Math.abs(distance) <= tolerance;
|
|
284
349
|
}
|
|
285
|
-
/** Toleranced equality test
|
|
350
|
+
/** Toleranced equality test using `smallMetricDistance` tolerance. */
|
|
286
351
|
static isSmallMetricDistance(distance) {
|
|
287
352
|
return Math.abs(distance) <= Geometry.smallMetricDistance;
|
|
288
353
|
}
|
|
289
|
-
/** Toleranced equality
|
|
354
|
+
/** Toleranced equality test using `smallMetricDistanceSquared` tolerance. */
|
|
290
355
|
static isSmallMetricDistanceSquared(distanceSquared) {
|
|
291
356
|
return Math.abs(distanceSquared) <= Geometry.smallMetricDistanceSquared;
|
|
292
357
|
}
|
|
293
358
|
/**
|
|
294
359
|
* Return `axis modulo 3` with proper handling of negative indices
|
|
295
360
|
* ..., -3:x, -2:y, -1:z, 0:x, 1:y, 2:z, 3:x, 4:y, 5:z, 6:x, 7:y, 8:z, ...
|
|
296
|
-
|
|
361
|
+
*/
|
|
297
362
|
static cyclic3dAxis(axis) {
|
|
298
|
-
/* Direct test for the most common cases
|
|
363
|
+
/* Direct test for the most common cases to avoid more expensive modulo operation */
|
|
299
364
|
if (axis >= 0) {
|
|
300
365
|
if (axis < 3)
|
|
301
366
|
return axis;
|
|
@@ -308,7 +373,8 @@ class Geometry {
|
|
|
308
373
|
return j;
|
|
309
374
|
return 2 - ((-axis - 1) % 3);
|
|
310
375
|
}
|
|
311
|
-
/**
|
|
376
|
+
/**
|
|
377
|
+
* Return the `AxisOrder` for which `axisIndex` is the first named axis.
|
|
312
378
|
* * `axisIndex === 0` returns `AxisOrder.XYZ`
|
|
313
379
|
* * `axisIndex === 1` returns `AxisOrder.YZX`
|
|
314
380
|
* * `axisIndex === 2` returns `AxisOrder.ZXY`
|
|
@@ -322,32 +388,55 @@ class Geometry {
|
|
|
322
388
|
return AxisOrder.ZXY;
|
|
323
389
|
return Geometry.axisIndexToRightHandedAxisOrder(Geometry.cyclic3dAxis(axisIndex));
|
|
324
390
|
}
|
|
325
|
-
/** Return the largest
|
|
326
|
-
static
|
|
327
|
-
|
|
391
|
+
/** Return the largest signed value among `a`, `b`, and `c` */
|
|
392
|
+
static maxXYZ(a, b, c) {
|
|
393
|
+
let max = a;
|
|
394
|
+
if (b > max)
|
|
395
|
+
max = b;
|
|
396
|
+
if (c > max)
|
|
397
|
+
max = c;
|
|
398
|
+
return max;
|
|
399
|
+
}
|
|
400
|
+
/** Return the smallest signed value among `a`, `b`, and `c` */
|
|
401
|
+
static minXYZ(a, b, c) {
|
|
402
|
+
let min = a;
|
|
403
|
+
if (b < min)
|
|
404
|
+
min = b;
|
|
405
|
+
if (c < min)
|
|
406
|
+
min = c;
|
|
407
|
+
return min;
|
|
408
|
+
}
|
|
409
|
+
/** Return the largest signed value among `a` and `b` */
|
|
410
|
+
static maxXY(a, b) {
|
|
411
|
+
let max = a;
|
|
412
|
+
if (b > max)
|
|
413
|
+
max = b;
|
|
414
|
+
return max;
|
|
328
415
|
}
|
|
329
|
-
/** Return the
|
|
416
|
+
/** Return the smallest signed value among `a` and `b` */
|
|
417
|
+
static minXY(a, b) {
|
|
418
|
+
let min = a;
|
|
419
|
+
if (b < min)
|
|
420
|
+
min = b;
|
|
421
|
+
return min;
|
|
422
|
+
}
|
|
423
|
+
/** Return the largest absolute value among `x`, `y`, and `z` */
|
|
330
424
|
static maxAbsXYZ(x, y, z) {
|
|
331
425
|
return Geometry.maxXYZ(Math.abs(x), Math.abs(y), Math.abs(z));
|
|
332
426
|
}
|
|
333
|
-
/** Return the largest absolute
|
|
427
|
+
/** Return the largest absolute value among `x` and `y` */
|
|
334
428
|
static maxAbsXY(x, y) {
|
|
335
429
|
return Geometry.maxXY(Math.abs(x), Math.abs(y));
|
|
336
430
|
}
|
|
337
|
-
/** Return the largest
|
|
338
|
-
static
|
|
339
|
-
|
|
340
|
-
if (b > q)
|
|
341
|
-
q = b;
|
|
342
|
-
if (c > q)
|
|
343
|
-
q = c;
|
|
344
|
-
return q;
|
|
431
|
+
/** Return the largest absolute distance from `a` to either of `b0` or `b1` */
|
|
432
|
+
static maxAbsDiff(a, b0, b1) {
|
|
433
|
+
return Math.max(Math.abs(a - b0), Math.abs(a - b1));
|
|
345
434
|
}
|
|
346
435
|
/**
|
|
347
|
-
* Examine the
|
|
348
|
-
* * If x is negative, return outNegative
|
|
349
|
-
* * If x is true zero, return outZero
|
|
350
|
-
* * If x is positive, return outPositive
|
|
436
|
+
* Examine the sign of `x`.
|
|
437
|
+
* * If `x` is negative, return `outNegative`
|
|
438
|
+
* * If `x` is true zero, return `outZero`
|
|
439
|
+
* * If `x` is positive, return `outPositive`
|
|
351
440
|
*/
|
|
352
441
|
static split3WaySign(x, outNegative, outZero, outPositive) {
|
|
353
442
|
if (x < 0)
|
|
@@ -369,45 +458,40 @@ class Geometry {
|
|
|
369
458
|
return -1;
|
|
370
459
|
return 0;
|
|
371
460
|
}
|
|
372
|
-
/** Return the
|
|
373
|
-
static
|
|
374
|
-
|
|
375
|
-
if (b > q)
|
|
376
|
-
q = b;
|
|
377
|
-
return q;
|
|
378
|
-
}
|
|
379
|
-
/** Return the smallest signed value among a, b */
|
|
380
|
-
static minXY(a, b) {
|
|
381
|
-
let q = a;
|
|
382
|
-
if (b < q)
|
|
383
|
-
q = b;
|
|
384
|
-
return q;
|
|
461
|
+
/** Return the square of x */
|
|
462
|
+
static square(x) {
|
|
463
|
+
return x * x;
|
|
385
464
|
}
|
|
386
|
-
/**
|
|
465
|
+
/**
|
|
466
|
+
* Return the hypotenuse (i.e., `sqrt(x*x + y*y)`).
|
|
467
|
+
* * This is much faster than `Math.hypot(x,y)`.
|
|
468
|
+
*/
|
|
387
469
|
static hypotenuseXY(x, y) {
|
|
388
470
|
return Math.sqrt(x * x + y * y);
|
|
389
471
|
}
|
|
390
|
-
/** Return the squared
|
|
472
|
+
/** Return the squared hypotenuse (i.e., `x*x + y*y`). */
|
|
391
473
|
static hypotenuseSquaredXY(x, y) {
|
|
392
474
|
return x * x + y * y;
|
|
393
475
|
}
|
|
394
|
-
/**
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
/** Return the hypotenuse `sqrt(x*x + y*y + z*z)`. This is much faster than `Math.hypot(x,y,z)`. */
|
|
476
|
+
/**
|
|
477
|
+
* Return the hypotenuse (i.e., `sqrt(x*x + y*y + z*z)`).
|
|
478
|
+
* * This is much faster than `Math.hypot(x,y,z)`.
|
|
479
|
+
*/
|
|
399
480
|
static hypotenuseXYZ(x, y, z) {
|
|
400
481
|
return Math.sqrt(x * x + y * y + z * z);
|
|
401
482
|
}
|
|
402
|
-
/** Return the squared hypotenuse `
|
|
483
|
+
/** Return the squared hypotenuse (i.e., `x*x + y*y + z*z`). */
|
|
403
484
|
static hypotenuseSquaredXYZ(x, y, z) {
|
|
404
485
|
return x * x + y * y + z * z;
|
|
405
486
|
}
|
|
406
|
-
/**
|
|
487
|
+
/**
|
|
488
|
+
* Return the full 4d hypotenuse (i.e., `sqrt(x*x + y*y + z*z + w*w)`).
|
|
489
|
+
* * This is much faster than `Math.hypot(x,y,z,w)`.
|
|
490
|
+
*/
|
|
407
491
|
static hypotenuseXYZW(x, y, z, w) {
|
|
408
492
|
return Math.sqrt(x * x + y * y + z * z + w * w);
|
|
409
493
|
}
|
|
410
|
-
/** Return the squared hypotenuse `
|
|
494
|
+
/** Return the squared hypotenuse (i.e., `x*x + y*y + z*z + w*w`). */
|
|
411
495
|
static hypotenuseSquaredXYZW(x, y, z, w) {
|
|
412
496
|
return x * x + y * y + z * z + w * w;
|
|
413
497
|
}
|
|
@@ -433,8 +517,8 @@ class Geometry {
|
|
|
433
517
|
static distanceXYZXYZ(x0, y0, z0, x1, y1, z1) {
|
|
434
518
|
return Geometry.hypotenuseXYZ(x1 - x0, y1 - y0, z1 - z0);
|
|
435
519
|
}
|
|
436
|
-
/**
|
|
437
|
-
*
|
|
520
|
+
/**
|
|
521
|
+
* Returns the triple product of 3 vectors provided as x,y,z number sequences.
|
|
438
522
|
* * The triple product is the determinant of the 3x3 matrix with the 9 numbers (3 vectors placed in 3 rows).
|
|
439
523
|
* * The triple product is positive if the 3 vectors form a right handed coordinate system.
|
|
440
524
|
* * The triple product is negative if the 3 vectors form a left handed coordinate system.
|
|
@@ -442,170 +526,196 @@ class Geometry {
|
|
|
442
526
|
* * U dot (V cross W)
|
|
443
527
|
* * V dot (W cross U)
|
|
444
528
|
* * W dot (U cross V)
|
|
445
|
-
* *
|
|
446
|
-
* *
|
|
447
|
-
* *
|
|
448
|
-
* *
|
|
529
|
+
* * -U dot (W cross V)
|
|
530
|
+
* * -V dot (U cross W)
|
|
531
|
+
* * -W dot (V cross U)
|
|
532
|
+
* * Note the negative in the last 3 formulas. Reversing cross product order changes the sign.
|
|
533
|
+
* * The triple product is 6 times the (signed) volume of the tetrahedron with the three vectors as edges from a
|
|
534
|
+
* common vertex.
|
|
449
535
|
*/
|
|
450
536
|
static tripleProduct(ux, uy, uz, vx, vy, vz, wx, wy, wz) {
|
|
451
537
|
return ux * (vy * wz - vz * wy)
|
|
452
538
|
+ uy * (vz * wx - vx * wz)
|
|
453
539
|
+ uz * (vx * wy - vy * wx);
|
|
454
540
|
}
|
|
455
|
-
/** Returns the determinant of the 4x4 matrix unrolled as the 16 parameters
|
|
456
|
-
*/
|
|
541
|
+
/** Returns the determinant of the 4x4 matrix unrolled as the 16 parameters */
|
|
457
542
|
static determinant4x4(xx, xy, xz, xw, yx, yy, yz, yw, zx, zy, zz, zw, wx, wy, wz, ww) {
|
|
458
543
|
return xx * this.tripleProduct(yy, yz, yw, zy, zz, zw, wy, wz, ww)
|
|
459
544
|
- yx * this.tripleProduct(xy, xz, xw, zy, zz, zw, wy, wz, ww)
|
|
460
545
|
+ zx * this.tripleProduct(xy, xz, xw, yy, yz, yw, wy, wz, ww)
|
|
461
546
|
- wx * this.tripleProduct(xy, xz, xw, yy, yz, yw, zy, zz, zw);
|
|
462
547
|
}
|
|
463
|
-
/** Return the mean curvature for two radii, with 0 radius implying 0 curvature */
|
|
464
|
-
static meanCurvatureOfRadii(r0, r1) {
|
|
465
|
-
return 0.5 * (this.safeDivideFraction(1, r0, 0) + this.safeDivideFraction(1, r1, 0));
|
|
466
|
-
}
|
|
467
548
|
/**
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
* @param vy second derivative y component
|
|
474
|
-
* @param vz second derivative z component
|
|
475
|
-
*/
|
|
476
|
-
static curvatureMagnitude(ux, uy, uz, vx, vy, vz) {
|
|
477
|
-
let q = uy * vz - uz * vy;
|
|
478
|
-
let sum = q * q;
|
|
479
|
-
q = uz * vx - ux * vz;
|
|
480
|
-
sum += q * q;
|
|
481
|
-
q = ux * vy - uy * vx;
|
|
482
|
-
sum += q * q;
|
|
483
|
-
const a = Math.sqrt(ux * ux + uy * uy + uz * uz);
|
|
484
|
-
const b = Math.sqrt(sum);
|
|
485
|
-
// (sum and a are both nonnegative)
|
|
486
|
-
const aaa = a * a * a;
|
|
487
|
-
// radius of curvature = aaa / b;
|
|
488
|
-
// curvature = b/aaa
|
|
489
|
-
const tol = Geometry.smallAngleRadians;
|
|
490
|
-
if (aaa > tol * b)
|
|
491
|
-
return b / aaa;
|
|
492
|
-
return 0; // hm.. maybe should be infinite?
|
|
493
|
-
}
|
|
494
|
-
/** Returns the determinant of 3x3 matrix with x and y rows taken from 3 points, third row from corresponding numbers.
|
|
495
|
-
*
|
|
549
|
+
* Returns the determinant of 3x3 matrix with first and second rows created from the 3 xy points and the third
|
|
550
|
+
* row created from the 3 numbers:
|
|
551
|
+
* [columnA.x columnB.x columnC.x]
|
|
552
|
+
* [columnA.y columnB.y columnC.y]
|
|
553
|
+
* [ weightA weightB weightC ]
|
|
496
554
|
*/
|
|
497
555
|
static tripleProductXYW(columnA, weightA, columnB, weightB, columnC, weightC) {
|
|
498
556
|
return Geometry.tripleProduct(columnA.x, columnB.x, columnC.x, columnA.y, columnB.y, columnC.y, weightA, weightB, weightC);
|
|
499
557
|
}
|
|
500
|
-
/**
|
|
501
|
-
*
|
|
558
|
+
/**
|
|
559
|
+
* Returns the determinant of 3x3 matrix columns created by the given `Point4d` ignoring the z part:
|
|
560
|
+
* [columnA.x columnB.x columnC.x]
|
|
561
|
+
* [columnA.y columnB.y columnC.y]
|
|
562
|
+
* [columnA.w columnB.w columnC.w]
|
|
502
563
|
*/
|
|
503
564
|
static tripleProductPoint4dXYW(columnA, columnB, columnC) {
|
|
504
565
|
return Geometry.tripleProduct(columnA.x, columnB.x, columnC.x, columnA.y, columnB.y, columnC.y, columnA.w, columnB.w, columnC.w);
|
|
505
566
|
}
|
|
506
|
-
/** 2D cross product of vectors
|
|
567
|
+
/** 2D cross product of vectors with the vectors presented as numbers. */
|
|
507
568
|
static crossProductXYXY(ux, uy, vx, vy) {
|
|
508
569
|
return ux * vy - uy * vx;
|
|
509
570
|
}
|
|
510
|
-
/** 3D cross product of vectors
|
|
571
|
+
/** 3D cross product of vectors with the vectors presented as numbers. */
|
|
511
572
|
static crossProductXYZXYZ(ux, uy, uz, vx, vy, vz, result) {
|
|
512
573
|
return Point3dVector3d_1.Vector3d.create(uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx, result);
|
|
513
574
|
}
|
|
514
|
-
/**
|
|
575
|
+
/** Magnitude of 3D cross product of vectors with the vectors presented as numbers. */
|
|
515
576
|
static crossProductMagnitude(ux, uy, uz, vx, vy, vz) {
|
|
516
577
|
return Geometry.hypotenuseXYZ(uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx);
|
|
517
578
|
}
|
|
518
|
-
/**
|
|
579
|
+
/** 2D dot product of vectors with the vectors presented as numbers. */
|
|
580
|
+
static dotProductXYXY(ux, uy, vx, vy) {
|
|
581
|
+
return ux * vx + uy * vy;
|
|
582
|
+
}
|
|
583
|
+
/** 3D dot product of vectors with the vectors presented as numbers. */
|
|
519
584
|
static dotProductXYZXYZ(ux, uy, uz, vx, vy, vz) {
|
|
520
585
|
return ux * vx + uy * vy + uz * vz;
|
|
521
586
|
}
|
|
522
|
-
/**
|
|
523
|
-
|
|
524
|
-
|
|
587
|
+
/**
|
|
588
|
+
* Return the mean curvature for two radii.
|
|
589
|
+
* * Curvature is the reciprocal of radius.
|
|
590
|
+
* * 0 radius implies 0 curvature.
|
|
591
|
+
* @param r0 first radius
|
|
592
|
+
* @param r1 second radius
|
|
593
|
+
*/
|
|
594
|
+
static meanCurvatureOfRadii(r0, r1) {
|
|
595
|
+
return 0.5 * (this.safeDivideFraction(1, r0, 0) + this.safeDivideFraction(1, r1, 0));
|
|
525
596
|
}
|
|
526
597
|
/**
|
|
527
|
-
*
|
|
528
|
-
* *
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
* @param
|
|
598
|
+
* Returns curvature from the first and second derivative vectors.
|
|
599
|
+
* * If U is the first derivative and V is the second derivative, the curvature is defined as:
|
|
600
|
+
* * `|| U x V || / || U ||^3`.
|
|
601
|
+
* * Math details can be found at https://en.wikipedia.org/wiki/Curvature#General_expressions
|
|
602
|
+
* @param ux first derivative x component
|
|
603
|
+
* @param uy first derivative y component
|
|
604
|
+
* @param uz first derivative z component
|
|
605
|
+
* @param vx second derivative x component
|
|
606
|
+
* @param vy second derivative y component
|
|
607
|
+
* @param vz second derivative z component
|
|
608
|
+
*/
|
|
609
|
+
static curvatureMagnitude(ux, uy, uz, vx, vy, vz) {
|
|
610
|
+
let q = uy * vz - uz * vy;
|
|
611
|
+
let sum = q * q;
|
|
612
|
+
q = uz * vx - ux * vz;
|
|
613
|
+
sum += q * q;
|
|
614
|
+
q = ux * vy - uy * vx;
|
|
615
|
+
sum += q * q;
|
|
616
|
+
const magUxV = Math.sqrt(sum);
|
|
617
|
+
const magU = Math.sqrt(ux * ux + uy * uy + uz * uz);
|
|
618
|
+
const magUCubed = magU * magU * magU;
|
|
619
|
+
if (magUCubed > Geometry.smallAngleRadians * magUxV)
|
|
620
|
+
return magUxV / magUCubed;
|
|
621
|
+
return 0;
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Clamp to (min(a,b), max(a,b)).
|
|
625
|
+
* * Always returns a number between `a` and `b`.
|
|
626
|
+
* @param value value to clamp
|
|
627
|
+
* @param a smallest allowed output if `a < b` or largest allowed output if `a > b`
|
|
628
|
+
* @param b largest allowed output if `a < b` or smallest allowed output if `a > b`
|
|
532
629
|
*/
|
|
533
|
-
static clampToStartEnd(
|
|
630
|
+
static clampToStartEnd(value, a, b) {
|
|
534
631
|
if (a > b)
|
|
535
|
-
return Geometry.clampToStartEnd(
|
|
536
|
-
if (
|
|
632
|
+
return Geometry.clampToStartEnd(value, b, a);
|
|
633
|
+
if (value < a)
|
|
537
634
|
return a;
|
|
538
|
-
if (b <
|
|
635
|
+
if (b < value)
|
|
539
636
|
return b;
|
|
540
|
-
return
|
|
637
|
+
return value;
|
|
541
638
|
}
|
|
542
639
|
/**
|
|
543
|
-
* Clamp value to (min,max) with no test for order of (min,max)
|
|
640
|
+
* Clamp value to (min, max) with no test for order of (min, max).
|
|
641
|
+
* * Always returns a number between `min` and `max`.
|
|
544
642
|
* @param value value to clamp
|
|
545
643
|
* @param min smallest allowed output
|
|
546
|
-
* @param max largest allowed
|
|
644
|
+
* @param max largest allowed output
|
|
547
645
|
*/
|
|
548
|
-
static clamp(value, min, max) {
|
|
549
|
-
|
|
646
|
+
static clamp(value, min, max) {
|
|
647
|
+
return Math.max(min, Math.min(max, value));
|
|
648
|
+
}
|
|
649
|
+
/** If given a `value`, return it. If given `undefined`, return `defaultValue`. */
|
|
550
650
|
static resolveNumber(value, defaultValue = 0) {
|
|
551
651
|
return value !== undefined ? value : defaultValue;
|
|
552
652
|
}
|
|
553
|
-
/** If given a value
|
|
653
|
+
/** If given a `value`, return it. If given `undefined`, return `defaultValue`. */
|
|
554
654
|
static resolveValue(value, defaultValue) {
|
|
555
655
|
return value !== undefined ? value : defaultValue;
|
|
556
656
|
}
|
|
557
|
-
/** If given value matches
|
|
657
|
+
/** If given `value` matches the `targetValue`, return `undefined`. Otherwise return the `value`. */
|
|
558
658
|
static resolveToUndefined(value, targetValue) {
|
|
559
659
|
return value === targetValue ? undefined : value;
|
|
560
660
|
}
|
|
561
661
|
/**
|
|
562
|
-
* Simple interpolation between values
|
|
563
|
-
* point for maximum accuracy.
|
|
662
|
+
* Simple interpolation between values `a` and `b` with fraction `f`.
|
|
564
663
|
* * If `f = 0`, then `a` is returned and if `f = 1`, then `b` is returned.
|
|
664
|
+
* * For maximum accuracy, we choose `a` or `b` as starting point based on fraction `f`.
|
|
565
665
|
*/
|
|
566
666
|
static interpolate(a, f, b) {
|
|
567
667
|
return f <= 0.5 ? a + f * (b - a) : b - (1.0 - f) * (b - a);
|
|
568
668
|
}
|
|
569
669
|
/**
|
|
570
|
-
* Given an axisOrder (e.g. XYZ, YZX, etc) and an index
|
|
571
|
-
* * For example, if axisOrder = XYZ
|
|
572
|
-
* Y (or axis
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
670
|
+
* Given an `axisOrder` (e.g. XYZ, YZX, etc) and an `index`, return the `axis` at the given index.
|
|
671
|
+
* * For example, if `axisOrder = XYZ`, then for index 0 return `X` (or axis 0), for index 1 return
|
|
672
|
+
* `Y` (or axis 1), and for index 2 return `Z` (or axis 2).
|
|
673
|
+
* * Another example: if `axisOrder = ZXY`, then for index 0 return `Z` (or axis 2), for index 1 return
|
|
674
|
+
* `X` (or axis 0), and for index 2 return `Y` (or axis 1).
|
|
675
|
+
* * For indexes greater than 2 or smaller than 0, it return cyclic axis. See [[Geometry.cyclic3dAxis]]
|
|
676
|
+
* for more info.
|
|
677
|
+
*/
|
|
577
678
|
static axisOrderToAxis(order, index) {
|
|
578
679
|
const axis = order <= AxisOrder.ZXY ? order + index : (order - AxisOrder.XZY) - index;
|
|
579
680
|
return Geometry.cyclic3dAxis(axis);
|
|
580
681
|
}
|
|
581
|
-
/**
|
|
682
|
+
/**
|
|
683
|
+
* Return `a` modulo `period`.
|
|
684
|
+
* * Both `a` and `period` can be negative.
|
|
685
|
+
* * This function can be faster than the `%` operator for the common case when `p > 0` and `-p < a < 2p`.
|
|
686
|
+
*/
|
|
582
687
|
static modulo(a, period) {
|
|
688
|
+
// period is negative
|
|
583
689
|
if (period <= 0) {
|
|
584
690
|
if (period === 0)
|
|
585
691
|
return a;
|
|
586
692
|
return -Geometry.modulo(-a, -period);
|
|
587
693
|
}
|
|
694
|
+
// period is positive
|
|
588
695
|
if (a >= 0) {
|
|
589
|
-
if (a < period)
|
|
696
|
+
if (a < period) // "0 < a < period"
|
|
590
697
|
return a;
|
|
591
|
-
if (a < 2 * period)
|
|
698
|
+
if (a < 2 * period) // "0 < period < a < 2*period"
|
|
592
699
|
return a - period;
|
|
593
700
|
}
|
|
594
|
-
else {
|
|
595
|
-
a += period;
|
|
701
|
+
else { // "-period < a < 0"
|
|
702
|
+
a += period;
|
|
596
703
|
if (a > 0)
|
|
597
704
|
return a;
|
|
598
705
|
}
|
|
706
|
+
// "0 < 2*period < a" or "a < -period < 0"
|
|
599
707
|
const m = Math.floor(a / period);
|
|
600
708
|
return a - m * period;
|
|
601
709
|
}
|
|
602
|
-
/**
|
|
603
|
-
static defined01(value) {
|
|
710
|
+
/** Return 0 if the value is `undefined` and 1 if the value is defined. */
|
|
711
|
+
static defined01(value) {
|
|
712
|
+
return value === undefined ? 0 : 1;
|
|
713
|
+
}
|
|
604
714
|
/**
|
|
605
|
-
* Return `numerator` divided by `denominator
|
|
715
|
+
* Return `numerator` divided by `denominator`.
|
|
606
716
|
* @param numerator the numerator
|
|
607
717
|
* @param denominator the denominator
|
|
608
|
-
* @returns return `numerator/denominator` but if the ratio
|
|
718
|
+
* @returns return `numerator/denominator` but if the ratio exceeds `Geometry.largeFractionResult`,
|
|
609
719
|
* return `undefined`.
|
|
610
720
|
*/
|
|
611
721
|
static conditionalDivideFraction(numerator, denominator) {
|
|
@@ -617,76 +727,105 @@ class Geometry {
|
|
|
617
727
|
* Return `numerator` divided by `denominator`.
|
|
618
728
|
* @param numerator the numerator
|
|
619
729
|
* @param denominator the denominator
|
|
620
|
-
* @returns return `numerator/denominator` but if the ratio
|
|
730
|
+
* @returns return `numerator/denominator` but if the ratio exceeds `Geometry.largeFractionResult`,
|
|
621
731
|
* return `defaultResult`.
|
|
622
732
|
*/
|
|
623
733
|
static safeDivideFraction(numerator, denominator, defaultResult) {
|
|
624
|
-
const
|
|
625
|
-
if (
|
|
626
|
-
return
|
|
734
|
+
const ratio = Geometry.conditionalDivideFraction(numerator, denominator);
|
|
735
|
+
if (ratio !== undefined)
|
|
736
|
+
return ratio;
|
|
627
737
|
return defaultResult;
|
|
628
738
|
}
|
|
629
739
|
/**
|
|
630
|
-
* Return `numerator` divided by `denominator` (with a given `largestResult`)
|
|
740
|
+
* Return `numerator` divided by `denominator` (with a given `largestResult`).
|
|
631
741
|
* @param numerator the numerator
|
|
632
742
|
* @param denominator the denominator
|
|
633
|
-
* @param largestResult the ratio threshold
|
|
634
|
-
* @returns return `numerator/denominator` but if the ratio
|
|
743
|
+
* @param largestResult the ratio threshold
|
|
744
|
+
* @returns return `numerator/denominator` but if the ratio exceeds `largestResult`, return `undefined`.
|
|
635
745
|
*/
|
|
636
746
|
static conditionalDivideCoordinate(numerator, denominator, largestResult = Geometry.largeCoordinateResult) {
|
|
637
747
|
if (Math.abs(denominator * largestResult) > Math.abs(numerator))
|
|
638
748
|
return numerator / denominator;
|
|
639
749
|
return undefined;
|
|
640
750
|
}
|
|
641
|
-
/**
|
|
642
|
-
*
|
|
643
|
-
*
|
|
751
|
+
/**
|
|
752
|
+
* Return solution(s) of equation `constCoff + cosCoff*c + sinCoff*s = 0` for `c` and `s` with the
|
|
753
|
+
* constraint `c*c + s*s = 1`.
|
|
754
|
+
* * There could be 0, 1, or 2 solutions. Return `undefined` if there is no solution.
|
|
644
755
|
*/
|
|
645
756
|
static solveTrigForm(constCoff, cosCoff, sinCoff) {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
757
|
+
/**
|
|
758
|
+
* Solutions can be found by finding the intersection of line "ax + by + d = 0" and unit circle "x^2 + y^2 = 1".
|
|
759
|
+
* From the line equation we have "y = (-ax - d) / b". By replacing this into the circle equation we get
|
|
760
|
+
* "x^2 + (ax+d)^2/b^2 = 1". If we solve this by quadratic formula we get
|
|
761
|
+
* x = (-ad +- b*sqrt(a^2+b^2-d^2)) / (a^2+b^2)
|
|
762
|
+
* y = (-ad -+ a*sqrt(a^2+b^2-d^2)) / (a^2+b^2)
|
|
763
|
+
*
|
|
764
|
+
* If "a^2+b^2-d^2 > 0" then there are two solutions (above).
|
|
765
|
+
* If "a^2+b^2-d^2 = 0" then there is one solution which is (-ad/(a^2+b^2), -bd/(a^2+b^2)).
|
|
766
|
+
* If "a^2+b^2-d^2 < 0" then there is no solution.
|
|
767
|
+
*
|
|
768
|
+
* Below in the code we have "a = cosCoff", "b = sinCoff", and "d = constCoff". Also equivalent criterion
|
|
769
|
+
* is used in the code. For example, "a^2+b^2-d^2 > 0" is equivalent of "1 - d^2/(a^2+b^2) > 0".
|
|
770
|
+
*/
|
|
771
|
+
const a2b2 = cosCoff * cosCoff + sinCoff * sinCoff; // a^2+b^2
|
|
772
|
+
const d2 = constCoff * constCoff; // d^2
|
|
773
|
+
let result;
|
|
774
|
+
if (a2b2 > 0.0) {
|
|
775
|
+
const a2b2r = 1.0 / a2b2; // 1/(a^2+b^2)
|
|
776
|
+
const d2a2b2 = d2 * a2b2r; // d^2/(a^2+b^2)
|
|
777
|
+
const criteria = 1.0 - d2a2b2; // 1 - d^2/(a^2+b^2); the criteria to specify how many solutions we got
|
|
778
|
+
if (criteria < -Geometry.smallMetricDistanceSquared) // nSolution = 0
|
|
779
|
+
return result;
|
|
780
|
+
const da2b2 = -constCoff * a2b2r; // -d/(a^2+b^2)
|
|
781
|
+
const c0 = da2b2 * cosCoff; // -ad/(a^2+b^2)
|
|
782
|
+
const s0 = da2b2 * sinCoff; // -bd/(a^2+b^2)
|
|
783
|
+
if (criteria <= 0.0) { // nSolution = 1 (observed criteria = -2.22e-16 in rotated system)
|
|
784
|
+
result = [Point2dVector2d_1.Vector2d.create(c0, s0)];
|
|
785
|
+
}
|
|
786
|
+
else if (criteria > 0.0) { // nSolution = 2
|
|
787
|
+
const s = Math.sqrt(criteria * a2b2r); // sqrt(a^2+b^2-d^2)) / (a^2+b^2)
|
|
788
|
+
result = [
|
|
789
|
+
Point2dVector2d_1.Vector2d.create(c0 - s * sinCoff, s0 + s * cosCoff),
|
|
790
|
+
Point2dVector2d_1.Vector2d.create(c0 + s * sinCoff, s0 - s * cosCoff),
|
|
791
|
+
];
|
|
669
792
|
}
|
|
670
|
-
return result;
|
|
671
793
|
}
|
|
794
|
+
return result;
|
|
672
795
|
}
|
|
673
|
-
/**
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
796
|
+
/**
|
|
797
|
+
* For a line `f(x)` where `f(x0) = f0` and `f(x1) = f1`, return the `x` value at which `f(x) = fTarget`
|
|
798
|
+
* Return `defaultResult` if `(fTarget - f0) / (f1 - f0)` exceeds `Geometry.largeFractionResult`
|
|
799
|
+
*/
|
|
800
|
+
static inverseInterpolate(x0, f0, x1, f1, fTarget = 0, defaultResult) {
|
|
801
|
+
/**
|
|
802
|
+
* Line equation is "fTarget-f0 = (f1-f0)/(x1-x0) * (x-x0)" or "(fTarget-f0)/(f1-f0) = (x-x0)/(x1-x0)".
|
|
803
|
+
* The left hand side is known so if we call it "fr" (short for "fraction") we get "fr = (x-x0)/(x1-x0)".
|
|
804
|
+
* Therefore, "x = x0*(1-fr) + x1*fr". This is same as interpolation between "x0" and "x1" with fraction "fr".
|
|
805
|
+
*/
|
|
806
|
+
const fr = Geometry.conditionalDivideFraction(fTarget - f0, f1 - f0); // (fTarget-f0)/(f1-f0)
|
|
807
|
+
if (fr !== undefined)
|
|
808
|
+
return Geometry.interpolate(x0, fr, x1); // x = x0*(1-fr) + x1*fr
|
|
678
809
|
return defaultResult;
|
|
679
810
|
}
|
|
680
|
-
/**
|
|
681
|
-
|
|
682
|
-
|
|
811
|
+
/**
|
|
812
|
+
* For a line `f(x)` where `f(0) = f0` and `f(1) = f1`, return the `x` value at which `f(x) = fTarget`
|
|
813
|
+
* Return `undefined` if `(fTarget - f0) / (f1 - f0)` exceeds `Geometry.largeFractionResult`
|
|
814
|
+
*/
|
|
815
|
+
static inverseInterpolate01(f0, f1, fTarget = 0) {
|
|
816
|
+
/**
|
|
817
|
+
* Line equation is "fTarget-f0 = (f1-f0)*x" so "x = (fTarget-f0)/(f1-f0)"
|
|
818
|
+
*/
|
|
819
|
+
return Geometry.conditionalDivideFraction(fTarget - f0, f1 - f0); // x = (fTarget-f0)/(f1-f0)
|
|
683
820
|
}
|
|
684
|
-
/**
|
|
821
|
+
/**
|
|
822
|
+
* Return `true` if `json` is an array with at least `minEntries` entries and all entries are numbers (including
|
|
823
|
+
* those beyond minEntries).
|
|
824
|
+
*/
|
|
685
825
|
static isNumberArray(json, minEntries = 0) {
|
|
686
826
|
if (Array.isArray(json) && json.length >= minEntries) {
|
|
687
827
|
let entry;
|
|
688
828
|
for (entry of json) {
|
|
689
|
-
// if (!(entry as number) && entry !== 0.0)
|
|
690
829
|
if (!Number.isFinite(entry))
|
|
691
830
|
return false;
|
|
692
831
|
}
|
|
@@ -694,10 +833,12 @@ class Geometry {
|
|
|
694
833
|
}
|
|
695
834
|
return false;
|
|
696
835
|
}
|
|
697
|
-
/**
|
|
836
|
+
/**
|
|
837
|
+
* Return `true` if `json` is an array of at least `minArrays` arrays with at least `minEntries` entries in
|
|
838
|
+
* each array and all entries are numbers (including those beyond minEntries).
|
|
698
839
|
*/
|
|
699
|
-
static isArrayOfNumberArray(json,
|
|
700
|
-
if (Array.isArray(json) && json.length >=
|
|
840
|
+
static isArrayOfNumberArray(json, minArrays, minEntries = 0) {
|
|
841
|
+
if (Array.isArray(json) && json.length >= minArrays) {
|
|
701
842
|
let entry;
|
|
702
843
|
for (entry of json)
|
|
703
844
|
if (!Geometry.isNumberArray(entry, minEntries))
|
|
@@ -706,36 +847,53 @@ class Geometry {
|
|
|
706
847
|
}
|
|
707
848
|
return false;
|
|
708
849
|
}
|
|
709
|
-
/**
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
|
|
850
|
+
/**
|
|
851
|
+
* Return the number of steps to take so that `numSteps * stepSize >= total`.
|
|
852
|
+
* * `minCount` is returned in the following 3 cases:
|
|
853
|
+
* * (a) `stepSize <= 0`
|
|
854
|
+
* * (b) `stepSize >= total`
|
|
855
|
+
* * (b) `numSteps < minCount`
|
|
856
|
+
* * `maxCount` is returned if `numSteps > maxCount`.
|
|
857
|
+
*/
|
|
713
858
|
static stepCount(stepSize, total, minCount = 1, maxCount = 101) {
|
|
714
859
|
if (stepSize <= 0)
|
|
715
860
|
return minCount;
|
|
716
861
|
total = Math.abs(total);
|
|
717
862
|
if (stepSize >= total)
|
|
718
863
|
return minCount;
|
|
719
|
-
|
|
720
|
-
|
|
864
|
+
/**
|
|
865
|
+
* 0.999999 is multiplied so we return the same "numSteps" if
|
|
866
|
+
* stepSize*(numSteps-1) < total <= stepSize*numSteps.
|
|
867
|
+
* For example, if "stepSize = 2" then we return "numSteps = 5" if 8 < total <= 10.
|
|
868
|
+
*/
|
|
869
|
+
const numSteps = Math.floor((total + 0.999999 * stepSize) / stepSize);
|
|
870
|
+
if (numSteps < minCount)
|
|
721
871
|
return minCount;
|
|
722
|
-
if (
|
|
872
|
+
if (numSteps > maxCount)
|
|
723
873
|
return maxCount;
|
|
724
|
-
return
|
|
874
|
+
return numSteps;
|
|
725
875
|
}
|
|
726
|
-
/**
|
|
876
|
+
/**
|
|
877
|
+
* Test if `x` is in the interval [0,1] (but skip the test if `apply01 = false`).
|
|
878
|
+
* * This odd behavior is very convenient for code that sometimes does not do the filtering.
|
|
727
879
|
* @param x value to test.
|
|
728
|
-
* @param apply01 if false,
|
|
880
|
+
* @param apply01 if false, return `true` for all values of `x`.
|
|
729
881
|
*/
|
|
730
|
-
static isIn01(x, apply01 = true) {
|
|
731
|
-
|
|
882
|
+
static isIn01(x, apply01 = true) {
|
|
883
|
+
return apply01 ? x >= 0.0 && x <= 1.0 : true;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* Test if `x` is in the interval [0,1] for a given positive `tolerance`.
|
|
887
|
+
* * Make sure to pass a positive `tolerance` because there is no check for that in the code.
|
|
732
888
|
* @param x value to test.
|
|
733
|
-
* @param
|
|
889
|
+
* @param tolerance the tolerance.
|
|
734
890
|
*/
|
|
735
|
-
static isIn01WithTolerance(x, tolerance) {
|
|
891
|
+
static isIn01WithTolerance(x, tolerance) {
|
|
892
|
+
return x + tolerance >= 0.0 && x - tolerance <= 1.0;
|
|
893
|
+
}
|
|
736
894
|
/**
|
|
737
|
-
*
|
|
738
|
-
* @param x
|
|
895
|
+
* Restrict x so it is in the interval `[a,b]` (allowing `a` and `b` to be in either order).
|
|
896
|
+
* @param x value to restrict
|
|
739
897
|
* @param a (usually the lower) interval limit
|
|
740
898
|
* @param b (usually the upper) interval limit
|
|
741
899
|
*/
|
|
@@ -747,7 +905,7 @@ class Geometry {
|
|
|
747
905
|
return b;
|
|
748
906
|
return x;
|
|
749
907
|
}
|
|
750
|
-
// reversed interval
|
|
908
|
+
// reversed interval
|
|
751
909
|
if (x < b)
|
|
752
910
|
return b;
|
|
753
911
|
if (x > a)
|
|
@@ -756,12 +914,15 @@ class Geometry {
|
|
|
756
914
|
}
|
|
757
915
|
/**
|
|
758
916
|
* Case-insensitive string comparison.
|
|
759
|
-
* * Return true if the toUpperCase values match.
|
|
917
|
+
* * Return `true` if the `toUpperCase` values of `string1` and `string2` match.
|
|
760
918
|
*/
|
|
761
919
|
static equalStringNoCase(string1, string2) {
|
|
762
920
|
return string1.toUpperCase() === string2.toUpperCase();
|
|
763
921
|
}
|
|
764
|
-
/**
|
|
922
|
+
/**
|
|
923
|
+
* Test for exact match of two number arrays.
|
|
924
|
+
* Returns `true` if both arrays have the same length and entries, or if both arrays are empty or `undefined`.
|
|
925
|
+
*/
|
|
765
926
|
static exactEqualNumberArrays(a, b) {
|
|
766
927
|
if (Array.isArray(a) && a.length === 0)
|
|
767
928
|
a = undefined;
|
|
@@ -779,7 +940,10 @@ class Geometry {
|
|
|
779
940
|
}
|
|
780
941
|
return false;
|
|
781
942
|
}
|
|
782
|
-
/**
|
|
943
|
+
/**
|
|
944
|
+
* Test for match of two arrays of type `T`.
|
|
945
|
+
* Returns `true` if both arrays have the same length and have the same entries (or both are empty arrays).
|
|
946
|
+
*/
|
|
783
947
|
static almostEqualArrays(a, b, testFunction) {
|
|
784
948
|
if (Array.isArray(a) && a.length === 0)
|
|
785
949
|
a = undefined;
|
|
@@ -798,7 +962,10 @@ class Geometry {
|
|
|
798
962
|
}
|
|
799
963
|
return false;
|
|
800
964
|
}
|
|
801
|
-
/**
|
|
965
|
+
/**
|
|
966
|
+
* Test for match of two arrays of type number or Float64Array.
|
|
967
|
+
* Returns `true` if both arrays have the same length and have the same entries (or both are empty arrays).
|
|
968
|
+
*/
|
|
802
969
|
static almostEqualNumberArrays(a, b, testFunction) {
|
|
803
970
|
if (Array.isArray(a) && a.length === 0)
|
|
804
971
|
a = undefined;
|
|
@@ -818,15 +985,12 @@ class Geometry {
|
|
|
818
985
|
return false;
|
|
819
986
|
}
|
|
820
987
|
/**
|
|
821
|
-
*
|
|
822
|
-
* * true if both values are defined and equal (with ===).
|
|
823
|
-
* * false if both defined by not equal
|
|
824
|
-
* * return (option arg) resultIfBothUndefined when both are undefined.
|
|
825
|
-
* * return false if one is defined and the other undefined
|
|
988
|
+
* Test for match of two values of type `T`.
|
|
826
989
|
* @param a first value
|
|
827
990
|
* @param b second value
|
|
828
|
-
* @param resultIfBothUndefined
|
|
829
|
-
* @returns
|
|
991
|
+
* @param resultIfBothUndefined returned value when both are `undefined`
|
|
992
|
+
* @returns `true` if both values are defined and equal (with ===) and `false` if both values are defined
|
|
993
|
+
* but not equal or if one is defined and the other undefined.
|
|
830
994
|
*/
|
|
831
995
|
static areEqualAllowUndefined(a, b, resultIfBothUndefined = true) {
|
|
832
996
|
if (a === undefined && b === undefined)
|
|
@@ -835,46 +999,52 @@ class Geometry {
|
|
|
835
999
|
return a === b;
|
|
836
1000
|
return false;
|
|
837
1001
|
}
|
|
838
|
-
/**
|
|
839
|
-
*
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1002
|
+
/**
|
|
1003
|
+
* Clone an array whose members have type `T`, which implements the clone method.
|
|
1004
|
+
* * If the clone method returns `undefined`, then `undefined` is forced into the cloned array.
|
|
1005
|
+
*/
|
|
1006
|
+
static cloneMembers(array) {
|
|
1007
|
+
if (array === undefined)
|
|
843
1008
|
return undefined;
|
|
844
|
-
const
|
|
845
|
-
for (const
|
|
846
|
-
|
|
1009
|
+
const clonedArray = [];
|
|
1010
|
+
for (const element of array) {
|
|
1011
|
+
clonedArray.push(element.clone());
|
|
847
1012
|
}
|
|
848
|
-
return
|
|
1013
|
+
return clonedArray;
|
|
849
1014
|
}
|
|
850
1015
|
}
|
|
851
|
-
/** Tolerance for small distances in metric coordinates */
|
|
1016
|
+
/** Tolerance for small distances in metric coordinates. */
|
|
852
1017
|
Geometry.smallMetricDistance = 1.0e-6;
|
|
853
|
-
/** Square of `
|
|
1018
|
+
/** Square of `smallMetricDistance`. */
|
|
854
1019
|
Geometry.smallMetricDistanceSquared = 1.0e-12;
|
|
855
|
-
/**
|
|
1020
|
+
/** Tolerance for small angle measured in radians. */
|
|
856
1021
|
Geometry.smallAngleRadians = 1.0e-12;
|
|
857
|
-
/**
|
|
1022
|
+
/** Square of `smallAngleRadians`. */
|
|
858
1023
|
Geometry.smallAngleRadiansSquared = 1.0e-24;
|
|
859
|
-
/**
|
|
1024
|
+
/** Tolerance for small angle measured in degrees. */
|
|
860
1025
|
Geometry.smallAngleDegrees = 5.7e-11;
|
|
861
|
-
/**
|
|
1026
|
+
/** Tolerance for small angle measured in arc-seconds. */
|
|
862
1027
|
Geometry.smallAngleSeconds = 2e-7;
|
|
863
|
-
/**
|
|
864
|
-
|
|
1028
|
+
/** Numeric value that may be considered zero for fractions between 0 and 1. */
|
|
1029
|
+
Geometry.smallFraction = 1.0e-10;
|
|
1030
|
+
/** Radians value for full circle 2PI radians minus `smallAngleRadians`. */
|
|
1031
|
+
Geometry.fullCircleRadiansMinusSmallAngle = 2.0 * Math.PI - Geometry.smallAngleRadians;
|
|
1032
|
+
/**
|
|
1033
|
+
* Numeric value that may be considered large for a ratio of numbers.
|
|
1034
|
+
* * Note that the allowed result value is vastly larger than 1.
|
|
865
1035
|
*/
|
|
866
1036
|
Geometry.largeFractionResult = 1.0e10;
|
|
867
|
-
/**
|
|
868
|
-
|
|
869
|
-
/** numeric value that may considered huge for numbers expected to be coordinates.
|
|
1037
|
+
/**
|
|
1038
|
+
* Numeric value that may considered large for numbers expected to be coordinates.
|
|
870
1039
|
* * This allows larger results than `largeFractionResult`.
|
|
871
1040
|
*/
|
|
872
1041
|
Geometry.largeCoordinateResult = 1.0e13;
|
|
873
|
-
/**
|
|
874
|
-
*
|
|
1042
|
+
/**
|
|
1043
|
+
* Numeric value that may considered infinite for metric coordinates.
|
|
1044
|
+
* @deprecated in 4.x. Use `largeCoordinateResult`.
|
|
1045
|
+
* * This coordinate should be used only as a placeholder indicating "at infinity" -- computing actual
|
|
1046
|
+
* points at this coordinate invites numerical problems.
|
|
875
1047
|
*/
|
|
876
1048
|
Geometry.hugeCoordinate = 1.0e12;
|
|
877
|
-
/** Radians value for full circle 2PI radians minus `smallAngleRadians` */
|
|
878
|
-
Geometry.fullCircleRadiansMinusSmallAngle = 2.0 * Math.PI - 1.0e-12; // smallAngleRadians less than 360degrees
|
|
879
1049
|
exports.Geometry = Geometry;
|
|
880
1050
|
//# sourceMappingURL=Geometry.js.map
|