@itwin/core-geometry 5.2.0 → 5.2.1
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/Arc3d.d.ts.map +1 -1
- package/lib/cjs/curve/Arc3d.js +5 -7
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/curve/CurveOps.d.ts +2 -5
- package/lib/cjs/curve/CurveOps.d.ts.map +1 -1
- package/lib/cjs/curve/CurveOps.js +2 -5
- package/lib/cjs/curve/CurveOps.js.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts +50 -15
- package/lib/cjs/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/cjs/curve/Query/PlanarSubdivision.js +102 -84
- package/lib/cjs/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/cjs/curve/RegionOps.d.ts +44 -25
- package/lib/cjs/curve/RegionOps.d.ts.map +1 -1
- package/lib/cjs/curve/RegionOps.js +74 -39
- package/lib/cjs/curve/RegionOps.js.map +1 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
- package/lib/cjs/curve/RegionOpsClassificationSweeps.js +8 -8
- package/lib/cjs/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts +1 -0
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js +102 -92
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.d.ts +2 -1
- package/lib/cjs/geometry3d/GrowableXYArray.d.ts.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYArray.js +2 -1
- package/lib/cjs/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.d.ts +2 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.d.ts.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.js +2 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +9 -16
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.js +3 -3
- package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/cjs/geometry3d/PolylineOps.d.ts +2 -2
- package/lib/cjs/geometry3d/PolylineOps.js +2 -2
- package/lib/cjs/geometry3d/PolylineOps.js.map +1 -1
- package/lib/cjs/numerics/ClusterableArray.d.ts.map +1 -1
- package/lib/cjs/numerics/ClusterableArray.js +2 -2
- package/lib/cjs/numerics/ClusterableArray.js.map +1 -1
- package/lib/cjs/topology/Merging.d.ts +15 -7
- package/lib/cjs/topology/Merging.d.ts.map +1 -1
- package/lib/cjs/topology/Merging.js +15 -10
- package/lib/cjs/topology/Merging.js.map +1 -1
- package/lib/esm/curve/Arc3d.d.ts.map +1 -1
- package/lib/esm/curve/Arc3d.js +5 -7
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/curve/CurveOps.d.ts +2 -5
- package/lib/esm/curve/CurveOps.d.ts.map +1 -1
- package/lib/esm/curve/CurveOps.js +2 -5
- package/lib/esm/curve/CurveOps.js.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts +50 -15
- package/lib/esm/curve/Query/PlanarSubdivision.d.ts.map +1 -1
- package/lib/esm/curve/Query/PlanarSubdivision.js +102 -84
- package/lib/esm/curve/Query/PlanarSubdivision.js.map +1 -1
- package/lib/esm/curve/RegionOps.d.ts +44 -25
- package/lib/esm/curve/RegionOps.d.ts.map +1 -1
- package/lib/esm/curve/RegionOps.js +72 -37
- package/lib/esm/curve/RegionOps.js.map +1 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.d.ts.map +1 -1
- package/lib/esm/curve/RegionOpsClassificationSweeps.js +8 -8
- package/lib/esm/curve/RegionOpsClassificationSweeps.js.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts +1 -0
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -1
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js +102 -92
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.d.ts +2 -1
- package/lib/esm/geometry3d/GrowableXYArray.d.ts.map +1 -1
- package/lib/esm/geometry3d/GrowableXYArray.js +2 -1
- package/lib/esm/geometry3d/GrowableXYArray.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYZArray.d.ts +2 -1
- package/lib/esm/geometry3d/GrowableXYZArray.d.ts.map +1 -1
- package/lib/esm/geometry3d/GrowableXYZArray.js +2 -1
- package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +9 -16
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.js +3 -3
- package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/esm/geometry3d/PolylineOps.d.ts +2 -2
- package/lib/esm/geometry3d/PolylineOps.js +2 -2
- package/lib/esm/geometry3d/PolylineOps.js.map +1 -1
- package/lib/esm/numerics/ClusterableArray.d.ts.map +1 -1
- package/lib/esm/numerics/ClusterableArray.js +2 -2
- package/lib/esm/numerics/ClusterableArray.js.map +1 -1
- package/lib/esm/topology/Merging.d.ts +15 -7
- package/lib/esm/topology/Merging.d.ts.map +1 -1
- package/lib/esm/topology/Merging.js +15 -10
- package/lib/esm/topology/Merging.js.map +1 -1
- package/package.json +3 -3
|
@@ -262,7 +262,9 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
262
262
|
// The fraction and extend parameters allow all combinations to be passed in.
|
|
263
263
|
dispatchSegmentArc(cpA, extendA0, pointA0, fractionA0, pointA1, fractionA1, extendA1, arc, extendB0, extendB1, reversed) {
|
|
264
264
|
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
265
|
-
|
|
265
|
+
const cosines = new GrowableFloat64Array(2);
|
|
266
|
+
const sines = new GrowableFloat64Array(2);
|
|
267
|
+
const radians = new GrowableFloat64Array(2);
|
|
266
268
|
// Arc: X = C + cU + sV
|
|
267
269
|
// Line: contains points A0,A1
|
|
268
270
|
// Arc point colinear with line if det (A0, A1, X) = 0
|
|
@@ -282,27 +284,30 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
282
284
|
const alpha = Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.center);
|
|
283
285
|
const beta = Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector0);
|
|
284
286
|
const gamma = Geometry.tripleProductPoint4dXYW(pointA0H, pointA1H, data.vector90);
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
let numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians);
|
|
288
|
+
const closeApproach = (0 === numRoots);
|
|
289
|
+
if (closeApproach)
|
|
290
|
+
numRoots = 1; // we returned the arc's closest approach as the first "root"; if within tolerance and at endpoints, we record it
|
|
291
|
+
const acceptSolution = (iRoot, checkOnlyEndPointDistance = false) => {
|
|
292
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
293
|
+
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
294
|
+
let fLine = SmallSystem.lineSegment3dHXYClosestPointUnbounded(pointA0H, pointA1H, arcPoint);
|
|
295
|
+
if (fLine === undefined)
|
|
296
|
+
return undefined;
|
|
297
|
+
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
298
|
+
return { fLine, fArc };
|
|
299
|
+
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
300
|
+
fLine = fLine < 0.5 ? 0 : 1;
|
|
301
|
+
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
302
|
+
const pointAH = fLine ? pointA1H : pointA0H;
|
|
303
|
+
const pointBH = fArc ? pointB1H : pointB0H;
|
|
304
|
+
const dist2 = pointAH.realDistanceSquaredXY(pointBH);
|
|
305
|
+
return (dist2 !== undefined && Geometry.isDistanceWithinTol(dist2, tol2)) ? { fLine, fArc } : undefined;
|
|
306
|
+
};
|
|
291
307
|
for (let i = 0; i < numRoots; i++) {
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
if (lineFraction !== undefined) {
|
|
296
|
-
if (this.acceptFraction(extendA0, lineFraction, extendA1) && this.acceptFraction(extendB0, arcFraction, extendB1)) {
|
|
297
|
-
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
298
|
-
}
|
|
299
|
-
else { // check for endpoint intersections beyond parametric tolerance but within point tolerance
|
|
300
|
-
const pointAH = lineFraction < 0.5 ? pointA0H : pointA1H;
|
|
301
|
-
const pointBH = (arcFraction = data.sweep.fractionToSignedPeriodicFraction(arcFraction)) < 0.5 ? pointB0H : pointB1H;
|
|
302
|
-
if ((dist2 = pointAH.realDistanceSquaredXY(pointBH)) !== undefined && Geometry.isDistanceWithinTol(dist2, tol2))
|
|
303
|
-
this.recordPointWithLocalFractions(lineFraction < 0.5 ? 0 : 1, cpA, fractionA0, fractionA1, arcFraction < 0.5 ? 0 : 1, arc, 0, 1, reversed);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
308
|
+
const result = acceptSolution(i, closeApproach);
|
|
309
|
+
if (result)
|
|
310
|
+
this.recordPointWithLocalFractions(result.fLine, cpA, fractionA0, fractionA1, result.fArc, arc, 0, 1, reversed);
|
|
306
311
|
}
|
|
307
312
|
}
|
|
308
313
|
else {
|
|
@@ -320,27 +325,30 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
320
325
|
const alpha = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
321
326
|
const beta = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
322
327
|
const gamma = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
328
|
+
let numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(alpha, beta, gamma, cosines, sines, radians);
|
|
329
|
+
const closeApproach = (0 === numRoots);
|
|
330
|
+
if (closeApproach)
|
|
331
|
+
numRoots = 1; // we returned the arc's closest approach as the first "root"; if within tolerance and at endpoints, we record it
|
|
332
|
+
const acceptSolution = (iRoot, checkOnlyEndPointDistance = false) => {
|
|
333
|
+
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(iRoot), data.vector90, sines.atUncheckedIndex(iRoot));
|
|
334
|
+
let fArc = data.sweep.radiansToSignedFraction(radians.atUncheckedIndex(iRoot), extendB0);
|
|
335
|
+
let fLine = SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
336
|
+
if (fLine === undefined)
|
|
337
|
+
return undefined;
|
|
338
|
+
if (!checkOnlyEndPointDistance && this.acceptFraction(extendA0, fLine, extendA1) && this.acceptFraction(extendB0, fArc, extendB1))
|
|
339
|
+
return { fLine, fArc };
|
|
340
|
+
// check for an endpoint intersection that is beyond parametric tolerance but within point tolerance
|
|
341
|
+
fLine = fLine < 0.5 ? 0 : 1;
|
|
342
|
+
fArc = data.sweep.fractionToSignedPeriodicFraction(fArc) < 0.5 ? 0 : 1;
|
|
343
|
+
const pointALocal = fLine ? pointA1Local : pointA0Local;
|
|
344
|
+
const pointBLocal = fArc ? pointB1Local : pointB0Local;
|
|
345
|
+
const dist2 = pointALocal.distanceSquaredXY(pointBLocal);
|
|
346
|
+
return Geometry.isDistanceWithinTol(dist2, tol2) ? { fLine, fArc } : undefined;
|
|
347
|
+
};
|
|
329
348
|
for (let i = 0; i < numRoots; i++) {
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (lineFraction !== undefined) {
|
|
334
|
-
if (this.acceptFraction(extendA0, lineFraction, extendA1) && this.acceptFraction(extendB0, arcFraction, extendB1)) {
|
|
335
|
-
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
336
|
-
}
|
|
337
|
-
else { // check for endpoint intersections beyond parametric tolerance but within point tolerance
|
|
338
|
-
const pointALocal = lineFraction < 0.5 ? pointA0Local : pointA1Local;
|
|
339
|
-
const pointBLocal = (arcFraction = data.sweep.fractionToSignedPeriodicFraction(arcFraction)) < 0.5 ? pointB0Local : pointB1Local;
|
|
340
|
-
if ((dist2 = pointALocal.distanceSquaredXY(pointBLocal)) !== undefined && Geometry.isDistanceWithinTol(dist2, tol2))
|
|
341
|
-
this.recordPointWithLocalFractions(lineFraction < 0.5 ? 0 : 1, cpA, fractionA0, fractionA1, arcFraction < 0.5 ? 0 : 1, arc, 0, 1, reversed);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
349
|
+
const result = acceptSolution(i, closeApproach);
|
|
350
|
+
if (result)
|
|
351
|
+
this.recordPointWithLocalFractions(result.fLine, cpA, fractionA0, fractionA1, result.fArc, arc, 0, 1, reversed);
|
|
344
352
|
}
|
|
345
353
|
}
|
|
346
354
|
}
|
|
@@ -363,12 +371,23 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
363
371
|
localB.coffs[0], localB.coffs[3], localB.coffs[6], // vector0 xyw
|
|
364
372
|
localB.coffs[1], localB.coffs[4], localB.coffs[7], // vector90 xyw
|
|
365
373
|
ellipseRadians, circleRadians);
|
|
374
|
+
const tol2 = this._coincidentGeometryContext.tolerance * this._coincidentGeometryContext.tolerance;
|
|
366
375
|
// the intersections are transform-invariant, so the solution angles apply directly to the input arcs
|
|
367
376
|
for (let i = 0; i < ellipseRadians.length; i++) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(extendB0, fractionB, extendB1))
|
|
377
|
+
let fractionA = cpA.sweep.radiansToSignedFraction(circleRadians[i], extendA0);
|
|
378
|
+
let fractionB = cpB.sweep.radiansToSignedFraction(ellipseRadians[i], extendB0);
|
|
379
|
+
if (this.acceptFraction(extendA0, fractionA, extendA1) && this.acceptFraction(extendB0, fractionB, extendB1)) {
|
|
371
380
|
this.recordPointWithLocalFractions(fractionA, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
381
|
+
}
|
|
382
|
+
else { // check for endpoint intersection beyond angular tolerance but within point tolerance
|
|
383
|
+
fractionA = cpA.sweep.fractionToSignedPeriodicFraction(fractionA) < 0.5 ? 0 : 1;
|
|
384
|
+
fractionB = cpB.sweep.fractionToSignedPeriodicFraction(fractionB) < 0.5 ? 0 : 1;
|
|
385
|
+
const endPointA = cpA.fractionToPoint(fractionA, CurveCurveIntersectXY._workPointAA0);
|
|
386
|
+
const endPointB = cpB.fractionToPoint(fractionB, CurveCurveIntersectXY._workPointBB0);
|
|
387
|
+
const dist2 = endPointA.distanceSquaredXY(endPointB);
|
|
388
|
+
if (Geometry.isDistanceWithinTol(dist2, tol2))
|
|
389
|
+
this.recordPointWithLocalFractions(fractionA, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
390
|
+
}
|
|
372
391
|
}
|
|
373
392
|
}
|
|
374
393
|
}
|
|
@@ -381,6 +400,15 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
381
400
|
* 5- Convert intersection angles to fractions and record intersections.
|
|
382
401
|
*/
|
|
383
402
|
dispatchArcArc(cpA, extendA0, extendA1, cpB, extendB0, extendB1, reversed) {
|
|
403
|
+
// overlap handling. perspective is not handled.
|
|
404
|
+
if (this._coincidentGeometryContext && !this._worldToLocalPerspective && !this._worldToLocalAffine) {
|
|
405
|
+
const pairs = this._coincidentGeometryContext.coincidentArcIntersectionXY(cpA, cpB, true);
|
|
406
|
+
if (pairs) {
|
|
407
|
+
this.recordPairs(cpA, cpB, pairs, reversed);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// look for isolated intersections
|
|
384
412
|
let matrixA;
|
|
385
413
|
let matrixB;
|
|
386
414
|
if (this._worldToLocalPerspective) {
|
|
@@ -397,27 +425,13 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
397
425
|
}
|
|
398
426
|
const conditionA = matrixA.conditionNumber();
|
|
399
427
|
const conditionB = matrixB.conditionNumber();
|
|
400
|
-
//
|
|
428
|
+
// order the arcs so that the first one we pass in is closer to circular
|
|
401
429
|
if (conditionA > conditionB)
|
|
402
430
|
this.dispatchArcArcThisOrder(cpA, matrixA, extendA0, extendA1, cpB, matrixB, extendB0, extendB1, reversed);
|
|
403
431
|
else
|
|
404
432
|
this.dispatchArcArcThisOrder(cpB, matrixB, extendB0, extendB1, cpA, matrixA, extendA0, extendA1, !reversed);
|
|
405
|
-
// overlap handling. perspective is not handled.
|
|
406
|
-
if (!this._coincidentGeometryContext) {
|
|
407
|
-
// do nothing
|
|
408
|
-
}
|
|
409
|
-
else if (this._worldToLocalPerspective) {
|
|
410
|
-
// do nothing
|
|
411
|
-
}
|
|
412
|
-
else if (this._worldToLocalAffine) {
|
|
413
|
-
// do nothing
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
const pairs = this._coincidentGeometryContext.coincidentArcIntersectionXY(cpA, cpB, true);
|
|
417
|
-
if (pairs !== undefined)
|
|
418
|
-
this.recordPairs(cpA, cpB, pairs, reversed);
|
|
419
|
-
}
|
|
420
433
|
}
|
|
434
|
+
/** Compute the intersection of an arc and a B-spline curve. */
|
|
421
435
|
dispatchArcBsplineCurve3d(cpA, extendA0, extendA1, cpB, extendB0, extendB1, reversed) {
|
|
422
436
|
// Arc: X = C + cU + sV
|
|
423
437
|
// implicitize the arc as viewed. This "3d" matrix is homogeneous "XYW" not "xyz"
|
|
@@ -432,8 +446,6 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
432
446
|
}
|
|
433
447
|
// The worldToLocal has moved the arc vectors into local space.
|
|
434
448
|
// matrixA captures the xyw parts (ignoring z)
|
|
435
|
-
// for any point in world space,
|
|
436
|
-
// THIS CODE ONLY WORKS FOR
|
|
437
449
|
const matrixAInverse = matrixA.inverse();
|
|
438
450
|
if (matrixAInverse) {
|
|
439
451
|
const orderF = cpB.order; // order of the beziers for simple coordinates
|
|
@@ -452,36 +464,34 @@ export class CurveCurveIntersectXY extends RecurseToCurvesGeometryHandler {
|
|
|
452
464
|
const awy = matrixAInverse.at(2, 1);
|
|
453
465
|
const awz = 0.0;
|
|
454
466
|
const aww = matrixAInverse.at(2, 2);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
this.recordPointWithLocalFractions(arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
484
|
-
}
|
|
467
|
+
let bezier;
|
|
468
|
+
for (let spanIndex = 0;; spanIndex++) {
|
|
469
|
+
bezier = cpB.getSaturatedBezierSpan3dH(spanIndex, bezier);
|
|
470
|
+
if (!bezier)
|
|
471
|
+
break;
|
|
472
|
+
if (this._worldToLocalPerspective)
|
|
473
|
+
bezier.tryMultiplyMatrix4dInPlace(this._worldToLocalPerspective);
|
|
474
|
+
else if (this._worldToLocalAffine)
|
|
475
|
+
bezier.tryTransformInPlace(this._worldToLocalAffine);
|
|
476
|
+
univariateBezierG.zero();
|
|
477
|
+
bezier.poleProductsXYZW(coffF, axx, axy, axz, axw);
|
|
478
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, 1.0);
|
|
479
|
+
bezier.poleProductsXYZW(coffF, ayx, ayy, ayz, ayw);
|
|
480
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, 1.0);
|
|
481
|
+
bezier.poleProductsXYZW(coffF, awx, awy, awz, aww);
|
|
482
|
+
univariateBezierG.addSquaredSquaredBezier(coffF, -1.0);
|
|
483
|
+
const roots = univariateBezierG.roots(0.0, true);
|
|
484
|
+
if (roots) {
|
|
485
|
+
for (const root of roots) {
|
|
486
|
+
const fractionB = bezier.fractionToParentFraction(root);
|
|
487
|
+
// The univariate bezier (which has been transformed by the view transform) evaluates into xyw space
|
|
488
|
+
const bcurvePoint4d = bezier.fractionToPoint4d(root);
|
|
489
|
+
const c = bcurvePoint4d.dotProductXYZW(axx, axy, axz, axw);
|
|
490
|
+
const s = bcurvePoint4d.dotProductXYZW(ayx, ayy, ayz, ayw);
|
|
491
|
+
const arcFraction = cpA.sweep.radiansToSignedFraction(Math.atan2(s, c), extendA0);
|
|
492
|
+
if (this.acceptFraction(extendA0, arcFraction, extendA1) &&
|
|
493
|
+
this.acceptFraction(extendB0, fractionB, extendB1)) {
|
|
494
|
+
this.recordPointWithLocalFractions(arcFraction, cpA, 0, 1, fractionB, cpB, 0, 1, reversed);
|
|
485
495
|
}
|
|
486
496
|
}
|
|
487
497
|
}
|