@itwin/core-geometry 4.2.0-dev.11 → 4.2.0-dev.12
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/clipping/AlternatingConvexClipTree.d.ts +4 -3
- package/lib/cjs/clipping/AlternatingConvexClipTree.d.ts.map +1 -1
- package/lib/cjs/clipping/AlternatingConvexClipTree.js +1 -1
- package/lib/cjs/clipping/AlternatingConvexClipTree.js.map +1 -1
- package/lib/cjs/clipping/BooleanClipNode.d.ts +4 -3
- package/lib/cjs/clipping/BooleanClipNode.d.ts.map +1 -1
- package/lib/cjs/clipping/BooleanClipNode.js.map +1 -1
- package/lib/cjs/clipping/ClipPlane.d.ts +2 -1
- package/lib/cjs/clipping/ClipPlane.d.ts.map +1 -1
- package/lib/cjs/clipping/ClipPlane.js.map +1 -1
- package/lib/cjs/clipping/ClipUtils.d.ts +4 -4
- package/lib/cjs/clipping/ClipUtils.d.ts.map +1 -1
- package/lib/cjs/clipping/ClipUtils.js +1 -1
- package/lib/cjs/clipping/ClipUtils.js.map +1 -1
- package/lib/cjs/clipping/ClipVector.d.ts +6 -5
- package/lib/cjs/clipping/ClipVector.d.ts.map +1 -1
- package/lib/cjs/clipping/ClipVector.js +1 -1
- package/lib/cjs/clipping/ClipVector.js.map +1 -1
- package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts +3 -2
- package/lib/cjs/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
- package/lib/cjs/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts +2 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
- package/lib/cjs/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/cjs/core-geometry.d.ts +0 -2
- package/lib/cjs/core-geometry.d.ts.map +1 -1
- package/lib/cjs/core-geometry.js +0 -2
- package/lib/cjs/core-geometry.js.map +1 -1
- package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/curve/CurveCollection.d.ts +1 -1
- package/lib/cjs/curve/CurveCollection.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCollection.js +1 -3
- package/lib/cjs/curve/CurveCollection.js.map +1 -1
- package/lib/cjs/curve/CurveCurve.d.ts +38 -26
- package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
- package/lib/cjs/curve/CurveCurve.js +70 -40
- package/lib/cjs/curve/CurveCurve.js.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.d.ts +12 -1
- package/lib/cjs/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/cjs/curve/CurveLocationDetail.js +13 -2
- package/lib/cjs/curve/CurveLocationDetail.js.map +1 -1
- package/lib/cjs/curve/{CurveCurveCloseApproachXY.d.ts → internalContexts/CurveCurveCloseApproachXY.d.ts} +89 -48
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.d.ts.map +1 -0
- package/lib/cjs/curve/{CurveCurveCloseApproachXY.js → internalContexts/CurveCurveCloseApproachXY.js} +196 -155
- package/lib/cjs/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -0
- package/lib/{esm/curve → cjs/curve/internalContexts}/CurveCurveIntersectXY.d.ts +14 -27
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -0
- package/lib/cjs/curve/{CurveCurveIntersectXY.js → internalContexts/CurveCurveIntersectXY.js} +19 -32
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -0
- package/lib/cjs/curve/{CurveCurveIntersectXYZ.d.ts → internalContexts/CurveCurveIntersectXYZ.d.ts} +11 -12
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.d.ts.map +1 -0
- package/lib/cjs/curve/{CurveCurveIntersectXYZ.js → internalContexts/CurveCurveIntersectXYZ.js} +12 -14
- package/lib/cjs/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -0
- package/lib/cjs/geometry3d/BarycentricTriangle.d.ts +1 -0
- package/lib/cjs/geometry3d/BarycentricTriangle.d.ts.map +1 -1
- package/lib/cjs/geometry3d/BarycentricTriangle.js +1 -0
- package/lib/cjs/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/cjs/geometry3d/FrameBuilder.d.ts +28 -11
- package/lib/cjs/geometry3d/FrameBuilder.d.ts.map +1 -1
- package/lib/cjs/geometry3d/FrameBuilder.js +57 -45
- package/lib/cjs/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.d.ts +0 -8
- package/lib/cjs/geometry3d/GrowableXYZArray.d.ts.map +1 -1
- package/lib/cjs/geometry3d/GrowableXYZArray.js +0 -16
- package/lib/cjs/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts +4 -4
- package/lib/cjs/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/cjs/geometry3d/IndexedXYZCollection.js +12 -0
- package/lib/cjs/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/cjs/geometry3d/Point3dArrayCarrier.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Point3dArrayCarrier.js.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.d.ts +1 -1
- package/lib/cjs/geometry3d/PolygonOps.d.ts.map +1 -1
- package/lib/cjs/geometry3d/PolygonOps.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts +3 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js +4 -3
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/cjs/geometry3d/ReusableObjectCache.d.ts +2 -1
- package/lib/cjs/geometry3d/ReusableObjectCache.d.ts.map +1 -1
- package/lib/cjs/geometry3d/ReusableObjectCache.js +1 -1
- package/lib/cjs/geometry3d/ReusableObjectCache.js.map +1 -1
- package/lib/cjs/numerics/Polynomials.d.ts +2 -2
- package/lib/cjs/numerics/Polynomials.d.ts.map +1 -1
- package/lib/cjs/numerics/Polynomials.js +2 -2
- package/lib/cjs/numerics/Polynomials.js.map +1 -1
- package/lib/esm/clipping/AlternatingConvexClipTree.d.ts +4 -3
- package/lib/esm/clipping/AlternatingConvexClipTree.d.ts.map +1 -1
- package/lib/esm/clipping/AlternatingConvexClipTree.js +1 -1
- package/lib/esm/clipping/AlternatingConvexClipTree.js.map +1 -1
- package/lib/esm/clipping/BooleanClipNode.d.ts +4 -3
- package/lib/esm/clipping/BooleanClipNode.d.ts.map +1 -1
- package/lib/esm/clipping/BooleanClipNode.js.map +1 -1
- package/lib/esm/clipping/ClipPlane.d.ts +2 -1
- package/lib/esm/clipping/ClipPlane.d.ts.map +1 -1
- package/lib/esm/clipping/ClipPlane.js.map +1 -1
- package/lib/esm/clipping/ClipUtils.d.ts +4 -4
- package/lib/esm/clipping/ClipUtils.d.ts.map +1 -1
- package/lib/esm/clipping/ClipUtils.js +1 -1
- package/lib/esm/clipping/ClipUtils.js.map +1 -1
- package/lib/esm/clipping/ClipVector.d.ts +6 -5
- package/lib/esm/clipping/ClipVector.d.ts.map +1 -1
- package/lib/esm/clipping/ClipVector.js +1 -1
- package/lib/esm/clipping/ClipVector.js.map +1 -1
- package/lib/esm/clipping/ConvexClipPlaneSet.d.ts +3 -2
- package/lib/esm/clipping/ConvexClipPlaneSet.d.ts.map +1 -1
- package/lib/esm/clipping/ConvexClipPlaneSet.js.map +1 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts +2 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.d.ts.map +1 -1
- package/lib/esm/clipping/UnionOfConvexClipPlaneSets.js.map +1 -1
- package/lib/esm/core-geometry.d.ts +0 -2
- package/lib/esm/core-geometry.d.ts.map +1 -1
- package/lib/esm/core-geometry.js +0 -2
- package/lib/esm/core-geometry.js.map +1 -1
- package/lib/esm/curve/Arc3d.d.ts.map +1 -1
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/curve/CurveCollection.d.ts +1 -1
- package/lib/esm/curve/CurveCollection.d.ts.map +1 -1
- package/lib/esm/curve/CurveCollection.js +1 -3
- package/lib/esm/curve/CurveCollection.js.map +1 -1
- package/lib/esm/curve/CurveCurve.d.ts +38 -26
- package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
- package/lib/esm/curve/CurveCurve.js +70 -40
- package/lib/esm/curve/CurveCurve.js.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.d.ts +12 -1
- package/lib/esm/curve/CurveLocationDetail.d.ts.map +1 -1
- package/lib/esm/curve/CurveLocationDetail.js +11 -1
- package/lib/esm/curve/CurveLocationDetail.js.map +1 -1
- package/lib/esm/curve/{CurveCurveCloseApproachXY.d.ts → internalContexts/CurveCurveCloseApproachXY.d.ts} +89 -48
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.d.ts.map +1 -0
- package/lib/esm/curve/{CurveCurveCloseApproachXY.js → internalContexts/CurveCurveCloseApproachXY.js} +196 -155
- package/lib/esm/curve/internalContexts/CurveCurveCloseApproachXY.js.map +1 -0
- package/lib/{cjs/curve → esm/curve/internalContexts}/CurveCurveIntersectXY.d.ts +14 -27
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.d.ts.map +1 -0
- package/lib/esm/curve/{CurveCurveIntersectXY.js → internalContexts/CurveCurveIntersectXY.js} +18 -30
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXY.js.map +1 -0
- package/lib/esm/curve/{CurveCurveIntersectXYZ.d.ts → internalContexts/CurveCurveIntersectXYZ.d.ts} +11 -12
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.d.ts.map +1 -0
- package/lib/esm/curve/{CurveCurveIntersectXYZ.js → internalContexts/CurveCurveIntersectXYZ.js} +11 -13
- package/lib/esm/curve/internalContexts/CurveCurveIntersectXYZ.js.map +1 -0
- package/lib/esm/geometry3d/BarycentricTriangle.d.ts +1 -0
- package/lib/esm/geometry3d/BarycentricTriangle.d.ts.map +1 -1
- package/lib/esm/geometry3d/BarycentricTriangle.js +1 -0
- package/lib/esm/geometry3d/BarycentricTriangle.js.map +1 -1
- package/lib/esm/geometry3d/FrameBuilder.d.ts +28 -11
- package/lib/esm/geometry3d/FrameBuilder.d.ts.map +1 -1
- package/lib/esm/geometry3d/FrameBuilder.js +57 -45
- package/lib/esm/geometry3d/FrameBuilder.js.map +1 -1
- package/lib/esm/geometry3d/GrowableXYZArray.d.ts +0 -8
- package/lib/esm/geometry3d/GrowableXYZArray.d.ts.map +1 -1
- package/lib/esm/geometry3d/GrowableXYZArray.js +0 -16
- package/lib/esm/geometry3d/GrowableXYZArray.js.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts +4 -4
- package/lib/esm/geometry3d/IndexedXYZCollection.d.ts.map +1 -1
- package/lib/esm/geometry3d/IndexedXYZCollection.js +12 -0
- package/lib/esm/geometry3d/IndexedXYZCollection.js.map +1 -1
- package/lib/esm/geometry3d/Point3dArrayCarrier.d.ts.map +1 -1
- package/lib/esm/geometry3d/Point3dArrayCarrier.js.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.d.ts +1 -1
- package/lib/esm/geometry3d/PolygonOps.d.ts.map +1 -1
- package/lib/esm/geometry3d/PolygonOps.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.d.ts +3 -1
- package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js +4 -3
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/geometry3d/ReusableObjectCache.d.ts +2 -1
- package/lib/esm/geometry3d/ReusableObjectCache.d.ts.map +1 -1
- package/lib/esm/geometry3d/ReusableObjectCache.js +1 -1
- package/lib/esm/geometry3d/ReusableObjectCache.js.map +1 -1
- package/lib/esm/numerics/Polynomials.d.ts +2 -2
- package/lib/esm/numerics/Polynomials.d.ts.map +1 -1
- package/lib/esm/numerics/Polynomials.js +2 -2
- package/lib/esm/numerics/Polynomials.js.map +1 -1
- package/package.json +3 -3
- package/lib/cjs/curve/CurveCurveCloseApproachXY.d.ts.map +0 -1
- package/lib/cjs/curve/CurveCurveCloseApproachXY.js.map +0 -1
- package/lib/cjs/curve/CurveCurveIntersectXY.d.ts.map +0 -1
- package/lib/cjs/curve/CurveCurveIntersectXY.js.map +0 -1
- package/lib/cjs/curve/CurveCurveIntersectXYZ.d.ts.map +0 -1
- package/lib/cjs/curve/CurveCurveIntersectXYZ.js.map +0 -1
- package/lib/esm/curve/CurveCurveCloseApproachXY.d.ts.map +0 -1
- package/lib/esm/curve/CurveCurveCloseApproachXY.js.map +0 -1
- package/lib/esm/curve/CurveCurveIntersectXY.d.ts.map +0 -1
- package/lib/esm/curve/CurveCurveIntersectXY.js.map +0 -1
- package/lib/esm/curve/CurveCurveIntersectXYZ.d.ts.map +0 -1
- package/lib/esm/curve/CurveCurveIntersectXYZ.js.map +0 -1
package/lib/esm/curve/{CurveCurveCloseApproachXY.js → internalContexts/CurveCurveCloseApproachXY.js}
RENAMED
|
@@ -5,32 +5,34 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module Curve
|
|
7
7
|
*/
|
|
8
|
-
import { BSplineCurve3d, BSplineCurve3dBase } from "
|
|
9
|
-
import { Geometry } from "
|
|
10
|
-
import {
|
|
11
|
-
import { GrowableFloat64Array } from "
|
|
12
|
-
import { Point3d, Vector3d } from "
|
|
13
|
-
import { Range3d } from "
|
|
14
|
-
import { AnalyticRoots, SmallSystem } from "
|
|
15
|
-
import { Arc3d } from "
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
8
|
+
import { BSplineCurve3d, BSplineCurve3dBase } from "../../bspline/BSplineCurve";
|
|
9
|
+
import { Geometry } from "../../Geometry";
|
|
10
|
+
import { RecurseToCurvesGeometryHandler } from "../../geometry3d/GeometryHandler";
|
|
11
|
+
import { GrowableFloat64Array } from "../../geometry3d/GrowableFloat64Array";
|
|
12
|
+
import { Point3d, Vector3d } from "../../geometry3d/Point3dVector3d";
|
|
13
|
+
import { Range3d } from "../../geometry3d/Range";
|
|
14
|
+
import { AnalyticRoots, SmallSystem } from "../../numerics/Polynomials";
|
|
15
|
+
import { Arc3d } from "../Arc3d";
|
|
16
|
+
import { CurveChain } from "../CurveCollection";
|
|
17
|
+
import { CurveIntervalRole, CurveLocationDetail, CurveLocationDetailPair } from "../CurveLocationDetail";
|
|
18
|
+
import { LineSegment3d } from "../LineSegment3d";
|
|
19
|
+
import { LineString3d } from "../LineString3d";
|
|
19
20
|
// cspell:word XYRR
|
|
20
21
|
/**
|
|
21
22
|
* Handler class for XY close approach between _geometryB and another geometry.
|
|
22
|
-
* * Approach means the distance between _geometryB and another geometry.
|
|
23
|
-
* * **NOTE:** GeometryQuery input (_geometryB) should really be AnyCurve.
|
|
23
|
+
* * Approach means the XY distance (z is ignored) between _geometryB and another geometry.
|
|
24
24
|
* * Closest approach is a measure of the proximity of one curve to another. It's the length of the shortest line
|
|
25
25
|
* segment perpendicular to both curves; if the curves intersect, the closest approach is zero. In the context of
|
|
26
26
|
* this class, z-coordinates are ignored, so the closest approach is as seen in the top view. If you have coplanar
|
|
27
|
-
* input curves, rotate them first into a plane parallel to the
|
|
28
|
-
* results back as required.
|
|
27
|
+
* input curves and want to find closest approach in their plane, rotate them first into a plane parallel to the
|
|
28
|
+
* xy-plane, then afterward, rotate the results back as required.
|
|
29
|
+
* * Close approach can also be from a curve endpoint perpendicular to another curve or from a curve endpoint to
|
|
30
|
+
* another curve endpoint.
|
|
29
31
|
* * Instances are initialized and called from CurveCurve.
|
|
30
32
|
* * geometryB is saved for later reference.
|
|
31
33
|
* @internal
|
|
32
34
|
*/
|
|
33
|
-
class CurveCurveCloseApproachXY extends
|
|
35
|
+
class CurveCurveCloseApproachXY extends RecurseToCurvesGeometryHandler {
|
|
34
36
|
setGeometryB(geometryB) {
|
|
35
37
|
this._geometryB = geometryB;
|
|
36
38
|
this._circularArcB = undefined;
|
|
@@ -56,13 +58,13 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
56
58
|
this._maxDistanceSquared = Geometry.smallMetricDistanceSquared;
|
|
57
59
|
this.reinitialize();
|
|
58
60
|
}
|
|
59
|
-
/** Set the (possibly undefined) max distance to accept. */
|
|
61
|
+
/** Set the (possibly undefined) max XY distance (z is ignored) to accept. */
|
|
60
62
|
set maxDistanceToAccept(value) {
|
|
61
63
|
this._maxDistanceToAccept = value;
|
|
62
64
|
if (this._maxDistanceToAccept !== undefined && this._maxDistanceToAccept > 0)
|
|
63
65
|
this._maxDistanceSquared = this._maxDistanceToAccept * this._maxDistanceToAccept;
|
|
64
66
|
}
|
|
65
|
-
/** Access the (possibly undefined) max distance to accept. */
|
|
67
|
+
/** Access the (possibly undefined) max XY distance (z is ignored) to accept. */
|
|
66
68
|
get maxDistanceToAccept() {
|
|
67
69
|
return this._maxDistanceToAccept;
|
|
68
70
|
}
|
|
@@ -96,6 +98,10 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
96
98
|
sameCurveAndFraction(cp, fraction, detail) {
|
|
97
99
|
return cp === detail.curve && Geometry.isAlmostEqualNumber(fraction, detail.fraction);
|
|
98
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* If distance between pointA and pointB is less than maxDistance, record CurveLocationDetailPair which is
|
|
103
|
+
* the approach from pointA to pointB.
|
|
104
|
+
*/
|
|
99
105
|
testAndRecordPointPairApproach(cpA, fA, pointA, cpB, fB, pointB, reversed) {
|
|
100
106
|
const d2 = pointA.distanceSquaredXY(pointB);
|
|
101
107
|
if (d2 < this._maxDistanceSquared) {
|
|
@@ -108,12 +114,19 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
108
114
|
}
|
|
109
115
|
}
|
|
110
116
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
117
|
+
* Create a close approach pair if XY distance is within maxDistance.
|
|
118
|
+
* @param localFractionA a fraction on first curve
|
|
119
|
+
* @param cpA the first curve
|
|
120
|
+
* @param fractionA0 start of the first curve
|
|
121
|
+
* @param fractionA1 end of the first curve
|
|
122
|
+
* @param localFractionB a fraction on second curve
|
|
123
|
+
* @param cpB the second curve
|
|
124
|
+
* @param fractionB0 start of the second curve
|
|
125
|
+
* @param fractionB1 end of the second curve
|
|
126
|
+
* @param reversed true to have order reversed in final structures
|
|
127
|
+
* @param intervalDetails optional CurveLocationDetailPair
|
|
114
128
|
*/
|
|
115
|
-
recordPointWithLocalFractions(localFractionA, cpA, fractionA0, fractionA1, localFractionB,
|
|
116
|
-
cpB, fractionB0, fractionB1, reversed, intervalDetails) {
|
|
129
|
+
recordPointWithLocalFractions(localFractionA, cpA, fractionA0, fractionA1, localFractionB, cpB, fractionB0, fractionB1, reversed, intervalDetails) {
|
|
117
130
|
let globalFractionA, globalFractionB;
|
|
118
131
|
let globalFractionA1, globalFractionB1;
|
|
119
132
|
const isInterval = intervalDetails !== undefined &&
|
|
@@ -129,7 +142,7 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
129
142
|
globalFractionA = globalFractionA1 = Geometry.interpolate(fractionA0, localFractionA, fractionA1);
|
|
130
143
|
globalFractionB = globalFractionB1 = Geometry.interpolate(fractionB0, localFractionB, fractionB1);
|
|
131
144
|
}
|
|
132
|
-
// ignore duplicate of most recent
|
|
145
|
+
// ignore duplicate of most recent approach
|
|
133
146
|
const numPrevious = this._results.length;
|
|
134
147
|
if (numPrevious > 0 && !isInterval) {
|
|
135
148
|
const oldDetailA = this._results[numPrevious - 1].detailA;
|
|
@@ -152,6 +165,9 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
152
165
|
detailB.captureFraction1Point1(globalFractionB1, cpB.fractionToPoint(globalFractionB1));
|
|
153
166
|
}
|
|
154
167
|
else {
|
|
168
|
+
const d2 = detailA.point.distanceSquaredXY(detailB.point);
|
|
169
|
+
if (d2 > this._maxDistanceSquared)
|
|
170
|
+
return;
|
|
155
171
|
detailA.setIntervalRole(CurveIntervalRole.isolated);
|
|
156
172
|
detailB.setIntervalRole(CurveIntervalRole.isolated);
|
|
157
173
|
}
|
|
@@ -164,12 +180,21 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
164
180
|
}
|
|
165
181
|
/**
|
|
166
182
|
* Capture a close approach pair that has point and local fraction but not curve.
|
|
167
|
-
* Record with fraction
|
|
183
|
+
* * Record the pair, each detail modified with global fraction and input curve.
|
|
184
|
+
* * Pair is neither modified nor recorded if it would be a duplicate of the last recorded pair.
|
|
185
|
+
* @param pair details computed with local fractions
|
|
186
|
+
* @param cpA curveA
|
|
187
|
+
* @param fractionA0 global start fraction on curveA
|
|
188
|
+
* @param fractionA1 global end fraction on curveA
|
|
189
|
+
* @param cpB curveB
|
|
190
|
+
* @param fractionB0 global start fraction on curveB
|
|
191
|
+
* @param fractionB1 global end fraction on curveB
|
|
192
|
+
* @param reversed whether to reverse the details in the pair
|
|
168
193
|
*/
|
|
169
194
|
capturePairWithLocalFractions(pair, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed) {
|
|
170
195
|
const globalFractionA = Geometry.interpolate(fractionA0, pair.detailA.fraction, fractionA1);
|
|
171
196
|
const globalFractionB = Geometry.interpolate(fractionB0, pair.detailB.fraction, fractionB1);
|
|
172
|
-
// ignore duplicate of most recent
|
|
197
|
+
// ignore duplicate of most recent pair
|
|
173
198
|
const numPrevious = this._results.length;
|
|
174
199
|
if (numPrevious > 0) {
|
|
175
200
|
const oldDetailA = this._results[numPrevious - 1].detailA;
|
|
@@ -185,18 +210,17 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
185
210
|
return;
|
|
186
211
|
}
|
|
187
212
|
}
|
|
213
|
+
if (reversed)
|
|
214
|
+
pair.swapDetails();
|
|
215
|
+
// recompute the points just in case
|
|
216
|
+
CurveLocationDetail.createCurveEvaluatedFraction(cpA, globalFractionA, pair.detailA);
|
|
217
|
+
CurveLocationDetail.createCurveEvaluatedFraction(cpB, globalFractionB, pair.detailB);
|
|
188
218
|
pair.detailA.setIntervalRole(CurveIntervalRole.isolated);
|
|
189
219
|
pair.detailB.setIntervalRole(CurveIntervalRole.isolated);
|
|
190
|
-
|
|
191
|
-
this._results.push(pair);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
pair.swapDetails();
|
|
195
|
-
this._results.push(pair);
|
|
196
|
-
}
|
|
220
|
+
this._results.push(pair);
|
|
197
221
|
}
|
|
198
222
|
/**
|
|
199
|
-
* Emit recordPoint for multiple pairs (on full curve
|
|
223
|
+
* Emit recordPoint for multiple pairs (on full curve) if within maxDistance.
|
|
200
224
|
* @param cpA first curve primitive (possibly different from curve in detailA, but fraction compatible)
|
|
201
225
|
* @param cpB second curve primitive (possibly different from curve in detailA, but fraction compatible)
|
|
202
226
|
* @param pairs array of pairs
|
|
@@ -218,44 +242,40 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
218
242
|
captureDetailPair(detailA, detailB, reversed) {
|
|
219
243
|
if (detailA && detailB) {
|
|
220
244
|
if (reversed) {
|
|
221
|
-
this._results.push(CurveLocationDetailPair.createCapture(
|
|
245
|
+
this._results.push(CurveLocationDetailPair.createCapture(detailB, detailA));
|
|
222
246
|
}
|
|
223
247
|
else {
|
|
224
|
-
this._results.push(CurveLocationDetailPair.createCapture(
|
|
248
|
+
this._results.push(CurveLocationDetailPair.createCapture(detailA, detailB));
|
|
225
249
|
}
|
|
226
250
|
}
|
|
227
251
|
}
|
|
228
|
-
static updatePointToSegmentDistance(fractionA, pointA, pointB0, pointB1, fractionB,
|
|
252
|
+
static updatePointToSegmentDistance(fractionA, pointA, pointB0, pointB1, fractionB, maxDistanceSquared, closestApproach) {
|
|
253
|
+
let updated = false;
|
|
229
254
|
if (fractionB < 0)
|
|
230
255
|
fractionB = 0;
|
|
231
256
|
else if (fractionB > 1)
|
|
232
257
|
fractionB = 1;
|
|
233
258
|
this._workPointB = pointB0.interpolate(fractionB, pointB1, this._workPointB);
|
|
234
259
|
const distanceSquared = this._workPointB.distanceSquaredXY(pointA);
|
|
235
|
-
if (distanceSquared <
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
closestApproach.detailA.setFP(fractionA, pointA);
|
|
240
|
-
closestApproach.detailA.a = distanceSquared;
|
|
241
|
-
closestApproach.detailB.setFP(fractionB, this._workPointB);
|
|
242
|
-
closestApproach.detailA.a = distanceSquared;
|
|
243
|
-
}
|
|
260
|
+
if (distanceSquared < Math.min(maxDistanceSquared, closestApproach.detailA.a)) {
|
|
261
|
+
closestApproach.detailA.setFP(fractionA, pointA, undefined, distanceSquared);
|
|
262
|
+
closestApproach.detailB.setFP(fractionB, this._workPointB, undefined, distanceSquared);
|
|
263
|
+
updated = true;
|
|
244
264
|
}
|
|
245
|
-
return
|
|
265
|
+
return updated;
|
|
246
266
|
}
|
|
247
267
|
/**
|
|
248
|
-
* Return fractions of close approach within
|
|
249
|
-
* *
|
|
250
|
-
* Return the fractional (not xy) coordinates in result.x, result.y
|
|
268
|
+
* Return fractions of close approach within maxDistance between two line segments (a0,a1) and (b0,b1).
|
|
269
|
+
* * Math details can be found at docs/learning/geometry/CurveCurve.md
|
|
251
270
|
* @param a0 start point of line a
|
|
252
|
-
* @param a1
|
|
253
|
-
* @param b0
|
|
271
|
+
* @param a1 end point of line a
|
|
272
|
+
* @param b0 start point of line b
|
|
254
273
|
* @param b1 end point of line b
|
|
255
|
-
* @param
|
|
256
|
-
* is fraction on line
|
|
274
|
+
* @param maxDistanceSquared maximum distance squared (assumed to be positive)
|
|
275
|
+
* @returns the fractional (not xy) coordinates in result.x and result.y. result.x is fraction on line a.
|
|
276
|
+
* result.y is fraction on line b.
|
|
257
277
|
*/
|
|
258
|
-
static segmentSegmentBoundedApproach(a0, a1, b0, b1,
|
|
278
|
+
static segmentSegmentBoundedApproach(a0, a1, b0, b1, maxDistanceSquared) {
|
|
259
279
|
const ux = a1.x - a0.x;
|
|
260
280
|
const uy = a1.y - a0.y;
|
|
261
281
|
const vx = b1.x - b0.x;
|
|
@@ -266,41 +286,60 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
266
286
|
const e01y = b1.y - a0.y;
|
|
267
287
|
const e10x = b0.x - a1.x;
|
|
268
288
|
const e10y = b0.y - a1.y;
|
|
269
|
-
const e11x = b1.x - a1.x;
|
|
270
|
-
const e11y = b1.y - a1.y;
|
|
271
289
|
const hab0 = Geometry.crossProductXYXY(ux, uy, e00x, e00y);
|
|
272
290
|
const hab1 = Geometry.crossProductXYXY(ux, uy, e01x, e01y);
|
|
273
291
|
const hba0 = -Geometry.crossProductXYXY(vx, vy, e00x, e00y);
|
|
274
|
-
const hba1 = -Geometry.crossProductXYXY(vx, vy,
|
|
275
|
-
if (hab0 * hab1 < 0.0 && hba0 * hba1 < 0.0) {
|
|
276
|
-
// true intersection, strictly within both segments !!!
|
|
292
|
+
const hba1 = -Geometry.crossProductXYXY(vx, vy, e10x, e10y);
|
|
293
|
+
if (hab0 * hab1 < 0.0 && hba0 * hba1 < 0.0) { // true intersection, strictly within both segments
|
|
277
294
|
const fractionA = -hba0 / (hba1 - hba0);
|
|
278
295
|
const fractionB = -hab0 / (hab1 - hab0);
|
|
279
296
|
return CurveLocationDetailPair.createCapture(CurveLocationDetail.createCurveFractionPoint(undefined, fractionA, a0.interpolate(fractionA, a1)), CurveLocationDetail.createCurveFractionPoint(undefined, fractionB, b0.interpolate(fractionB, b1)));
|
|
280
297
|
}
|
|
281
|
-
|
|
298
|
+
// there's no intersection, so find the closest approach within maxDistance from an endpoint
|
|
299
|
+
const closestApproach = new CurveLocationDetailPair();
|
|
300
|
+
closestApproach.detailA.a = 2 * maxDistanceSquared; // init to an approach that's too far away
|
|
301
|
+
let reversed = false;
|
|
282
302
|
const uu = Geometry.hypotenuseSquaredXY(ux, uy);
|
|
283
|
-
if (hab0 * hab0 <
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
303
|
+
if (hab0 * hab0 < maxDistanceSquared * uu) { // test distance of b0 to u
|
|
304
|
+
const fractionA = Geometry.dotProductXYXY(ux, uy, e00x, e00y) / uu;
|
|
305
|
+
if (this.updatePointToSegmentDistance(0, b0, a0, a1, fractionA, maxDistanceSquared, closestApproach))
|
|
306
|
+
reversed = true;
|
|
307
|
+
}
|
|
308
|
+
if (hab1 * hab1 < maxDistanceSquared * uu) { // test distance of b1 to u
|
|
309
|
+
const fractionA = Geometry.dotProductXYXY(ux, uy, e01x, e01y) / uu;
|
|
310
|
+
if (this.updatePointToSegmentDistance(1, b1, a0, a1, fractionA, maxDistanceSquared, closestApproach))
|
|
311
|
+
reversed = true;
|
|
312
|
+
}
|
|
287
313
|
const vv = Geometry.hypotenuseSquaredXY(vx, vy);
|
|
288
|
-
if (hba0 * hba0 <
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
314
|
+
if (hba0 * hba0 < maxDistanceSquared * vv) { // test distance of a0 to v
|
|
315
|
+
const fractionB = -Geometry.dotProductXYXY(vx, vy, e00x, e00y) / vv;
|
|
316
|
+
if (this.updatePointToSegmentDistance(0, a0, b0, b1, fractionB, maxDistanceSquared, closestApproach))
|
|
317
|
+
reversed = false;
|
|
318
|
+
}
|
|
319
|
+
if (hba1 * hba1 < maxDistanceSquared * vv) { // test distance of a1 to v
|
|
320
|
+
const fractionB = -Geometry.dotProductXYXY(vx, vy, e10x, e10y) / vv;
|
|
321
|
+
if (this.updatePointToSegmentDistance(1, a1, b0, b1, fractionB, maxDistanceSquared, closestApproach))
|
|
322
|
+
reversed = false;
|
|
323
|
+
}
|
|
324
|
+
if (closestApproach.detailA.a > maxDistanceSquared)
|
|
325
|
+
return undefined;
|
|
326
|
+
if (reversed)
|
|
327
|
+
closestApproach.swapDetails();
|
|
292
328
|
return closestApproach;
|
|
293
329
|
}
|
|
294
330
|
/**
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
* @param
|
|
299
|
-
* @param
|
|
300
|
-
* @param
|
|
301
|
-
* @param
|
|
302
|
-
* @param
|
|
303
|
-
*
|
|
331
|
+
* Check different combination of fractions on curveA and curveB. If distance between points at 2 fractions
|
|
332
|
+
* is less than maxDistance, record CurveLocationDetailPair which is the approach between the 2 points.
|
|
333
|
+
* Optionally, record close approaches of one curve's points if they fall between the other curve's points.
|
|
334
|
+
* @param cpA curveA
|
|
335
|
+
* @param fA0 fraction0 on curveA
|
|
336
|
+
* @param fA1 fraction1 on curveA
|
|
337
|
+
* @param testProjectionOnA whether to record projections of the given curveB points onto curveA
|
|
338
|
+
* @param cpB curveB
|
|
339
|
+
* @param fB0 fraction0 on curveB
|
|
340
|
+
* @param fB1 fraction0 on curveB
|
|
341
|
+
* @param testProjectionOnB whether to record projections of the given curveA points onto curveB
|
|
342
|
+
* @param reversed true to have order reversed in final structures.
|
|
304
343
|
*/
|
|
305
344
|
testAndRecordFractionalPairApproach(cpA, fA0, fA1, testProjectionOnA, cpB, fB0, fB1, testProjectionOnB, reversed) {
|
|
306
345
|
const pointA0 = cpA.fractionToPoint(fA0);
|
|
@@ -320,12 +359,13 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
320
359
|
this.testAndRecordProjection(cpB, fB1, pointB1, cpA, fA0, fA1, !reversed);
|
|
321
360
|
}
|
|
322
361
|
}
|
|
362
|
+
/** Find the closest approach between pointA and cpB. Add the approach if it's within fB0 and fB1. */
|
|
323
363
|
testAndRecordProjection(cpA, fA, pointA, cpB, fB0, fB1, reversed) {
|
|
324
364
|
// NO NO NO -- this is 3D closest point --- need 2d !!
|
|
325
365
|
const detail = cpB.closestPoint(pointA, false);
|
|
326
366
|
if (detail) {
|
|
327
367
|
const fB = Geometry.restrictToInterval(detail.fraction, fB0, fB1);
|
|
328
|
-
if (fB === detail.fraction) {
|
|
368
|
+
if (fB === detail.fraction) { // if fraction is within fB0 and fB1
|
|
329
369
|
this.testAndRecordPointPairApproach(cpA, fA, pointA, cpB, detail.fraction, detail.point, reversed);
|
|
330
370
|
}
|
|
331
371
|
}
|
|
@@ -337,53 +377,69 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
337
377
|
* * The fraction mappings allow portions of a linestring to be passed here.
|
|
338
378
|
*/
|
|
339
379
|
computeSegmentSegment3D(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed) {
|
|
380
|
+
// compute a pair with fractions local to segments
|
|
340
381
|
const approach = CurveCurveCloseApproachXY.segmentSegmentBoundedApproach(pointA0, pointA1, pointB0, pointB1, this._maxDistanceSquared);
|
|
341
|
-
if
|
|
382
|
+
// adjust the pair to refer to input curves and global fractions, then record it if new
|
|
383
|
+
if (approach) {
|
|
384
|
+
approach.detailA.setCurve(cpA);
|
|
385
|
+
approach.detailB.setCurve(cpB);
|
|
342
386
|
this.capturePairWithLocalFractions(approach, cpA, fractionA0, fractionA1, cpB, fractionB0, fractionB1, reversed);
|
|
387
|
+
}
|
|
343
388
|
}
|
|
344
|
-
|
|
345
|
-
// (The line segment in question might be (a) a full line segment or (b) a fragment within a linestring.
|
|
346
|
-
// The fraction and extend parameters allow all combinations to be passed in)
|
|
347
|
-
// This method applies transform.
|
|
389
|
+
/** Low level dispatch of segment with segment. */
|
|
348
390
|
dispatchSegmentSegment(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed) {
|
|
349
391
|
this.computeSegmentSegment3D(cpA, pointA0, fractionA0, pointA1, fractionA1, cpB, pointB0, fractionB0, pointB1, fractionB1, reversed);
|
|
350
392
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
393
|
+
/**
|
|
394
|
+
* Low level dispatch of segment with arc.
|
|
395
|
+
* Find close approaches within maxDistance between a line segments (pointA0, pointA1) and an arc.
|
|
396
|
+
* To consider:
|
|
397
|
+
* 1) arc endpoints to segment endpoints or arc endpoints projection to the segment.
|
|
398
|
+
* 2) intersection between arc and segment.
|
|
399
|
+
* 3) line parallel to arc tangent.
|
|
400
|
+
* @param cpA the segment
|
|
401
|
+
* @param pointA0 start point of the segment
|
|
402
|
+
* @param fractionA0 fraction of the start of the segment
|
|
403
|
+
* @param pointA1 end point of the segment
|
|
404
|
+
* @param fractionA1 fraction of the end of the segment
|
|
405
|
+
* @param arc the arc
|
|
406
|
+
* @param reversed true to have order reversed in final structures
|
|
407
|
+
*/
|
|
354
408
|
dispatchSegmentArc(cpA, pointA0, fractionA0, pointA1, fractionA1, arc, reversed) {
|
|
355
|
-
//
|
|
356
|
-
// 1) endpoint to endpoint or projection
|
|
357
|
-
// 2) true intersection
|
|
358
|
-
// 3) line parallel to arc tangent.
|
|
409
|
+
// 1) arc endpoints to segment endpoints or arc endpoints projection to the segment
|
|
359
410
|
this.testAndRecordFractionalPairApproach(cpA, 0, 1, true, arc, 0, 1, false, reversed);
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
// Arc
|
|
363
|
-
//
|
|
364
|
-
//
|
|
411
|
+
// 2) intersection between arc and segment
|
|
412
|
+
// Suppose:
|
|
413
|
+
// Arc: X = C + cU + sV where c = cos(theta) and s = sin(theta)
|
|
414
|
+
// Line: contains points A0 and A1
|
|
415
|
+
// The arc intersects the line at point X if det(A0, A1, X) = 0 with homogeneous xyw points and vectors.
|
|
416
|
+
// With equational X: det(A0, A1, C) + c*det(A0, A1, U) + s*det(A0, A1, V) = 0.
|
|
365
417
|
// solve for theta.
|
|
366
418
|
// evaluate points.
|
|
367
419
|
// project back to line.
|
|
368
420
|
const data = arc.toTransformedVectors();
|
|
369
421
|
const pointA0Local = pointA0;
|
|
370
422
|
const pointA1Local = pointA1;
|
|
371
|
-
const alpha = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1);
|
|
372
|
-
const beta = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0);
|
|
373
|
-
const gamma = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0);
|
|
423
|
+
const alpha = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.center, 1); // det(A0, A1, C)
|
|
424
|
+
const beta = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector0, 0); // det(A0, A1, U)
|
|
425
|
+
const gamma = Geometry.tripleProductXYW(pointA0Local, 1, pointA1Local, 1, data.vector90, 0); // det(A0, A1, V)
|
|
374
426
|
const cosines = new GrowableFloat64Array(2);
|
|
375
427
|
const sines = new GrowableFloat64Array(2);
|
|
376
428
|
const radians = new GrowableFloat64Array(2);
|
|
377
|
-
const numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(
|
|
429
|
+
const numRoots = AnalyticRoots.appendImplicitLineUnitCircleIntersections(// solve the equation
|
|
430
|
+
alpha, beta, gamma, cosines, sines, radians);
|
|
378
431
|
for (let i = 0; i < numRoots; i++) {
|
|
379
432
|
const arcPoint = data.center.plus2Scaled(data.vector0, cosines.atUncheckedIndex(i), data.vector90, sines.atUncheckedIndex(i));
|
|
380
433
|
const arcFraction = data.sweep.radiansToSignedPeriodicFraction(radians.atUncheckedIndex(i));
|
|
381
434
|
const lineFraction = SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
435
|
+
// only add if the point is within the start and end fractions of both line segment and arc
|
|
382
436
|
if (lineFraction !== undefined && this.acceptFraction(lineFraction) && this.acceptFraction(arcFraction)) {
|
|
383
437
|
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
384
438
|
}
|
|
385
439
|
}
|
|
386
|
-
// line parallel to arc tangent.
|
|
440
|
+
// 3) line parallel to arc tangent.
|
|
441
|
+
// If line does not intersect the arc, then the closest (and/or the furthest) point on arc to the line is a
|
|
442
|
+
// point where the tangent line on arc at that point is parallel to the line.
|
|
387
443
|
const dotUT = data.vector0.crossProductStartEndXY(pointA0, pointA1);
|
|
388
444
|
const dotVT = data.vector90.crossProductStartEndXY(pointA0, pointA1);
|
|
389
445
|
const parallelRadians = Math.atan2(dotVT, dotUT);
|
|
@@ -391,6 +447,7 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
391
447
|
const arcPoint = data.center.plus2Scaled(data.vector0, Math.cos(radians1), data.vector90, Math.sin(radians1));
|
|
392
448
|
const arcFraction = data.sweep.radiansToSignedPeriodicFraction(radians1);
|
|
393
449
|
const lineFraction = SmallSystem.lineSegment3dXYClosestPointUnbounded(pointA0Local, pointA1Local, arcPoint);
|
|
450
|
+
// only add if the point is within the start and end fractions of both line segment and arc
|
|
394
451
|
if (lineFraction !== undefined && this.acceptFraction(lineFraction) && this.acceptFraction(arcFraction)) {
|
|
395
452
|
this.recordPointWithLocalFractions(lineFraction, cpA, fractionA0, fractionA1, arcFraction, arc, 0, 1, reversed);
|
|
396
453
|
}
|
|
@@ -487,63 +544,26 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
487
544
|
this.computeLineStringLineString(lsA, lsB, reversed);
|
|
488
545
|
}
|
|
489
546
|
/** Low level dispatch of segment with (beziers of) a bspline curve */
|
|
490
|
-
dispatchSegmentBsplineCurve(
|
|
547
|
+
dispatchSegmentBsplineCurve(segA, curveB, reversed) {
|
|
491
548
|
const lsB = LineString3d.create();
|
|
492
549
|
curveB.emitStrokes(lsB);
|
|
493
|
-
this.computeSegmentLineString(
|
|
550
|
+
this.computeSegmentLineString(segA, lsB, reversed);
|
|
494
551
|
}
|
|
495
552
|
/** Detail computation for segment approaching linestring. */
|
|
496
|
-
computeSegmentLineString(
|
|
497
|
-
const pointA0 = lsA.point0Ref;
|
|
498
|
-
const pointA1 = lsA.point1Ref;
|
|
499
|
-
let pointB0 = CurveCurveCloseApproachXY._workPointBB0;
|
|
500
|
-
let pointB1 = CurveCurveCloseApproachXY._workPointBB1;
|
|
501
|
-
let pointB2 = CurveCurveCloseApproachXY._workPointBB2;
|
|
502
|
-
let cross0, cross1, cross2;
|
|
503
|
-
let dot0, dot1, dot2;
|
|
504
|
-
const vectorA = CurveCurveCloseApproachXY._workVectorA;
|
|
505
|
-
Vector3d.createStartEnd(pointA0, pointA1, vectorA);
|
|
506
|
-
const aa = vectorA.magnitudeSquared();
|
|
553
|
+
computeSegmentLineString(segA, lsB, reversed) {
|
|
507
554
|
const numB = lsB.numPoints();
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
lsB.packedPoints.getPoint3dAtUncheckedPointIndex(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
// There is a true minimum at point1 ... see if it is within the line
|
|
521
|
-
if (dot1 >= 0.0 && dot1 <= aa) {
|
|
522
|
-
const fractionA1 = dot1 / aa;
|
|
523
|
-
const projection = pointA0.interpolate(dot1 / aa, pointA1);
|
|
524
|
-
if (pointB1.distanceXY(projection) < this._maxDistanceToAccept) {
|
|
525
|
-
const detailA = CurveLocationDetail.createCurveFractionPoint(lsA, fractionA1, projection);
|
|
526
|
-
const detailB = CurveLocationDetail.createCurveFractionPoint(lsB, iB / (numB - 1), pointB2);
|
|
527
|
-
const pair = CurveLocationDetailPair.createCaptureOptionalReverse(detailA, detailB, reversed);
|
|
528
|
-
this._results.push(pair);
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
const tempPoint = pointB0;
|
|
533
|
-
pointB0 = pointB1;
|
|
534
|
-
pointB1 = pointB2;
|
|
535
|
-
pointB2 = tempPoint;
|
|
536
|
-
const tempCross = cross0;
|
|
537
|
-
cross0 = cross1;
|
|
538
|
-
cross1 = cross2;
|
|
539
|
-
cross2 = tempCross;
|
|
540
|
-
const tempDot = dot0;
|
|
541
|
-
dot0 = dot1;
|
|
542
|
-
dot1 = dot2;
|
|
543
|
-
dot2 = tempDot;
|
|
544
|
-
}
|
|
545
|
-
this.testAndRecordFractionalPairApproach(lsA, 0, 1, true, lsB, 0, 1, false, reversed);
|
|
546
|
-
return undefined;
|
|
555
|
+
const deltaFracB = Geometry.safeDivideFraction(1, numB - 1, 0);
|
|
556
|
+
const pointA0 = segA.point0Ref;
|
|
557
|
+
const pointA1 = segA.point1Ref;
|
|
558
|
+
const pointB0 = CurveCurveCloseApproachXY._workPointBB0;
|
|
559
|
+
const pointB1 = CurveCurveCloseApproachXY._workPointBB1;
|
|
560
|
+
for (let i = 0; i < numB - 1; ++i) {
|
|
561
|
+
const fB0 = i * deltaFracB; // global linestring fractions
|
|
562
|
+
const fB1 = (i + 1 === numB - 1) ? 1.0 : (i + 1) * deltaFracB; // make sure we nail the end fraction
|
|
563
|
+
lsB.packedPoints.getPoint3dAtUncheckedPointIndex(i, pointB0);
|
|
564
|
+
lsB.packedPoints.getPoint3dAtUncheckedPointIndex(i + 1, pointB1);
|
|
565
|
+
this.dispatchSegmentSegment(segA, pointA0, 0.0, pointA1, 1.0, lsB, pointB0, fB0, pointB1, fB1, reversed);
|
|
566
|
+
}
|
|
547
567
|
}
|
|
548
568
|
/** Detail computation for arc approaching linestring. */
|
|
549
569
|
computeArcLineString(arcA, lsB, reversed) {
|
|
@@ -564,6 +584,17 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
564
584
|
}
|
|
565
585
|
return undefined;
|
|
566
586
|
}
|
|
587
|
+
/** Low level dispatch of curve chain. */
|
|
588
|
+
dispatchCurveChain(geomA, geomAHandler) {
|
|
589
|
+
const geomB = this._geometryB; // save
|
|
590
|
+
if (!geomB || !(geomB instanceof CurveChain))
|
|
591
|
+
return;
|
|
592
|
+
for (const child of geomB.children) {
|
|
593
|
+
this.resetGeometry(child);
|
|
594
|
+
geomAHandler(geomA);
|
|
595
|
+
}
|
|
596
|
+
this._geometryB = geomB; // restore
|
|
597
|
+
}
|
|
567
598
|
/** Double dispatch handler for strongly typed segment. */
|
|
568
599
|
handleLineSegment3d(segmentA) {
|
|
569
600
|
if (this._geometryB instanceof LineSegment3d) {
|
|
@@ -579,6 +610,9 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
579
610
|
else if (this._geometryB instanceof BSplineCurve3d) {
|
|
580
611
|
this.dispatchSegmentBsplineCurve(segmentA, this._geometryB, false);
|
|
581
612
|
}
|
|
613
|
+
else if (this._geometryB instanceof CurveChain) {
|
|
614
|
+
this.dispatchCurveChain(segmentA, this.handleLineSegment3d.bind(this));
|
|
615
|
+
}
|
|
582
616
|
}
|
|
583
617
|
/**
|
|
584
618
|
* Set bits for comparison to range xy
|
|
@@ -662,6 +696,9 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
662
696
|
else if (this._geometryB instanceof BSplineCurve3d) {
|
|
663
697
|
this.dispatchLineStringBSplineCurve(lsA, this._geometryB, false);
|
|
664
698
|
}
|
|
699
|
+
else if (this._geometryB instanceof CurveChain) {
|
|
700
|
+
this.dispatchCurveChain(lsA, this.handleLineString3d.bind(this));
|
|
701
|
+
}
|
|
665
702
|
return undefined;
|
|
666
703
|
}
|
|
667
704
|
/** Double dispatch handler for strongly typed arc. */
|
|
@@ -678,6 +715,9 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
678
715
|
else if (this._geometryB instanceof BSplineCurve3d) {
|
|
679
716
|
this.dispatchArcBsplineCurve3d(arc0, this._geometryB, false);
|
|
680
717
|
}
|
|
718
|
+
else if (this._geometryB instanceof CurveChain) {
|
|
719
|
+
this.dispatchCurveChain(arc0, this.handleArc3d.bind(this));
|
|
720
|
+
}
|
|
681
721
|
return undefined;
|
|
682
722
|
}
|
|
683
723
|
/** Double dispatch handler for strongly typed bspline curve. */
|
|
@@ -694,6 +734,9 @@ class CurveCurveCloseApproachXY extends NullGeometryHandler {
|
|
|
694
734
|
else if (this._geometryB instanceof BSplineCurve3dBase) {
|
|
695
735
|
this.dispatchBSplineCurve3dBSplineCurve3d(curve, this._geometryB, false);
|
|
696
736
|
}
|
|
737
|
+
else if (this._geometryB instanceof CurveChain) {
|
|
738
|
+
this.dispatchCurveChain(curve, this.handleBSplineCurve3d.bind(this));
|
|
739
|
+
}
|
|
697
740
|
return undefined;
|
|
698
741
|
}
|
|
699
742
|
/** Double dispatch handler for strongly typed homogeneous bspline curve .. */
|
|
@@ -718,8 +761,6 @@ CurveCurveCloseApproachXY._workPointAA0 = Point3d.create();
|
|
|
718
761
|
CurveCurveCloseApproachXY._workPointAA1 = Point3d.create();
|
|
719
762
|
CurveCurveCloseApproachXY._workPointBB0 = Point3d.create();
|
|
720
763
|
CurveCurveCloseApproachXY._workPointBB1 = Point3d.create();
|
|
721
|
-
CurveCurveCloseApproachXY._workPointBB2 = Point3d.create();
|
|
722
|
-
CurveCurveCloseApproachXY._workVectorA = Vector3d.create();
|
|
723
764
|
CurveCurveCloseApproachXY._workPointB = Point3d.create();
|
|
724
765
|
export { CurveCurveCloseApproachXY };
|
|
725
766
|
//# sourceMappingURL=CurveCurveCloseApproachXY.js.map
|