@itwin/core-geometry 4.2.0-dev.32 → 4.2.0-dev.34
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 +6 -1
- package/lib/cjs/curve/CurveCurve.d.ts +13 -11
- package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCurve.js +14 -12
- package/lib/cjs/curve/CurveCurve.js.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.d.ts +6 -5
- package/lib/cjs/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.js +2 -1
- package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts +31 -24
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +85 -83
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.d.ts +8 -7
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js +123 -95
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
- package/lib/cjs/geometry4d/Map4d.d.ts +14 -8
- package/lib/cjs/geometry4d/Map4d.d.ts.map +1 -1
- package/lib/cjs/geometry4d/Map4d.js +38 -16
- package/lib/cjs/geometry4d/Map4d.js.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/cjs/polyface/PolyfaceBuilder.js +7 -10
- package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
- package/lib/esm/curve/CurveCurve.d.ts +13 -11
- package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
- package/lib/esm/curve/CurveCurve.js +14 -12
- package/lib/esm/curve/CurveCurve.js.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.d.ts +6 -5
- package/lib/esm/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.js +2 -1
- package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts +31 -24
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +85 -83
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.d.ts +8 -7
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js +124 -96
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -1
- package/lib/esm/geometry4d/Map4d.d.ts +14 -8
- package/lib/esm/geometry4d/Map4d.d.ts.map +1 -1
- package/lib/esm/geometry4d/Map4d.js +38 -16
- package/lib/esm/geometry4d/Map4d.js.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
- package/lib/esm/polyface/PolyfaceBuilder.js +7 -10
- package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
- package/package.json +3 -3
|
@@ -27,9 +27,6 @@ const LineString3d_1 = require("../LineString3d");
|
|
|
27
27
|
* @internal
|
|
28
28
|
*/
|
|
29
29
|
class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
30
|
-
reinitialize() {
|
|
31
|
-
this._results = new CurveLocationDetail_1.CurveLocationDetailArrayPair();
|
|
32
|
-
}
|
|
33
30
|
/**
|
|
34
31
|
* @param extendA flag to enable using extension of the other geometry.
|
|
35
32
|
* @param geometryB second curve for intersection. Saved for reference by specific handler methods.
|
|
@@ -40,16 +37,16 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
40
37
|
this._extendA = extendA;
|
|
41
38
|
this._geometryB = geometryB;
|
|
42
39
|
this._extendB = extendB;
|
|
43
|
-
this.
|
|
40
|
+
this._results = [];
|
|
44
41
|
}
|
|
45
42
|
/**
|
|
46
|
-
*
|
|
43
|
+
* Return the results structure for the intersection calculation, structured as an array of CurveLocationDetailPair.
|
|
47
44
|
* @param reinitialize if true, a new results structure is created for use by later calls.
|
|
48
45
|
*/
|
|
49
|
-
|
|
46
|
+
grabPairedResults(reinitialize = false) {
|
|
50
47
|
const result = this._results;
|
|
51
48
|
if (reinitialize)
|
|
52
|
-
this.
|
|
49
|
+
this._results = [];
|
|
53
50
|
return result;
|
|
54
51
|
}
|
|
55
52
|
acceptFraction(extend0, fraction, extend1) {
|
|
@@ -65,15 +62,14 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
65
62
|
* Reject if evaluated points do not match coordinates (e.g. close approach point).
|
|
66
63
|
* Record with fraction mapping.
|
|
67
64
|
*/
|
|
68
|
-
recordPointWithLocalFractions(localFractionA, cpA, fractionA0, fractionA1, localFractionB,
|
|
69
|
-
cpB, fractionB0, fractionB1, reversed) {
|
|
65
|
+
recordPointWithLocalFractions(localFractionA, cpA, fractionA0, fractionA1, localFractionB, cpB, fractionB0, fractionB1, reversed) {
|
|
70
66
|
const globalFractionA = Geometry_1.Geometry.interpolate(fractionA0, localFractionA, fractionA1);
|
|
71
67
|
const globalFractionB = Geometry_1.Geometry.interpolate(fractionB0, localFractionB, fractionB1);
|
|
72
68
|
// ignore duplicate of most recent point . ..
|
|
73
|
-
const numPrevious = this._results.
|
|
69
|
+
const numPrevious = this._results.length;
|
|
74
70
|
if (numPrevious > 0) {
|
|
75
|
-
const topFractionA = this._results
|
|
76
|
-
const topFractionB = this._results
|
|
71
|
+
const topFractionA = this._results[numPrevious - 1].detailA.fraction;
|
|
72
|
+
const topFractionB = this._results[numPrevious - 1].detailB.fraction;
|
|
77
73
|
if (reversed) {
|
|
78
74
|
if (Geometry_1.Geometry.isAlmostEqualNumber(topFractionA, globalFractionB) &&
|
|
79
75
|
Geometry_1.Geometry.isAlmostEqualNumber(topFractionB, globalFractionA))
|
|
@@ -94,12 +90,12 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
94
90
|
const detailB = CurveLocationDetail_1.CurveLocationDetail.createCurveFractionPoint(cpB, globalFractionB, pointB);
|
|
95
91
|
detailB.setIntervalRole(CurveLocationDetail_1.CurveIntervalRole.isolated);
|
|
96
92
|
if (reversed) {
|
|
97
|
-
|
|
98
|
-
this._results.
|
|
93
|
+
const pair = new CurveLocationDetail_1.CurveLocationDetailPair(detailB, detailA);
|
|
94
|
+
this._results.push(pair);
|
|
99
95
|
}
|
|
100
96
|
else {
|
|
101
|
-
|
|
102
|
-
this._results.
|
|
97
|
+
const pair = new CurveLocationDetail_1.CurveLocationDetailPair(detailA, detailB);
|
|
98
|
+
this._results.push(pair);
|
|
103
99
|
}
|
|
104
100
|
}
|
|
105
101
|
/**
|
|
@@ -115,8 +111,8 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
115
111
|
}
|
|
116
112
|
}
|
|
117
113
|
// Caller accesses data from a line segment and passes to here.
|
|
118
|
-
//
|
|
119
|
-
// allow all combinations to be passed in
|
|
114
|
+
// The line segment in question might be (a) a full line segment or (b) a fragment within a linestring.
|
|
115
|
+
// The fraction and extend parameters allow all combinations to be passed in.
|
|
120
116
|
// This method applies transform.
|
|
121
117
|
dispatchSegmentSegment(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, cpB, extendB0, pointB0, fractionB0, pointB1, fractionB1, extendB1, reversed) {
|
|
122
118
|
this.computeSegmentSegment3D(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, cpB, extendB0, pointB0, fractionB0, pointB1, fractionB1, extendB1, reversed);
|
|
@@ -131,7 +127,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
131
127
|
* @param origin plane origin
|
|
132
128
|
* @param vectorA vector which must be in the plane.
|
|
133
129
|
* @param cosineValue largest cosine of the angle theta between vectorA and vectorB to prefer their cross product, e.g.
|
|
134
|
-
*
|
|
130
|
+
* passing 0.94 ~ cos(20deg) will switch to using vectorC in the cross product if theta < ~20deg or theta > ~160deg.
|
|
135
131
|
* @param vectorB first candidate for additional in-plane vector
|
|
136
132
|
* @param vectorC second candidate for additional in-plane vector
|
|
137
133
|
*/
|
|
@@ -146,8 +142,8 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
146
142
|
return undefined;
|
|
147
143
|
}
|
|
148
144
|
// Caller accesses data from a linestring or segment and passes it here.
|
|
149
|
-
//
|
|
150
|
-
// allow all combinations to be passed in
|
|
145
|
+
// The line segment in question might be (a) a full line segment or (b) a fragment within a linestring.
|
|
146
|
+
// The fraction and extend parameters allow all combinations to be passed in.
|
|
151
147
|
dispatchSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
152
148
|
const lineVector = Point3dVector3d_1.Vector3d.createStartEnd(pointA0, pointA1);
|
|
153
149
|
const plane = this.createPlaneWithPreferredPerpendicular(pointA0, lineVector, 0.94, arc.perpendicularVector, arc.vector0);
|
|
@@ -182,7 +178,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
182
178
|
Polynomials_1.TrigPolynomial.solveUnitCircleHomogeneousEllipseIntersection(otherVectors.center.x, otherVectors.center.y, 1.0, otherVectors.vector0.x, otherVectors.vector0.y, 0.0, otherVectors.vector90.x, otherVectors.vector90.y, 0.0, ellipseRadians, circleRadians);
|
|
183
179
|
for (let i = 0; i < ellipseRadians.length; i++) {
|
|
184
180
|
const fractionA = cpA.sweep.radiansToSignedPeriodicFraction(circleRadians[i]);
|
|
185
|
-
const fractionB =
|
|
181
|
+
const fractionB = cpB.sweep.radiansToSignedPeriodicFraction(ellipseRadians[i]);
|
|
186
182
|
// hm .. do we really need to check the fractions? We know they are internal to the beziers
|
|
187
183
|
if (this.acceptFraction(extendA, fractionA, extendA) && this.acceptFraction(extendB, fractionB, extendB)) {
|
|
188
184
|
this.recordPointWithLocalFractions(fractionA, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
@@ -191,13 +187,13 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
189
|
// Caller accesses data from two arcs.
|
|
194
|
-
// Selects the best conditioned arc (in xy parts) as "circle after inversion"
|
|
195
|
-
// Solves the arc-arc equations
|
|
190
|
+
// Selects the best conditioned arc (in xy parts) as "circle after inversion".
|
|
191
|
+
// Solves the arc-arc equations.
|
|
196
192
|
dispatchArcArc(cpA, extendA, cpB, extendB, reversed) {
|
|
197
193
|
// If arcs are in different planes:
|
|
198
194
|
// 1) Intersect each plane with the other arc (quadratic)
|
|
199
195
|
// 2) accept points that appear in both intersection sets.
|
|
200
|
-
// If arcs are in parallel planes -- no intersections
|
|
196
|
+
// If arcs are in parallel planes -- no intersections.
|
|
201
197
|
// If arcs are in the same plane -- xy intersection in that plane.
|
|
202
198
|
const planeA = Plane3dByOriginAndUnitNormal_1.Plane3dByOriginAndUnitNormal.create(cpA.center, cpA.perpendicularVector);
|
|
203
199
|
const planeB = Plane3dByOriginAndUnitNormal_1.Plane3dByOriginAndUnitNormal.create(cpB.center, cpB.perpendicularVector);
|
|
@@ -205,7 +201,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
205
201
|
return;
|
|
206
202
|
if (planeA.getNormalRef().isParallelTo(planeB.getNormalRef())) {
|
|
207
203
|
if (planeA.isPointInPlane(planeB.getOriginRef()) && planeB.isPointInPlane(planeA.getOriginRef())) {
|
|
208
|
-
// coplanar
|
|
204
|
+
// coplanar
|
|
209
205
|
this.dispatchArcArcInPlane(cpA, extendA, cpB, extendB, reversed);
|
|
210
206
|
}
|
|
211
207
|
}
|
|
@@ -227,8 +223,8 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
227
223
|
}
|
|
228
224
|
}
|
|
229
225
|
// Caller accesses data from two arcs.
|
|
230
|
-
// Selects the best conditioned arc (in xy parts) as "circle after inversion"
|
|
231
|
-
// Solves the arc-arc equations
|
|
226
|
+
// Selects the best conditioned arc (in xy parts) as "circle after inversion".
|
|
227
|
+
// Solves the arc-arc equations.
|
|
232
228
|
dispatchArcBsplineCurve3d(_arc, _extendA, _cpB, _extendB, _reversed) {
|
|
233
229
|
/*
|
|
234
230
|
// Arc: X = C + cU + sV
|
|
@@ -236,7 +232,9 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
236
232
|
let matrixA: Matrix3d;
|
|
237
233
|
if (this._worldToLocalPerspective) {
|
|
238
234
|
const dataA = cpA.toTransformedPoint4d(this._worldToLocalPerspective);
|
|
239
|
-
matrixA = Matrix3d.createColumnsXYW(
|
|
235
|
+
matrixA = Matrix3d.createColumnsXYW(
|
|
236
|
+
dataA.vector0, dataA.vector0.w, dataA.vector90, dataA.vector90.w, dataA.center, dataA.center.w,
|
|
237
|
+
);
|
|
240
238
|
} else {
|
|
241
239
|
const dataA = cpA.toTransformedVectors(this._worldToLocalAffine);
|
|
242
240
|
matrixA = Matrix3d.createColumnsXYW(dataA.vector0, 0, dataA.vector90, 0, dataA.center, 1);
|
|
@@ -248,12 +246,21 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
248
246
|
const matrixAInverse = matrixA.inverse();
|
|
249
247
|
if (matrixAInverse) {
|
|
250
248
|
const orderF = cpB.order; // order of the beziers for simple coordinates
|
|
251
|
-
const orderG = 2 * orderF - 1;
|
|
249
|
+
const orderG = 2 * orderF - 1; // order of the (single) bezier for squared coordinates.
|
|
252
250
|
const coffF = new Float64Array(orderF);
|
|
253
251
|
const univariateBezierG = new UnivariateBezier(orderG);
|
|
254
|
-
const axx = matrixAInverse.at(0, 0);
|
|
255
|
-
const
|
|
256
|
-
const
|
|
252
|
+
const axx = matrixAInverse.at(0, 0);
|
|
253
|
+
const axy = matrixAInverse.at(0, 1);
|
|
254
|
+
const axz = 0.0;
|
|
255
|
+
const axw = matrixAInverse.at(0, 2);
|
|
256
|
+
const ayx = matrixAInverse.at(1, 0);
|
|
257
|
+
const ayy = matrixAInverse.at(1, 1);
|
|
258
|
+
const ayz = 0.0;
|
|
259
|
+
const ayw = matrixAInverse.at(1, 2);
|
|
260
|
+
const awx = matrixAInverse.at(2, 0);
|
|
261
|
+
const awy = matrixAInverse.at(2, 1);
|
|
262
|
+
const awz = 0.0;
|
|
263
|
+
const aww = matrixAInverse.at(2, 2);
|
|
257
264
|
|
|
258
265
|
if (matrixAInverse) {
|
|
259
266
|
let bezier: BezierCurve3dH | undefined;
|
|
@@ -280,9 +287,11 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
280
287
|
const c = bcurvePoint4d.dotProductXYZW(axx, axy, axz, axw);
|
|
281
288
|
const s = bcurvePoint4d.dotProductXYZW(ayx, ayy, ayz, ayw);
|
|
282
289
|
const arcFraction = cpA.sweep.radiansToSignedPeriodicFraction(Math.atan2(s, c));
|
|
283
|
-
if (this.acceptFraction(extendA, arcFraction, extendA) &&
|
|
284
|
-
this.
|
|
285
|
-
|
|
290
|
+
if (this.acceptFraction(extendA, arcFraction, extendA) &&
|
|
291
|
+
this.acceptFraction(extendB, fractionB, extendB)) {
|
|
292
|
+
this.recordPointWithLocalFractions(
|
|
293
|
+
arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed,
|
|
294
|
+
);
|
|
286
295
|
}
|
|
287
296
|
}
|
|
288
297
|
}
|
|
@@ -292,8 +301,8 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
292
301
|
*/
|
|
293
302
|
}
|
|
294
303
|
/*
|
|
295
|
-
//
|
|
296
|
-
private transformBeziers(beziers: BezierCurve3dH[]) {
|
|
304
|
+
// Apply the transformation to bezier curves. Optionally construct ranges.
|
|
305
|
+
private transformBeziers(beziers: BezierCurve3dH[]): void {
|
|
297
306
|
if (this._worldToLocalAffine) {
|
|
298
307
|
for (const bezier of beziers) bezier.tryTransformInPlace(this._worldToLocalAffine);
|
|
299
308
|
} else if (this._worldToLocalPerspective) {
|
|
@@ -310,11 +319,6 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
310
319
|
}
|
|
311
320
|
return ranges;
|
|
312
321
|
}
|
|
313
|
-
private _xyzwA0?: Point4d;
|
|
314
|
-
private _xyzwA1?: Point4d;
|
|
315
|
-
private _xyzwPlane?: Point4d;
|
|
316
|
-
private _xyzwB?: Point4d;
|
|
317
|
-
|
|
318
322
|
private dispatchBezierBezierStrokeFirst(
|
|
319
323
|
bezierA: BezierCurve3dH,
|
|
320
324
|
bcurveA: BSplineCurve3dBase,
|
|
@@ -323,11 +327,16 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
323
327
|
bcurveB: BSplineCurve3dBase,
|
|
324
328
|
_strokeCountB: number,
|
|
325
329
|
univariateBezierB: UnivariateBezier, // caller-allocated for univariate coefficients.
|
|
326
|
-
reversed: boolean
|
|
327
|
-
|
|
328
|
-
if (!this.
|
|
329
|
-
|
|
330
|
-
if (!this.
|
|
330
|
+
reversed: boolean,
|
|
331
|
+
) {
|
|
332
|
+
if (!this._xyzwA0)
|
|
333
|
+
this._xyzwA0 = Point4d.create();
|
|
334
|
+
if (!this._xyzwA1)
|
|
335
|
+
this._xyzwA1 = Point4d.create();
|
|
336
|
+
if (!this._xyzwPlane)
|
|
337
|
+
this._xyzwPlane = Point4d.create();
|
|
338
|
+
if (!this._xyzwB)
|
|
339
|
+
this._xyzwB = Point4d.create();
|
|
331
340
|
const roots = univariateBezierG.roots(0.0, true);
|
|
332
341
|
if (roots) {
|
|
333
342
|
for (const root of roots) {
|
|
@@ -338,8 +347,9 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
338
347
|
const s = bcurvePoint4d.dotProductXYZW(ayx, ayy, ayz, ayw);
|
|
339
348
|
const arcFraction = cpA.sweep.radiansToSignedPeriodicFraction(Math.atan2(s, c));
|
|
340
349
|
if (this.acceptFraction(extendA, arcFraction, extendA) && this.acceptFraction(extendB, fractionB, extendB)) {
|
|
341
|
-
this.recordPointWithLocalFractions(
|
|
342
|
-
fractionB, cpB, 0, 1, reversed
|
|
350
|
+
this.recordPointWithLocalFractions(
|
|
351
|
+
arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed,
|
|
352
|
+
);
|
|
343
353
|
}
|
|
344
354
|
}
|
|
345
355
|
bezierA.fractionToPoint4d(0.0, this._xyzwA0);
|
|
@@ -351,7 +361,9 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
351
361
|
f1 = i * df;
|
|
352
362
|
bezierA.fractionToPoint4d(f1, this._xyzwA1);
|
|
353
363
|
Point4d.createPlanePointPointZ(this._xyzwA0, this._xyzwA1, this._xyzwPlane);
|
|
354
|
-
bezierB.poleProductsXYZW(
|
|
364
|
+
bezierB.poleProductsXYZW(
|
|
365
|
+
univariateBezierB.coffs, this._xyzwPlane.x, this._xyzwPlane.y, this._xyzwPlane.z, this._xyzwPlane.w,
|
|
366
|
+
);
|
|
355
367
|
let errors = 0;
|
|
356
368
|
const roots = univariateBezierB.roots(0.0, true);
|
|
357
369
|
if (roots)
|
|
@@ -361,7 +373,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
361
373
|
const segmentAFraction = SmallSystem.lineSegment3dHXYClosestPointUnbounded(this._xyzwA0, this._xyzwA1, this._xyzwB);
|
|
362
374
|
if (segmentAFraction && Geometry.isIn01WithTolerance(segmentAFraction, intervalTolerance)) {
|
|
363
375
|
const bezierAFraction = Geometry.interpolate(f0, segmentAFraction, f1);
|
|
364
|
-
|
|
376
|
+
// TODO implement newton search
|
|
365
377
|
const xyMatchingFunction = new BezierBezierIntersectionXYRRToRRD(bezierA, bezierB);
|
|
366
378
|
const newtonSearcher = new Newton2dUnboundedWithDerivative(xyMatchingFunction);
|
|
367
379
|
newtonSearcher.setUV(bezierAFraction, bezierBFraction);
|
|
@@ -386,9 +398,11 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
386
398
|
errors++;
|
|
387
399
|
if (errors > 0 && !xyzA1.isAlmostEqual(xyzB1))
|
|
388
400
|
errors++;
|
|
389
|
-
if (this.acceptFraction(false, bcurveAFraction, false) &&
|
|
390
|
-
this.
|
|
391
|
-
|
|
401
|
+
if (this.acceptFraction(false, bcurveAFraction, false) &&
|
|
402
|
+
this.acceptFraction(false, bcurveBFraction, false)) {
|
|
403
|
+
this.recordPointWithLocalFractions(
|
|
404
|
+
bcurveAFraction, bcurveA, 0, 1, bcurveBFraction, bcurveB, 0, 1, reversed,
|
|
405
|
+
);
|
|
392
406
|
}
|
|
393
407
|
}
|
|
394
408
|
}
|
|
@@ -396,8 +410,8 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
396
410
|
}
|
|
397
411
|
*/
|
|
398
412
|
// Caller accesses data from two arcs.
|
|
399
|
-
// Selects the best conditioned arc (in xy parts) as "circle after inversion"
|
|
400
|
-
// Solves the arc-arc equations
|
|
413
|
+
// Selects the best conditioned arc (in xy parts) as "circle after inversion".
|
|
414
|
+
// Solves the arc-arc equations.
|
|
401
415
|
dispatchBSplineCurve3dBSplineCurve3d(_bcurveA, _bcurveB, _reversed) {
|
|
402
416
|
/*
|
|
403
417
|
const bezierSpanA = bcurveA.collectBezierSpans(true) as BezierCurve3dH[];
|
|
@@ -418,9 +432,13 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
418
432
|
const strokeCountA = bezierSpanA[a].computeStrokeCountForOptions();
|
|
419
433
|
const strokeCountB = bezierSpanB[b].computeStrokeCountForOptions();
|
|
420
434
|
if (strokeCountA < strokeCountB)
|
|
421
|
-
this.dispatchBezierBezierStrokeFirst(
|
|
435
|
+
this.dispatchBezierBezierStrokeFirst(
|
|
436
|
+
bezierSpanA[a], bcurveA, strokeCountA, bezierSpanB[b], bcurveB, strokeCountB, univariateCoffsB, _reversed,
|
|
437
|
+
);
|
|
422
438
|
else
|
|
423
|
-
this.dispatchBezierBezierStrokeFirst(
|
|
439
|
+
this.dispatchBezierBezierStrokeFirst(
|
|
440
|
+
bezierSpanB[b], bcurveB, strokeCountB, bezierSpanA[a], bcurveA, strokeCountA, univariateCoffsA, !_reversed,
|
|
441
|
+
);
|
|
424
442
|
}
|
|
425
443
|
}
|
|
426
444
|
}
|
|
@@ -428,9 +446,9 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
428
446
|
}
|
|
429
447
|
/*
|
|
430
448
|
/**
|
|
431
|
-
* Apply the projection transform (if any) to (xyz, w)
|
|
449
|
+
* Apply the projection transform (if any) to (xyz, w).
|
|
432
450
|
* @param xyz xyz parts of input point.
|
|
433
|
-
* @param w
|
|
451
|
+
* @param w weight to use for homogeneous effects.
|
|
434
452
|
*/
|
|
435
453
|
/*
|
|
436
454
|
private projectPoint(xyz: XYAndZ, w: number = 1.0): Point4d {
|
|
@@ -467,16 +485,19 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
467
485
|
// NOW .. we have a plane in world space. Intersect it with the bspline:
|
|
468
486
|
const intersections: CurveLocationDetail[] = [];
|
|
469
487
|
bcurve.appendPlaneIntersectionPoints(planeCoffs, intersections);
|
|
470
|
-
// intersections has WORLD points with bspline fractions.
|
|
488
|
+
// intersections has WORLD points with bspline fractions.
|
|
489
|
+
// (the bspline fractions are all good 0..1 fractions within the spline).
|
|
471
490
|
// accept those that are within the segment range.
|
|
472
491
|
for (const detail of intersections) {
|
|
473
492
|
const fractionB = detail.fraction;
|
|
474
493
|
const curvePoint = detail.point;
|
|
475
494
|
const curvePointH = this.projectPoint(curvePoint);
|
|
476
495
|
const lineFraction = SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, curvePointH);
|
|
477
|
-
if (lineFraction !== undefined && this.acceptFraction(extendA0, lineFraction, extendA1) &&
|
|
478
|
-
this.
|
|
479
|
-
|
|
496
|
+
if (lineFraction !== undefined && this.acceptFraction(extendA0, lineFraction, extendA1) &&
|
|
497
|
+
this.acceptFraction(extendB, fractionB, extendB)) {
|
|
498
|
+
this.recordPointWithLocalFractions(
|
|
499
|
+
lineFraction, cpA, fractionA0, fractionA1, fractionB, bcurve, 0, 1, reversed,
|
|
500
|
+
);
|
|
480
501
|
}
|
|
481
502
|
}
|
|
482
503
|
*/
|
|
@@ -493,7 +514,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
493
514
|
const pointA0 = CurveCurveIntersectXYZ._workPointA0;
|
|
494
515
|
const pointA1 = CurveCurveIntersectXYZ._workPointA1;
|
|
495
516
|
lsA.pointAt(0, pointA0);
|
|
496
|
-
for (let iA = 1; iA < numA; iA
|
|
517
|
+
for (let iA = 1; iA < numA; iA++, pointA0.setFrom(pointA1), fA0 = fA1) {
|
|
497
518
|
lsA.pointAt(iA, pointA1);
|
|
498
519
|
fA1 = iA * dfA;
|
|
499
520
|
this.dispatchSegmentBsplineCurve(
|
|
@@ -544,6 +565,38 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
544
565
|
}
|
|
545
566
|
return undefined;
|
|
546
567
|
}
|
|
568
|
+
/** Detail computation for linestring intersecting linestring. */
|
|
569
|
+
computeLineStringLineString(lsA, lsB, reversed) {
|
|
570
|
+
const pointA0 = CurveCurveIntersectXYZ._workPointAA0;
|
|
571
|
+
const pointA1 = CurveCurveIntersectXYZ._workPointAA1;
|
|
572
|
+
const pointB0 = CurveCurveIntersectXYZ._workPointBB0;
|
|
573
|
+
const pointB1 = CurveCurveIntersectXYZ._workPointBB1;
|
|
574
|
+
const numA = lsA.numPoints();
|
|
575
|
+
const numB = lsB.numPoints();
|
|
576
|
+
if (numA > 1 && numB > 1) {
|
|
577
|
+
lsA.pointAt(0, pointA0);
|
|
578
|
+
const dfA = 1.0 / (numA - 1);
|
|
579
|
+
const dfB = 1.0 / (numB - 1);
|
|
580
|
+
let fA0 = 0.0;
|
|
581
|
+
let fB0;
|
|
582
|
+
let fA1;
|
|
583
|
+
let fB1;
|
|
584
|
+
const extendA = this._extendA;
|
|
585
|
+
const extendB = this._extendB;
|
|
586
|
+
lsA.pointAt(0, pointA0);
|
|
587
|
+
for (let ia = 1; ia < numA; ia++, pointA0.setFrom(pointA1), fA0 = fA1) {
|
|
588
|
+
fA1 = ia * dfA;
|
|
589
|
+
fB0 = 0.0;
|
|
590
|
+
lsA.pointAt(ia, pointA1);
|
|
591
|
+
lsB.pointAt(0, pointB0);
|
|
592
|
+
for (let ib = 1; ib < numB; ib++, pointB0.setFrom(pointB1), fB0 = fB1) {
|
|
593
|
+
lsB.pointAt(ib, pointB1);
|
|
594
|
+
fB1 = ib * dfB;
|
|
595
|
+
this.dispatchSegmentSegment(lsA, ia === 1 && extendA, pointA0, fA0, pointA1, fA1, (ia + 1) === numA && extendA, lsB, ib === 1 && extendB, pointB0, fB0, pointB1, fB1, (ib + 1) === numB && extendB, reversed);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
547
600
|
/** Double dispatch handler for strongly typed segment. */
|
|
548
601
|
handleLineSegment3d(segmentA) {
|
|
549
602
|
if (this._geometryB instanceof LineSegment3d_1.LineSegment3d) {
|
|
@@ -559,38 +612,13 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
559
612
|
else if (this._geometryB instanceof BSplineCurve_1.BSplineCurve3d) {
|
|
560
613
|
this.dispatchSegmentBsplineCurve(segmentA, this._extendA, segmentA.point0Ref, 0.0, segmentA.point1Ref, 1.0, this._extendA, this._geometryB, this._extendB, false);
|
|
561
614
|
}
|
|
615
|
+
return undefined;
|
|
562
616
|
}
|
|
563
|
-
/** double dispatch handler for strongly typed linestring
|
|
617
|
+
/** double dispatch handler for strongly typed linestring. */
|
|
564
618
|
handleLineString3d(lsA) {
|
|
565
619
|
if (this._geometryB instanceof LineString3d_1.LineString3d) {
|
|
566
620
|
const lsB = this._geometryB;
|
|
567
|
-
|
|
568
|
-
const pointA1 = CurveCurveIntersectXYZ._workPointAA1;
|
|
569
|
-
const pointB0 = CurveCurveIntersectXYZ._workPointBB0;
|
|
570
|
-
const pointB1 = CurveCurveIntersectXYZ._workPointBB1;
|
|
571
|
-
const numA = lsA.numPoints();
|
|
572
|
-
const numB = lsB.numPoints();
|
|
573
|
-
if (numA > 1 && numB > 1) {
|
|
574
|
-
lsA.pointAt(0, pointA0);
|
|
575
|
-
const dfA = 1.0 / (numA - 1);
|
|
576
|
-
const dfB = 1.0 / (numB - 1);
|
|
577
|
-
let fA0 = 0.0;
|
|
578
|
-
let fA1, fB0, fB1;
|
|
579
|
-
const extendA = this._extendA;
|
|
580
|
-
const extendB = this._extendB;
|
|
581
|
-
lsA.pointAt(0, pointA0);
|
|
582
|
-
for (let ia = 1; ia < numA; ia++, pointA0.setFrom(pointA1), fA0 = fA1) {
|
|
583
|
-
fA1 = ia * dfA;
|
|
584
|
-
fB0 = 0.0;
|
|
585
|
-
lsA.pointAt(ia, pointA1);
|
|
586
|
-
lsB.pointAt(0, pointB0);
|
|
587
|
-
for (let ib = 1; ib < numB; ib++, pointB0.setFrom(pointB1), fB0 = fB1) {
|
|
588
|
-
lsB.pointAt(ib, pointB1);
|
|
589
|
-
fB1 = ib * dfB;
|
|
590
|
-
this.dispatchSegmentSegment(lsA, ia === 1 && extendA, pointA0, fA0, pointA1, fA1, (ia + 1) === numA && extendA, lsB, ib === 1 && extendB, pointB0, fB0, pointB1, fB1, (ib + 1) === numB && extendB, false);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
}
|
|
621
|
+
this.computeLineStringLineString(lsA, lsB, false);
|
|
594
622
|
}
|
|
595
623
|
else if (this._geometryB instanceof LineSegment3d_1.LineSegment3d) {
|
|
596
624
|
this.computeSegmentLineString(this._geometryB, this._extendB, lsA, this._extendA, true);
|
|
@@ -619,7 +647,7 @@ class CurveCurveIntersectXYZ extends GeometryHandler_1.NullGeometryHandler {
|
|
|
619
647
|
}
|
|
620
648
|
return undefined;
|
|
621
649
|
}
|
|
622
|
-
/** Double dispatch handler for strongly typed bspline curve
|
|
650
|
+
/** Double dispatch handler for strongly typed bspline curve. */
|
|
623
651
|
handleBSplineCurve3d(curve) {
|
|
624
652
|
if (this._geometryB instanceof LineSegment3d_1.LineSegment3d) {
|
|
625
653
|
this.dispatchSegmentBsplineCurve(this._geometryB, this._extendB, this._geometryB.point0Ref, 0.0, this._geometryB.point1Ref, 1.0, this._extendB, curve, this._extendA, true);
|