@itwin/core-geometry 5.12.0-dev.12 → 5.12.0-dev.13
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/curve/internalContexts/CurveCurveIntersectXY.d.ts +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +81 -57
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/geometry3d/Transform.d.ts +1 -4
- package/lib/cjs/geometry3d/Transform.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Transform.js +1 -4
- package/lib/cjs/geometry3d/Transform.js.map +1 -1
- package/lib/cjs/numerics/Polynomials.d.ts +3 -3
- package/lib/cjs/numerics/Polynomials.js +5 -5
- package/lib/cjs/numerics/Polynomials.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +81 -57
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/geometry3d/Transform.d.ts +1 -4
- package/lib/esm/geometry3d/Transform.d.ts.map +1 -1
- package/lib/esm/geometry3d/Transform.js +1 -4
- package/lib/esm/geometry3d/Transform.js.map +1 -1
- package/lib/esm/numerics/Polynomials.d.ts +3 -3
- package/lib/esm/numerics/Polynomials.js +5 -5
- package/lib/esm/numerics/Polynomials.js.map +1 -1
- package/package.json +3 -3
|
@@ -122,12 +122,14 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
122
122
|
return true;
|
|
123
123
|
}
|
|
124
124
|
/** Test the fraction by strict parameter, but allow toleranced distance test at ends. */
|
|
125
|
-
acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB
|
|
125
|
+
acceptFractionOnLine(extend0, fraction, extend1, pointA, pointB) {
|
|
126
126
|
if (!extend0 && fraction < 0) {
|
|
127
|
-
return Geometry.isDistanceWithinTol(fraction * pointA.
|
|
127
|
+
return Geometry.isDistanceWithinTol(fraction * fraction * pointA.distanceSquaredXY(pointB), this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance);
|
|
128
|
+
}
|
|
129
|
+
else if (!extend1 && fraction > 1.0) {
|
|
130
|
+
const f = fraction - 1;
|
|
131
|
+
return Geometry.isDistanceWithinTol(f * f * pointA.distanceSquaredXY(pointB), this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance);
|
|
128
132
|
}
|
|
129
|
-
else if (!extend1 && fraction > 1.0)
|
|
130
|
-
return Geometry.isDistanceWithinTol((fraction - 1.0) * pointA.distanceXY(pointB), tolerance);
|
|
131
133
|
return true;
|
|
132
134
|
}
|
|
133
135
|
/**
|
|
@@ -141,7 +143,7 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
141
143
|
return result;
|
|
142
144
|
}
|
|
143
145
|
/**
|
|
144
|
-
* Record the pre-computed intersection between two curves.
|
|
146
|
+
* Record the pre-computed intersection between two curves. Record with fraction mapping.
|
|
145
147
|
* @param localFractionA intersection fraction local to the subcurve of cpA between fractionA0 and fractionA1
|
|
146
148
|
* @param cpA the first curve
|
|
147
149
|
* @param fractionA0 start of the subcurve of cpA
|
|
@@ -221,8 +223,7 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
221
223
|
computeSegmentSegment3D(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, cpB, extendB0, pointB0, fractionB0, pointB1, fractionB1, extendB1, reversed) {
|
|
222
224
|
const aDir = { x: pointA1.x - pointA0.x, y: pointA1.y - pointA0.y };
|
|
223
225
|
const bDir = { x: pointB1.x - pointB0.x, y: pointB1.y - pointB0.y };
|
|
224
|
-
const
|
|
225
|
-
const fractions = SmallSystem.lineSegmentXYUVIntersectionUnbounded(pointA0, aDir, pointB0, bDir, tol);
|
|
226
|
+
const fractions = SmallSystem.lineSegmentXYUVIntersectionUnbounded(pointA0, aDir, pointB0, bDir, this._coincidentGeometryContext.tolerance);
|
|
226
227
|
if (!fractions)
|
|
227
228
|
return;
|
|
228
229
|
if (fractions.f1) { // the lines are coincident
|
|
@@ -235,8 +236,8 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
235
236
|
this.recordPointWithLocalFractions(overlap.detailA.fraction, cpA, fractionA0, fractionA1, overlap.detailB.fraction, cpB, fractionB0, fractionB1, reversed, overlap);
|
|
236
237
|
}
|
|
237
238
|
else { // the lines have a transverse intersection
|
|
238
|
-
if (this.acceptFractionOnLine(extendA0, fractions.f0.x, extendA1, pointA0, pointA1
|
|
239
|
-
if (this.acceptFractionOnLine(extendB0, fractions.f0.y, extendB1, pointB0, pointB1
|
|
239
|
+
if (this.acceptFractionOnLine(extendA0, fractions.f0.x, extendA1, pointA0, pointA1)) {
|
|
240
|
+
if (this.acceptFractionOnLine(extendB0, fractions.f0.y, extendB1, pointB0, pointB1))
|
|
240
241
|
this.recordPointWithLocalFractions(fractions.f0.x, cpA, fractionA0, fractionA1, fractions.f0.y, cpB, fractionB0, fractionB1, reversed);
|
|
241
242
|
}
|
|
242
243
|
}
|
|
@@ -301,10 +302,6 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
301
302
|
// solve for theta; evaluate points; project back to line
|
|
302
303
|
if (this._worldToLocalPerspective) {
|
|
303
304
|
const data = arc.toTransformedPoint4d(this._worldToLocalPerspective);
|
|
304
|
-
const radians0 = data.sweep.fractionToRadians(0);
|
|
305
|
-
const pointB0H = data.center.plus2Scaled(data.vector0, Math.cos(radians0), data.vector90, Math.sin(radians0));
|
|
306
|
-
const radians1 = data.sweep.fractionToRadians(1);
|
|
307
|
-
const pointB1H = data.center.plus2Scaled(data.vector0, Math.cos(radians1), data.vector90, Math.sin(radians1));
|
|
308
305
|
const pointA0H = this._worldToLocalPerspective.multiplyPoint3d(pointA0, 1);
|
|
309
306
|
const pointA1H = this._worldToLocalPerspective.multiplyPoint3d(pointA1, 1);
|
|
310
307
|
const alpha = Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
@@ -313,35 +310,49 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
313
310
|
let numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians, tol2);
|
|
314
311
|
const closeApproach = (0 === numRoots);
|
|
315
312
|
if (closeApproach)
|
|
316
|
-
numRoots = 1; //
|
|
317
|
-
|
|
318
|
-
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
319
|
-
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
320
|
-
let fLine = SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, arcPoint);
|
|
321
|
-
if (fLine === undefined)
|
|
322
|
-
return undefined;
|
|
323
|
-
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
324
|
-
return { fLine, fArc };
|
|
325
|
-
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
326
|
-
fLine = fLine < 0.5 ? 0 : 1;
|
|
327
|
-
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
328
|
-
const pointAH = fLine ? pointA1H : pointA0H;
|
|
329
|
-
const pointBH = fArc ? pointB1H : pointB0H;
|
|
330
|
-
const dist2 = pointAH.realDistanceSquaredXY(pointBH);
|
|
331
|
-
return (dist2 !== undefined && Geometry.isDistanceWithinTol(dist2, tol2)) ? { fLine, fArc } : undefined;
|
|
332
|
-
};
|
|
313
|
+
numRoots = 1; // arc closest approach is the first entry
|
|
314
|
+
let numAccepted = 0;
|
|
333
315
|
for (let i = 0; i < numRoots; i++) {
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
316
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
317
|
+
const fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(i), extendB0);
|
|
318
|
+
const fLine = SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, arcPoint);
|
|
319
|
+
if (fLine === undefined)
|
|
320
|
+
continue;
|
|
321
|
+
if (closeApproach) {
|
|
322
|
+
const linePoint = pointA0H.interpolate(fLine, pointA1H);
|
|
323
|
+
const dist2 = arcPoint.realDistanceSquaredXY(linePoint);
|
|
324
|
+
if (dist2 === undefined || !Geometry.isDistanceWithinTol(dist2, tol2))
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1)) {
|
|
328
|
+
this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
|
|
329
|
+
numAccepted++;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (numAccepted === 0 && !arc.sweep.isFullCircle) {
|
|
333
|
+
// check for endpoint intersection beyond parametric tolerance but within point tolerance
|
|
334
|
+
const pointB0H = this._worldToLocalPerspective.multiplyPoint3d(arc.startPoint(), 1);
|
|
335
|
+
const pointB1H = this._worldToLocalPerspective.multiplyPoint3d(arc.endPoint(), 1);
|
|
336
|
+
const dist2 = [];
|
|
337
|
+
let d2 = pointA0H.realDistanceSquaredXY(pointB0H);
|
|
338
|
+
if (d2 !== undefined)
|
|
339
|
+
dist2.push({ d2, fA: 0, fB: 0 });
|
|
340
|
+
d2 = pointA0H.realDistanceSquaredXY(pointB1H);
|
|
341
|
+
if (d2 !== undefined)
|
|
342
|
+
dist2.push({ d2, fA: 0, fB: 1 });
|
|
343
|
+
d2 = pointA1H.realDistanceSquaredXY(pointB0H);
|
|
344
|
+
if (d2 !== undefined)
|
|
345
|
+
dist2.push({ d2, fA: 1, fB: 0 });
|
|
346
|
+
d2 = pointA1H.realDistanceSquaredXY(pointB1H);
|
|
347
|
+
if (d2 !== undefined)
|
|
348
|
+
dist2.push({ d2, fA: 1, fB: 1 });
|
|
349
|
+
dist2.sort((a, b) => a.d2 - b.d2);
|
|
350
|
+
if (Geometry.isDistanceWithinTol(dist2[0].d2, tol2))
|
|
351
|
+
this.recordPointWithLocalFractions(dist2[0].fA, cpA, fractionA0, fractionA1, dist2[0].fB, arc, 0, 1, reversed);
|
|
337
352
|
}
|
|
338
353
|
}
|
|
339
354
|
else {
|
|
340
355
|
const data = arc.toTransformedVectors(this._worldToLocalAffine);
|
|
341
|
-
const radians0 = data.sweep.fractionToRadians(0);
|
|
342
|
-
const pointB0Local = data.center.plus2Scaled(data.vector0, Math.cos(radians0), data.vector90, Math.sin(radians0));
|
|
343
|
-
const radians1 = data.sweep.fractionToRadians(1);
|
|
344
|
-
const pointB1Local = data.center.plus2Scaled(data.vector0, Math.cos(radians1), data.vector90, Math.sin(radians1));
|
|
345
356
|
let pointA0Local = pointA0;
|
|
346
357
|
let pointA1Local = pointA1;
|
|
347
358
|
if (this._worldToLocalAffine) {
|
|
@@ -354,27 +365,40 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
354
365
|
let numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians, tol2);
|
|
355
366
|
const closeApproach = (0 === numRoots);
|
|
356
367
|
if (closeApproach)
|
|
357
|
-
numRoots = 1; //
|
|
358
|
-
|
|
359
|
-
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
360
|
-
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
361
|
-
let fLine = SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
362
|
-
if (fLine === undefined)
|
|
363
|
-
return undefined;
|
|
364
|
-
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
365
|
-
return { fLine, fArc };
|
|
366
|
-
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
367
|
-
fLine = fLine < 0.5 ? 0 : 1;
|
|
368
|
-
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
369
|
-
const pointALocal = fLine ? pointA1Local : pointA0Local;
|
|
370
|
-
const pointBLocal = fArc ? pointB1Local : pointB0Local;
|
|
371
|
-
const dist2 = pointALocal.distanceSquaredXY(pointBLocal);
|
|
372
|
-
return Geometry.isDistanceWithinTol(dist2, tol2) ? { fLine, fArc } : undefined;
|
|
373
|
-
};
|
|
368
|
+
numRoots = 1; // arc closest approach is the first entry
|
|
369
|
+
let numAccepted = 0;
|
|
374
370
|
for (let i = 0; i < numRoots; i++) {
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
|
|
371
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
372
|
+
const fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(i), extendB0);
|
|
373
|
+
const fLine = SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
374
|
+
if (fLine === undefined)
|
|
375
|
+
continue;
|
|
376
|
+
if (closeApproach) {
|
|
377
|
+
const linePoint = pointA0Local.interpolate(fLine, pointA1Local);
|
|
378
|
+
if (!Geometry.isDistanceWithinTol(arcPoint.distanceSquaredXY(linePoint), tol2))
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1)) {
|
|
382
|
+
this.recordPointWithLocalFractions(fLine, cpA, fractionA0, fractionA1, fArc, arc, 0, 1, reversed);
|
|
383
|
+
numAccepted++;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (numAccepted === 0 && !arc.sweep.isFullCircle) {
|
|
387
|
+
// check for endpoint intersection beyond parametric tolerance but within point tolerance
|
|
388
|
+
const pointB0Local = arc.startPoint();
|
|
389
|
+
const pointB1Local = arc.endPoint();
|
|
390
|
+
if (this._worldToLocalAffine) {
|
|
391
|
+
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB0Local);
|
|
392
|
+
this._worldToLocalAffine.multiplyXYAndZInPlace(pointB1Local);
|
|
393
|
+
}
|
|
394
|
+
const dist2 = [];
|
|
395
|
+
dist2.push({ d2: pointA0Local.distanceSquaredXY(pointB0Local), fA: 0, fB: 0 });
|
|
396
|
+
dist2.push({ d2: pointA0Local.distanceSquaredXY(pointB1Local), fA: 0, fB: 1 });
|
|
397
|
+
dist2.push({ d2: pointA1Local.distanceSquaredXY(pointB0Local), fA: 1, fB: 0 });
|
|
398
|
+
dist2.push({ d2: pointA1Local.distanceSquaredXY(pointB1Local), fA: 1, fB: 1 });
|
|
399
|
+
dist2.sort((a, b) => a.d2 - b.d2);
|
|
400
|
+
if (Geometry.isDistanceWithinTol(dist2[0].d2, tol2))
|
|
401
|
+
this.recordPointWithLocalFractions(dist2[0].fA, cpA, fractionA0, fractionA1, dist2[0].fB, arc, 0, 1, reversed);
|
|
378
402
|
}
|
|
379
403
|
}
|
|
380
404
|
}
|