@itwin/core-geometry 5.13.0-dev.4 → 5.13.0-dev.6
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 +12 -1
- package/lib/cjs/curve/Arc3d.d.ts +1 -1
- package/lib/cjs/curve/Arc3d.js +1 -1
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/curve/CurveFactory.d.ts +14 -6
- package/lib/cjs/curve/CurveFactory.d.ts.map +1 -1
- package/lib/cjs/curve/CurveFactory.js +11 -1
- package/lib/cjs/curve/CurveFactory.js.map +1 -1
- package/lib/cjs/curve/LineSegment3d.d.ts +6 -1
- package/lib/cjs/curve/LineSegment3d.d.ts.map +1 -1
- package/lib/cjs/curve/LineSegment3d.js +8 -1
- package/lib/cjs/curve/LineSegment3d.js.map +1 -1
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts +9 -4
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js +25 -16
- package/lib/cjs/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.js +1 -3
- package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/cjs/curve/RegionOps.d.ts +25 -3
- package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
- package/lib/cjs/curve/RegionOps.js +2 -1
- package/lib/cjs/curve/RegionOps.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts +4 -0
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +132 -106
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/curve/spiral/TransitionSpiral3d.d.ts +5 -0
- package/lib/cjs/curve/spiral/TransitionSpiral3d.d.ts.map +1 -1
- package/lib/cjs/curve/spiral/TransitionSpiral3d.js +7 -0
- package/lib/cjs/curve/spiral/TransitionSpiral3d.js.map +1 -1
- package/lib/cjs/geometry3d/AngleSweep.d.ts +2 -2
- package/lib/cjs/geometry3d/AngleSweep.js +2 -2
- package/lib/cjs/geometry3d/AngleSweep.js.map +1 -1
- package/lib/cjs/geometry3d/Range.d.ts +8 -0
- package/lib/cjs/geometry3d/Range.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Range.js +16 -0
- package/lib/cjs/geometry3d/Range.js.map +1 -1
- package/lib/esm/curve/Arc3d.d.ts +1 -1
- package/lib/esm/curve/Arc3d.js +1 -1
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/curve/CurveFactory.d.ts +14 -6
- package/lib/esm/curve/CurveFactory.d.ts.map +1 -1
- package/lib/esm/curve/CurveFactory.js +11 -1
- package/lib/esm/curve/CurveFactory.js.map +1 -1
- package/lib/esm/curve/LineSegment3d.d.ts +6 -1
- package/lib/esm/curve/LineSegment3d.d.ts.map +1 -1
- package/lib/esm/curve/LineSegment3d.js +8 -1
- package/lib/esm/curve/LineSegment3d.js.map +1 -1
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts +9 -4
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.d.ts.map +1 -1
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js +25 -16
- package/lib/esm/curve/Query/ConsolidateAdjacentPrimitivesContext.js.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.js +2 -4
- package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/esm/curve/RegionOps.d.ts +25 -3
- package/lib/esm/curve/RegionOps.d.ts.map +1 -1
- package/lib/esm/curve/RegionOps.js +2 -1
- package/lib/esm/curve/RegionOps.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts +4 -0
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +132 -106
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/curve/spiral/TransitionSpiral3d.d.ts +5 -0
- package/lib/esm/curve/spiral/TransitionSpiral3d.d.ts.map +1 -1
- package/lib/esm/curve/spiral/TransitionSpiral3d.js +7 -0
- package/lib/esm/curve/spiral/TransitionSpiral3d.js.map +1 -1
- package/lib/esm/geometry3d/AngleSweep.d.ts +2 -2
- package/lib/esm/geometry3d/AngleSweep.js +2 -2
- package/lib/esm/geometry3d/AngleSweep.js.map +1 -1
- package/lib/esm/geometry3d/Range.d.ts +8 -0
- package/lib/esm/geometry3d/Range.d.ts.map +1 -1
- package/lib/esm/geometry3d/Range.js +16 -0
- package/lib/esm/geometry3d/Range.js.map +1 -1
- package/package.json +3 -3
|
@@ -287,124 +287,149 @@ class CurveCurveIntersectXY extends GeometryHandler_1.RecurseToCurvesGeometryHan
|
|
|
287
287
|
this.computeSegmentSegment3D(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, cpB, extendB0, pointB0, fractionB0, pointB1, fractionB1, extendB1, reversed);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
// The fraction and extend parameters allow all combinations to be passed in.
|
|
293
|
-
dispatchSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
290
|
+
/** Implementation of dispatchSegmentArc under affine transform. KEEP IN SYNC WITH computeSegmentArcHomogeneous. */
|
|
291
|
+
computeSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
294
292
|
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
295
293
|
const cosines = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
296
294
|
const sines = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
297
295
|
const radians = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
numAccepted++;
|
|
333
|
-
}
|
|
296
|
+
const recordIfNearIntersection = (fA, fB, d2) => {
|
|
297
|
+
if (!Geometry_1.Geometry.isDistanceWithinTol(d2, tol2))
|
|
298
|
+
return false;
|
|
299
|
+
this.recordPointWithLocalFractions(fA, cpA, fractionA0, fractionA1, fB, arc, 0, 1, reversed);
|
|
300
|
+
return true;
|
|
301
|
+
};
|
|
302
|
+
const data = arc.toTransformedVectors(this._worldToLocalAffine);
|
|
303
|
+
let pointA0Local = pointA0;
|
|
304
|
+
let pointA1Local = pointA1;
|
|
305
|
+
const pointB0Local = arc.startPoint();
|
|
306
|
+
const pointB1Local = arc.endPoint();
|
|
307
|
+
if (this._worldToLocalAffine) {
|
|
308
|
+
pointA0Local = this._worldToLocalAffine.multiplyPoint3d(pointA0);
|
|
309
|
+
pointA1Local = this._worldToLocalAffine.multiplyPoint3d(pointA1);
|
|
310
|
+
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB0Local);
|
|
311
|
+
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB1Local);
|
|
312
|
+
}
|
|
313
|
+
const alpha = Geometry_1.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
314
|
+
const beta = Geometry_1.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
315
|
+
const gamma = Geometry_1.Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
316
|
+
// note really tight tol for tangency since below we check closest approach also
|
|
317
|
+
let numRoots = Polynomials_1.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians, tol2);
|
|
318
|
+
const closeApproach = (0 === numRoots);
|
|
319
|
+
if (closeApproach)
|
|
320
|
+
numRoots = 1; // we returned the closest approach instead: first entry is the arc point, which is all we need
|
|
321
|
+
const roots = [];
|
|
322
|
+
for (let i = 0; i < numRoots; i++) {
|
|
323
|
+
const arcPt = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
324
|
+
const fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(i), extendB0); // exterior fraction sign based on extend flags
|
|
325
|
+
const fArcNearest01 = data.sweep.fractionToSignedPeriodicFraction(fArc, undefined); // exterior fraction sign based on proximity to 0/1
|
|
326
|
+
const fLine = SmallSystem_1.SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPt);
|
|
327
|
+
if (fLine !== undefined) {
|
|
328
|
+
const linePt = pointA0Local.interpolate(fLine, pointA1Local);
|
|
329
|
+
roots.push({ fArc, fArcNearest01, fLine, arcPt, linePt });
|
|
334
330
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
dist2.push({ d2, fA: 0, fB: 1 });
|
|
346
|
-
d2 = pointA1H.realDistanceSquaredXY(pointB0H);
|
|
347
|
-
if (d2 !== undefined)
|
|
348
|
-
dist2.push({ d2, fA: 1, fB: 0 });
|
|
349
|
-
d2 = pointA1H.realDistanceSquaredXY(pointB1H);
|
|
350
|
-
if (d2 !== undefined)
|
|
351
|
-
dist2.push({ d2, fA: 1, fB: 1 });
|
|
352
|
-
dist2.sort((a, b) => a.d2 - b.d2);
|
|
353
|
-
if (Geometry_1.Geometry.isDistanceWithinTol(dist2[0].d2, tol2))
|
|
354
|
-
this.recordPointWithLocalFractions(dist2[0].fA, cpA, fractionA0, fractionA1, dist2[0].fB, arc, 0, 1, reversed);
|
|
331
|
+
}
|
|
332
|
+
// range-test and record roots
|
|
333
|
+
for (const root of roots) {
|
|
334
|
+
const { fArc, fArcNearest01, fLine, arcPt, linePt } = root;
|
|
335
|
+
if (closeApproach && !Geometry_1.Geometry.isDistanceWithinTol(arcPt.distanceSquaredXY(linePt), tol2)) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1)) {
|
|
339
|
+
this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
|
|
340
|
+
continue;
|
|
355
341
|
}
|
|
342
|
+
// since line-arc chains are so common, look for near-endpoint intersections using distance tol, which is often relatively looser than fraction tol
|
|
343
|
+
const inArcRange = extendB0 || extendB1 || Geometry_1.Geometry.isIn01(fArc);
|
|
344
|
+
const inLineRange = (extendA0 && fLine < 0) || (extendA1 && fLine > 1) || Geometry_1.Geometry.isIn01(fLine);
|
|
345
|
+
let accepted = false;
|
|
346
|
+
if (inArcRange && !inLineRange) // check tangency near line endpoint
|
|
347
|
+
accepted = recordIfNearIntersection(fLine < 0 ? 0 : 1, fArc, (fLine < 0 ? pointA0Local : pointA1Local).distanceSquaredXY(arcPt));
|
|
348
|
+
else if (!inArcRange && inLineRange) // check tangency near arc endpoint
|
|
349
|
+
accepted = recordIfNearIntersection(fLine, fArcNearest01 < 0 ? 0 : 1, linePt.distanceSquaredXY(fArcNearest01 < 0 ? pointB0Local : pointB1Local));
|
|
350
|
+
if (!accepted) // check intersection between nearest endpoints
|
|
351
|
+
recordIfNearIntersection(fLine < 0.5 ? 0 : 1, fArcNearest01 < 0.5 ? 0 : 1, (fLine < 0.5 ? pointA0Local : pointA1Local).distanceSquaredXY(fArcNearest01 < 0.5 ? pointB0Local : pointB1Local));
|
|
356
352
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
353
|
+
}
|
|
354
|
+
/** Implementation of dispatchSegmentArc under perspective transform. KEEP IN SYNC WITH computeSegmentArc. */
|
|
355
|
+
computeSegmentArcHomogeneous(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
356
|
+
if (!this._worldToLocalPerspective)
|
|
357
|
+
return;
|
|
358
|
+
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
359
|
+
const cosines = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
360
|
+
const sines = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
361
|
+
const radians = new GrowableFloat64Array_1.GrowableFloat64Array(2);
|
|
362
|
+
const recordIfNearIntersection = (fA, fB, d2) => {
|
|
363
|
+
if (d2 === undefined || !Geometry_1.Geometry.isDistanceWithinTol(d2, tol2))
|
|
364
|
+
return false;
|
|
365
|
+
this.recordPointWithLocalFractions(fA, cpA, fractionA0, fractionA1, fB, arc, 0, 1, reversed);
|
|
366
|
+
return true;
|
|
367
|
+
};
|
|
368
|
+
const data = arc.toTransformedPoint4d(this._worldToLocalPerspective);
|
|
369
|
+
const pointA0H = this._worldToLocalPerspective.multiplyPoint3d(pointA0, 1);
|
|
370
|
+
const pointA1H = this._worldToLocalPerspective.multiplyPoint3d(pointA1, 1);
|
|
371
|
+
const pointB0H = this._worldToLocalPerspective.multiplyPoint3d(arc.startPoint(), 1);
|
|
372
|
+
const pointB1H = this._worldToLocalPerspective.multiplyPoint3d(arc.endPoint(), 1);
|
|
373
|
+
const alpha = Geometry_1.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
374
|
+
const beta = Geometry_1.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
|
|
375
|
+
const gamma = Geometry_1.Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
|
|
376
|
+
// note really tight tol for tangency since below we check closest approach also
|
|
377
|
+
let numRoots = Polynomials_1.AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians, tol2);
|
|
378
|
+
const closeApproach = (0 === numRoots);
|
|
379
|
+
if (closeApproach)
|
|
380
|
+
numRoots = 1; // we returned the closest approach instead: first entry is the arc point, which is all we need
|
|
381
|
+
const roots = [];
|
|
382
|
+
for (let i = 0; i < numRoots; i++) {
|
|
383
|
+
const arcPt = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
384
|
+
const fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(i), extendB0); // exterior fraction sign based on extend flags
|
|
385
|
+
const fArcNearest01 = data.sweep.fractionToSignedPeriodicFraction(fArc, undefined); // exterior fraction sign based on proximity to 0/1
|
|
386
|
+
const fLine = SmallSystem_1.SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, arcPt);
|
|
387
|
+
if (fLine !== undefined) {
|
|
388
|
+
const linePt = pointA0H.interpolate(fLine, pointA1H);
|
|
389
|
+
roots.push({ fArc, fArcNearest01, fLine, arcPt, linePt });
|
|
364
390
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
let numAccepted = 0;
|
|
373
|
-
for (let i = 0; i < numRoots; i++) {
|
|
374
|
-
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
375
|
-
const fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(i), extendB0);
|
|
376
|
-
const fLine = SmallSystem_1.SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
377
|
-
if (fLine === undefined)
|
|
391
|
+
}
|
|
392
|
+
// range-test and record roots
|
|
393
|
+
for (const root of roots) {
|
|
394
|
+
const { fArc, fArcNearest01, fLine, arcPt, linePt } = root;
|
|
395
|
+
if (closeApproach) {
|
|
396
|
+
const dist2 = arcPt.realDistanceSquaredXY(linePt);
|
|
397
|
+
if (dist2 === undefined || !Geometry_1.Geometry.isDistanceWithinTol(dist2, tol2))
|
|
378
398
|
continue;
|
|
379
|
-
if (closeApproach) {
|
|
380
|
-
const linePoint = pointA0Local.interpolate(fLine, pointA1Local);
|
|
381
|
-
if (!Geometry_1.Geometry.isDistanceWithinTol(arcPoint.distanceSquaredXY(linePoint), tol2))
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
if (this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1)) {
|
|
385
|
-
this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
|
|
386
|
-
numAccepted++;
|
|
387
|
-
}
|
|
388
399
|
}
|
|
389
|
-
if (
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const pointB1Local = arc.endPoint();
|
|
393
|
-
if (this._worldToLocalAffine) {
|
|
394
|
-
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB0Local);
|
|
395
|
-
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB1Local);
|
|
396
|
-
}
|
|
397
|
-
const dist2 = [];
|
|
398
|
-
dist2.push({ d2: pointA0Local.distanceSquaredXY(pointB0Local), fA: 0, fB: 0 });
|
|
399
|
-
dist2.push({ d2: pointA0Local.distanceSquaredXY(pointB1Local), fA: 0, fB: 1 });
|
|
400
|
-
dist2.push({ d2: pointA1Local.distanceSquaredXY(pointB0Local), fA: 1, fB: 0 });
|
|
401
|
-
dist2.push({ d2: pointA1Local.distanceSquaredXY(pointB1Local), fA: 1, fB: 1 });
|
|
402
|
-
dist2.sort((a, b) => a.d2 - b.d2);
|
|
403
|
-
if (Geometry_1.Geometry.isDistanceWithinTol(dist2[0].d2, tol2))
|
|
404
|
-
this.recordPointWithLocalFractions(dist2[0].fA, cpA, fractionA0, fractionA1, dist2[0].fB, arc, 0, 1, reversed);
|
|
400
|
+
if (this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1)) {
|
|
401
|
+
this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
|
|
402
|
+
continue;
|
|
405
403
|
}
|
|
404
|
+
// since line-arc chains are so common, look for near-endpoint intersections using distance tol, which is often relatively looser than fraction tol
|
|
405
|
+
const inArcRange = extendB0 || extendB1 || Geometry_1.Geometry.isIn01(fArc);
|
|
406
|
+
const inLineRange = (extendA0 && fLine < 0) || (extendA1 && fLine > 1) || Geometry_1.Geometry.isIn01(fLine);
|
|
407
|
+
let accepted = false;
|
|
408
|
+
if (inArcRange && !inLineRange) // check tangency near line endpoint
|
|
409
|
+
accepted = recordIfNearIntersection(fLine < 0 ? 0 : 1, fArc, (fLine < 0 ? pointA0H : pointA1H).realDistanceSquaredXY(arcPt));
|
|
410
|
+
else if (!inArcRange && inLineRange) // check tangency near arc endpoint
|
|
411
|
+
accepted = recordIfNearIntersection(fLine, fArcNearest01 < 0 ? 0 : 1, linePt.realDistanceSquaredXY(fArcNearest01 < 0 ? pointB0H : pointB1H));
|
|
412
|
+
if (!accepted) // check intersection between nearest endpoints
|
|
413
|
+
recordIfNearIntersection(fLine < 0.5 ? 0 : 1, fArcNearest01 < 0.5 ? 0 : 1, (fLine < 0.5 ? pointA0H : pointA1H).realDistanceSquaredXY(fArcNearest01 < 0.5 ? pointB0H : pointB1H));
|
|
406
414
|
}
|
|
407
415
|
}
|
|
416
|
+
// Caller accesses data from a linestring or segment and passes it here.
|
|
417
|
+
// The line segment in question might be (a) a full line segment or (b) a fragment within a linestring.
|
|
418
|
+
// The fraction and extend parameters allow all combinations to be passed in.
|
|
419
|
+
dispatchSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
420
|
+
// Arc: X(theta) = C + cos(theta)·U + sin(theta)·V
|
|
421
|
+
// Line: contains points A0,A1
|
|
422
|
+
// Arc point X is colinear (intersects) with line if det(A0, A1, X) = 0 with homogeneous xyw points and vectors
|
|
423
|
+
// This leads to
|
|
424
|
+
// det(A0, A1, C) + cos(theta) det(A0, A1, U) + sin(theta) det(A0, A1, V) = 0
|
|
425
|
+
// or
|
|
426
|
+
// alpha + beta cos(theta) + gamma sin(theta) = 0
|
|
427
|
+
// solve for theta; evaluate points; project back to line
|
|
428
|
+
if (this._worldToLocalPerspective)
|
|
429
|
+
this.computeSegmentArcHomogeneous(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed);
|
|
430
|
+
else
|
|
431
|
+
this.computeSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed);
|
|
432
|
+
}
|
|
408
433
|
/**
|
|
409
434
|
* Compute the intersection of two xy-arcs.
|
|
410
435
|
* * Each matrix has [U V C] in (x,y,w) form from homogeneous projection (local to world).
|
|
@@ -899,7 +924,8 @@ class CurveCurveIntersectXY extends GeometryHandler_1.RecurseToCurvesGeometryHan
|
|
|
899
924
|
let converged = newtonSearcher.runIterations();
|
|
900
925
|
const fractionA = newtonSearcher.getU();
|
|
901
926
|
const fractionB = newtonSearcher.getV();
|
|
902
|
-
|
|
927
|
+
// note looser tol for spiral, which can have high order tangency at start/end
|
|
928
|
+
if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(false, fractionB, false, Geometry_1.Geometry.smallFraction)) {
|
|
903
929
|
const pointA = curveA.fractionToPoint(fractionA, CurveCurveIntersectXY._workPointA0);
|
|
904
930
|
const pointB = spiralB.fractionToPoint(fractionB, CurveCurveIntersectXY._workPointB0);
|
|
905
931
|
if (!converged) // Newton may have found close points even if it didn't converge parametrically
|