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