@itwin/core-geometry 5.0.0-dev.62 → 5.0.0-dev.65
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/bspline/BSpline1dNd.d.ts +90 -54
- package/lib/cjs/bspline/BSpline1dNd.d.ts.map +1 -1
- package/lib/cjs/bspline/BSpline1dNd.js +134 -99
- package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
- package/lib/cjs/bspline/BSplineCurve.d.ts +193 -155
- package/lib/cjs/bspline/BSplineCurve.d.ts.map +1 -1
- package/lib/cjs/bspline/BSplineCurve.js +245 -181
- package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
- package/lib/cjs/bspline/BezierCurve3d.d.ts +3 -1
- package/lib/cjs/bspline/BezierCurve3d.d.ts.map +1 -1
- package/lib/cjs/bspline/BezierCurve3d.js +3 -5
- package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
- package/lib/cjs/bspline/KnotVector.d.ts +74 -54
- package/lib/cjs/bspline/KnotVector.d.ts.map +1 -1
- package/lib/cjs/bspline/KnotVector.js +127 -80
- package/lib/cjs/bspline/KnotVector.js.map +1 -1
- package/lib/cjs/curve/Arc3d.d.ts +2 -0
- package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
- package/lib/cjs/curve/Arc3d.js +2 -0
- package/lib/cjs/curve/Arc3d.js.map +1 -1
- package/lib/cjs/geometry3d/PointHelpers.d.ts +3 -3
- package/lib/cjs/geometry3d/PointHelpers.js +3 -3
- package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.d.ts +2 -2
- package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Ray3d.js +8 -11
- package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
- package/lib/esm/bspline/BSpline1dNd.d.ts +90 -54
- package/lib/esm/bspline/BSpline1dNd.d.ts.map +1 -1
- package/lib/esm/bspline/BSpline1dNd.js +134 -99
- package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
- package/lib/esm/bspline/BSplineCurve.d.ts +193 -155
- package/lib/esm/bspline/BSplineCurve.d.ts.map +1 -1
- package/lib/esm/bspline/BSplineCurve.js +245 -181
- package/lib/esm/bspline/BSplineCurve.js.map +1 -1
- package/lib/esm/bspline/BezierCurve3d.d.ts +3 -1
- package/lib/esm/bspline/BezierCurve3d.d.ts.map +1 -1
- package/lib/esm/bspline/BezierCurve3d.js +3 -5
- package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
- package/lib/esm/bspline/KnotVector.d.ts +74 -54
- package/lib/esm/bspline/KnotVector.d.ts.map +1 -1
- package/lib/esm/bspline/KnotVector.js +127 -80
- package/lib/esm/bspline/KnotVector.js.map +1 -1
- package/lib/esm/curve/Arc3d.d.ts +2 -0
- package/lib/esm/curve/Arc3d.d.ts.map +1 -1
- package/lib/esm/curve/Arc3d.js +2 -0
- package/lib/esm/curve/Arc3d.js.map +1 -1
- package/lib/esm/geometry3d/PointHelpers.d.ts +3 -3
- package/lib/esm/geometry3d/PointHelpers.js +3 -3
- package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
- package/lib/esm/geometry3d/Ray3d.d.ts +2 -2
- package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Ray3d.js +8 -11
- package/lib/esm/geometry3d/Ray3d.js.map +1 -1
- package/package.json +5 -5
|
@@ -28,83 +28,117 @@ import { BSplineCurveOps } from "./BSplineCurveOps";
|
|
|
28
28
|
import { BSplineWrapMode, KnotVector } from "./KnotVector";
|
|
29
29
|
/**
|
|
30
30
|
* Base class for BSplineCurve3d and BSplineCurve3dH.
|
|
31
|
-
* * A
|
|
32
|
-
* * The
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* * A B-spline curve consists of an array of `knots`, an array of `poles`, and a `degree`.
|
|
32
|
+
* * The knot array is a non-decreasing sequence of numbers. It is also called a "knot vector".
|
|
33
|
+
* * The curve is a parametric function whose domain is a sub-range of its knots.
|
|
34
|
+
* * The API sometimes refers to a domain parameter `u` as a "knot", even if `u` is not actually an entry in the
|
|
35
|
+
* knot array.
|
|
36
|
+
* * The curve loosely "follows" the line string formed by the poles, aka the "control polygon".
|
|
37
|
+
* * The curve is a chain of polynomial segments, aka "spans" or "fragments". B-spline theory identifies these as
|
|
38
|
+
* Bezier curves.
|
|
35
39
|
* * The polynomial spans all have same `degree`.
|
|
36
|
-
* *
|
|
37
|
-
* *
|
|
38
|
-
* * The number of spans is `numSpan = numPoles - degree
|
|
39
|
-
* * For a
|
|
40
|
-
* * The `order` poles begin at index `spanIndex`.
|
|
41
|
-
* * The `2*
|
|
42
|
-
* * The
|
|
43
|
-
* * The
|
|
40
|
+
* * Each span is controlled by `order = degree + 1` contiguous points in the pole array.
|
|
41
|
+
* * There is a strict relationship between knot and poles counts: `numPoles + order = numKnots + 2'.
|
|
42
|
+
* * The number of spans is `numSpan = numPoles - degree`.
|
|
43
|
+
* * For a span with index `spanIndex`:
|
|
44
|
+
* * The `order` relevant poles begin at pole index `spanIndex`.
|
|
45
|
+
* * The `2*degree` relevant knots begin at knot index `spanIndex`.
|
|
46
|
+
* * The span domain is the knot range `[knot[spanIndex+degree-1], knot[spanIndex+degree]]`.
|
|
47
|
+
* * The curve domain is the knot range `[knot[degree-1], knot[numSpan+degree-1]]`, or equivalently
|
|
48
|
+
* `[knot[degree-1], knot[numPoles-1]]`. The API refers to this domain as the "active knot interval" of the curve.
|
|
44
49
|
*
|
|
45
|
-
* Nearly all
|
|
46
|
-
* *
|
|
47
|
-
*
|
|
48
|
-
* *
|
|
49
|
-
*
|
|
50
|
-
*
|
|
50
|
+
* Nearly all B-spline curves are "clamped".
|
|
51
|
+
* * This means that in the `knots` array, the first `degree` knots are equal, and the last `degree` knots are equal.
|
|
52
|
+
* We say the smallest knot and the largest knot have multiplicity `degree`.
|
|
53
|
+
* * Clamping make the curve pass through its first and last poles, with tangents directed along the first and
|
|
54
|
+
* last edges of the control polygon.
|
|
55
|
+
* * For instance, a cubic B-spline curve with knot vector `[0,0,0,1,2,3,3,3]`
|
|
56
|
+
* * can be evaluated at parameter values in the range `[0, 3]`
|
|
57
|
+
* * has 3 spans, with domains `[0, 1]`, `[1, 2]`, and `[2, 3]`
|
|
51
58
|
* * has 6 poles
|
|
52
59
|
* * passes through its first and last poles.
|
|
53
|
-
* * `create` methods may allow classic convention that has an extra knot at the beginning and end of the
|
|
54
|
-
*
|
|
55
|
-
* *
|
|
60
|
+
* * The `create` methods may allow the classic convention that has an extra knot at the beginning and end of the
|
|
61
|
+
* knot vector.
|
|
62
|
+
* * These two extra knots are not actually needed to define the B-spline curve.
|
|
63
|
+
* * When the `create` methods recognize the classic setup (`numPoles + order = numKnots`), the extra knots are
|
|
64
|
+
* not saved with the BSplineCurve3dBase knots.
|
|
56
65
|
*
|
|
57
|
-
* * The weighted variant has the problem that CurvePrimitive
|
|
58
|
-
*
|
|
66
|
+
* * The weighted variant [[BSplineCurve3dH]] has the problem that `CurvePrimitive` 3D typing does not allow the
|
|
67
|
+
* undefined result where a homogeneous pole has zero weight; the convention in this case is to return 000.
|
|
59
68
|
*
|
|
60
69
|
* * Note the class relationships:
|
|
61
|
-
* * BSpline1dNd knows the
|
|
62
|
-
* * BsplineCurve3dBase owns a protected BSpline1dNd
|
|
63
|
-
* * BsplineCurve3dBase is derived from CurvePrimitive, which creates obligation to act as a 3D curve,
|
|
64
|
-
* * evaluate fraction to point and derivatives wrt fraction
|
|
65
|
-
* * compute intersection with plane
|
|
66
|
-
* * BSplineCurve3d and BSplineCurve3dH have variant logic driven by whether or not there are "weights" on the poles.
|
|
67
|
-
* * For `BSplineCurve3d`, the xyz value of pole calculations are "final" values for 3d evaluation
|
|
70
|
+
* * [[BSpline1dNd]] knows the definitional B-spline recurrence relation with no physical interpretation for the poles.
|
|
71
|
+
* * BsplineCurve3dBase owns a protected BSpline1dNd.
|
|
72
|
+
* * `BsplineCurve3dBase` is derived from [[CurvePrimitive]], which creates obligation to act as a 3D curve, e.g.,
|
|
73
|
+
* * evaluate fraction to point and derivatives wrt fraction.
|
|
74
|
+
* * compute intersection with plane.
|
|
75
|
+
* * [[BSplineCurve3d]] and [[BSplineCurve3dH]] have variant logic driven by whether or not there are "weights" on the poles.
|
|
76
|
+
* * For `BSplineCurve3d`, the xyz value of pole calculations are "final" values for 3d evaluation.
|
|
68
77
|
* * For `BSplineCurve3dH`, various `BSpline1dNd` results with xyzw have to be normalized back to xyz.
|
|
69
78
|
*
|
|
70
79
|
* * These classes do not support "periodic" variants.
|
|
71
|
-
* * Periodic curves
|
|
80
|
+
* * Periodic curves historically have carried a flag (e.g., "closed") indicating that certain un-stored
|
|
81
|
+
* leading/trailing knots and poles are understood to wrap around periodically.
|
|
82
|
+
* * Instead, these classes carry no such flag. They represent such curves with explicitly wrapped knots/poles.
|
|
83
|
+
*
|
|
84
|
+
* * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
|
|
72
85
|
* @public
|
|
73
86
|
*/
|
|
74
87
|
export class BSplineCurve3dBase extends CurvePrimitive {
|
|
75
|
-
/** String name for schema properties */
|
|
88
|
+
/** String name for schema properties. */
|
|
76
89
|
curvePrimitiveType = "bsplineCurve";
|
|
77
|
-
/** The underlying blocked-pole spline, with simple x,y,z poles */
|
|
90
|
+
/** The underlying blocked-pole spline, with simple x,y,z poles. */
|
|
78
91
|
_bcurve;
|
|
79
92
|
_definitionData;
|
|
80
|
-
set definitionData(data) {
|
|
81
|
-
|
|
93
|
+
set definitionData(data) {
|
|
94
|
+
this._definitionData = data;
|
|
95
|
+
}
|
|
96
|
+
get definitionData() {
|
|
97
|
+
return this._definitionData;
|
|
98
|
+
}
|
|
82
99
|
constructor(poleDimension, numPoles, order, knots) {
|
|
83
100
|
super();
|
|
84
101
|
this._bcurve = BSpline1dNd.create(numPoles, poleDimension, order, knots);
|
|
85
102
|
}
|
|
86
|
-
/** Return the degree (one less than the order) of the curve */
|
|
87
|
-
get degree() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/** Return the
|
|
91
|
-
get
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
get knotsRef() { return this._bcurve.knots.knots; }
|
|
98
|
-
/** Number of components per pole.
|
|
99
|
-
* * 3 for conventional (x,y,z) curve
|
|
100
|
-
* * 4 for weighted (wx,wy,wz,w) curve
|
|
103
|
+
/** Return the degree (one less than the order) of the curve. */
|
|
104
|
+
get degree() {
|
|
105
|
+
return this._bcurve.degree;
|
|
106
|
+
}
|
|
107
|
+
/** Return the order (one more than degree) of the curve. */
|
|
108
|
+
get order() {
|
|
109
|
+
return this._bcurve.order;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Return the number of Bezier spans in the curve. Note that this number includes the number of null
|
|
113
|
+
* spans at repeated knows.
|
|
101
114
|
*/
|
|
102
|
-
get
|
|
115
|
+
get numSpan() {
|
|
116
|
+
return this._bcurve.numSpan;
|
|
117
|
+
}
|
|
118
|
+
/** Return the number of poles. */
|
|
119
|
+
get numPoles() {
|
|
120
|
+
return this._bcurve.numPoles;
|
|
121
|
+
}
|
|
122
|
+
/** Return live reference to the poles of the curve. */
|
|
123
|
+
get polesRef() {
|
|
124
|
+
return this._bcurve.packedData;
|
|
125
|
+
}
|
|
126
|
+
/** Return live reference to the knots of the curve. */
|
|
127
|
+
get knotsRef() {
|
|
128
|
+
return this._bcurve.knots.knots;
|
|
129
|
+
}
|
|
103
130
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
131
|
+
* Number of components per pole, e.g.,
|
|
132
|
+
* * 3 for conventional (x,y,z) curve.
|
|
133
|
+
* * 4 for weighted (wx,wy,wz,w) curve.
|
|
106
134
|
*/
|
|
107
|
-
|
|
135
|
+
get poleDimension() {
|
|
136
|
+
return this._bcurve.poleLength;
|
|
137
|
+
}
|
|
138
|
+
/** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
|
|
139
|
+
copyKnots(includeExtraEndKnot) {
|
|
140
|
+
return this._bcurve.knots.copyKnots(includeExtraEndKnot);
|
|
141
|
+
}
|
|
108
142
|
/** Get the flag indicating the curve might be suitable for having wrapped "closed" interpretation. */
|
|
109
143
|
getWrappable() {
|
|
110
144
|
return this._bcurve.knots.wrappable;
|
|
@@ -114,7 +148,7 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
114
148
|
this._bcurve.knots.wrappable = value;
|
|
115
149
|
}
|
|
116
150
|
/**
|
|
117
|
-
* Test knots and
|
|
151
|
+
* Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
|
|
118
152
|
* @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
|
|
119
153
|
*/
|
|
120
154
|
get isClosableCurve() {
|
|
@@ -127,25 +161,18 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
127
161
|
return BSplineWrapMode.None;
|
|
128
162
|
return mode;
|
|
129
163
|
}
|
|
130
|
-
/** Evaluate the curve point at
|
|
164
|
+
/** Evaluate the curve point at the given fractional parameter. */
|
|
131
165
|
fractionToPoint(fraction, result) {
|
|
132
166
|
return this.knotToPoint(this._bcurve.knots.fractionToKnot(fraction), result);
|
|
133
167
|
}
|
|
134
|
-
/**
|
|
135
|
-
* * origin at the fractional position along the arc
|
|
136
|
-
* * direction is the first derivative, i.e. tangent along the curve
|
|
137
|
-
*/
|
|
168
|
+
/** Evaluate the curve and derivative at the given fractional parameter. */
|
|
138
169
|
fractionToPointAndDerivative(fraction, result) {
|
|
139
170
|
const knot = this._bcurve.knots.fractionToKnot(fraction);
|
|
140
171
|
result = this.knotToPointAndDerivative(knot, result);
|
|
141
172
|
result.direction.scaleInPlace(this._bcurve.knots.knotLength01);
|
|
142
173
|
return result;
|
|
143
174
|
}
|
|
144
|
-
/**
|
|
145
|
-
* * origin at the fractional position along the arc
|
|
146
|
-
* * x axis is the first derivative, i.e. tangent along the curve
|
|
147
|
-
* * y axis is the second derivative
|
|
148
|
-
*/
|
|
175
|
+
/** Evaluate the curve and two derivatives at the given fractional parameter. */
|
|
149
176
|
fractionToPointAnd2Derivatives(fraction, result) {
|
|
150
177
|
const knot = this._bcurve.knots.fractionToKnot(fraction);
|
|
151
178
|
result = this.knotToPointAnd2Derivatives(knot, result);
|
|
@@ -154,22 +181,23 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
154
181
|
result.vectorV.scaleInPlace(a * a);
|
|
155
182
|
return result;
|
|
156
183
|
}
|
|
184
|
+
/** Return the start point of the curve. */
|
|
185
|
+
startPoint() {
|
|
186
|
+
return this.evaluatePointInSpan(0, 0.0);
|
|
187
|
+
}
|
|
188
|
+
/** Return the end point of the curve. */
|
|
189
|
+
endPoint() {
|
|
190
|
+
return this.evaluatePointInSpan(this.numSpan - 1, 1.0);
|
|
191
|
+
}
|
|
157
192
|
/**
|
|
158
|
-
*
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Return the end point of the curve
|
|
163
|
-
*/
|
|
164
|
-
endPoint() { return this.evaluatePointInSpan(this.numSpan - 1, 1.0); }
|
|
165
|
-
/** Reverse the curve in place.
|
|
166
|
-
* * Poles are reversed
|
|
167
|
-
* * knot values are mirrored around the middle of the
|
|
168
|
-
*/
|
|
169
|
-
reverseInPlace() { this._bcurve.reverseInPlace(); }
|
|
170
|
-
/**
|
|
171
|
-
* Return an array with this curve's bezier fragments.
|
|
193
|
+
* Reverse the curve in place.
|
|
194
|
+
* * Poles are reversed.
|
|
195
|
+
* * Knot values are mirrored around the middle of the knot array.
|
|
172
196
|
*/
|
|
197
|
+
reverseInPlace() {
|
|
198
|
+
this._bcurve.reverseInPlace();
|
|
199
|
+
}
|
|
200
|
+
/** Return an array with this curve's Bezier fragments. */
|
|
173
201
|
collectBezierSpans(prefer3dH) {
|
|
174
202
|
const result = [];
|
|
175
203
|
const numSpans = this.numSpan;
|
|
@@ -188,17 +216,18 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
188
216
|
return poleIndex * this._bcurve.poleLength;
|
|
189
217
|
return undefined;
|
|
190
218
|
}
|
|
191
|
-
/**
|
|
192
|
-
*
|
|
219
|
+
/**
|
|
220
|
+
* Search for the curve point that is closest to the spacePoint.
|
|
193
221
|
* * If the space point is exactly on the curve, this is the reverse of fractionToPoint.
|
|
194
|
-
* * Since CurvePrimitive should always have start and end available as candidate points, this method should always
|
|
195
|
-
*
|
|
222
|
+
* * Since CurvePrimitive should always have start and end available as candidate points, this method should always
|
|
223
|
+
* succeed.
|
|
224
|
+
* @param spacePoint point in space.
|
|
196
225
|
* @param _extend ignored (pass false). A BSplineCurve3dBase cannot be extended.
|
|
197
226
|
* @param result optional pre-allocated detail to populate and return.
|
|
198
227
|
* @returns details of the closest point.
|
|
199
228
|
*/
|
|
200
229
|
closestPoint(spacePoint, _extend, result) {
|
|
201
|
-
// seed at start point
|
|
230
|
+
// seed at start point; final point comes with final bezier perpendicular step
|
|
202
231
|
const point = this.fractionToPoint(0);
|
|
203
232
|
result = CurveLocationDetail.createCurveFractionPointDistance(this, 0.0, point, point.distance(spacePoint), result);
|
|
204
233
|
let span;
|
|
@@ -207,9 +236,9 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
207
236
|
if (this._bcurve.knots.isIndexOfRealSpan(i)) {
|
|
208
237
|
span = this.getSaturatedBezierSpan3dOr3dH(i, true, span);
|
|
209
238
|
if (span) {
|
|
210
|
-
//
|
|
239
|
+
// if the B-spline is discontinuous, both ends should be tested; ignore that possibility
|
|
211
240
|
if (span.updateClosestPointByTruePerpendicular(spacePoint, result, false, true)) {
|
|
212
|
-
// the detail records the span bezier
|
|
241
|
+
// the detail records the span bezier; promote it to the parent curve
|
|
213
242
|
result.curve = this;
|
|
214
243
|
result.fraction = span.fractionToParentFraction(result.fraction);
|
|
215
244
|
}
|
|
@@ -220,13 +249,14 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
220
249
|
}
|
|
221
250
|
/** Return a transformed deep clone. */
|
|
222
251
|
cloneTransformed(transform) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
return
|
|
252
|
+
const curve = this.clone();
|
|
253
|
+
curve.tryTransformInPlace(transform);
|
|
254
|
+
return curve;
|
|
226
255
|
}
|
|
227
|
-
/**
|
|
228
|
-
*
|
|
229
|
-
* @param
|
|
256
|
+
/**
|
|
257
|
+
* Return a curve primitive which is a portion of this curve.
|
|
258
|
+
* @param fractionA start fraction.
|
|
259
|
+
* @param fractionB end fraction.
|
|
230
260
|
*/
|
|
231
261
|
clonePartialCurve(fractionA, fractionB) {
|
|
232
262
|
const clone = this.clone();
|
|
@@ -237,11 +267,8 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
237
267
|
clone._bcurve.addKnot(knotB, clone.degree);
|
|
238
268
|
if (origNumKnots === clone._bcurve.knots.knots.length)
|
|
239
269
|
return clone; // full curve
|
|
240
|
-
if (knotA > knotB)
|
|
241
|
-
|
|
242
|
-
knotA = knotB;
|
|
243
|
-
knotB = tmp;
|
|
244
|
-
}
|
|
270
|
+
if (knotA > knotB)
|
|
271
|
+
[knotA, knotB] = [knotB, knotA];
|
|
245
272
|
// choose first/last knot and pole such that knotA/knotB has degree multiplicity in the new knot sequence
|
|
246
273
|
const iStartKnot = clone._bcurve.knots.knotToLeftKnotIndex(knotA) - clone.degree + 1;
|
|
247
274
|
const iStartPole = iStartKnot * clone._bcurve.poleLength;
|
|
@@ -251,15 +278,17 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
251
278
|
iLastKnotLeftMultiple = iLastKnot + 1;
|
|
252
279
|
const iEndPole = (iLastKnotLeftMultiple + 1) * clone._bcurve.poleLength; // one past last pole
|
|
253
280
|
const iEndKnot = iLastKnotLeftMultiple + clone.degree; // one past last knot
|
|
254
|
-
// trim the arrays (leave knots unnormalized
|
|
281
|
+
// trim the arrays (leave knots unnormalized)
|
|
255
282
|
clone._bcurve.knots.setKnotsCapture(clone._bcurve.knots.knots.slice(iStartKnot, iEndKnot));
|
|
256
283
|
clone._bcurve.packedData = clone._bcurve.packedData.slice(iStartPole, iEndPole);
|
|
257
284
|
clone.setWrappable(BSplineWrapMode.None); // always open
|
|
258
285
|
return clone;
|
|
259
286
|
}
|
|
260
|
-
/**
|
|
261
|
-
*
|
|
262
|
-
* @param
|
|
287
|
+
/**
|
|
288
|
+
* Implement `CurvePrimitive.appendPlaneIntersections` to compute intersections of the curve with a plane.
|
|
289
|
+
* @param plane the plane with which to intersect the curve. Concrete types include [[Plane3dByOriginAndUnitNormal]],
|
|
290
|
+
* [[Point4d]], etc.
|
|
291
|
+
* @param result growing array of plane intersections.
|
|
263
292
|
* @return number of intersections appended to the array.
|
|
264
293
|
*/
|
|
265
294
|
appendPlaneIntersectionPoints(plane, result) {
|
|
@@ -270,34 +299,32 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
270
299
|
const point4d = Point4d.create();
|
|
271
300
|
// compute all pole altitudes from the plane
|
|
272
301
|
const minMax = Range1d.createNull();
|
|
273
|
-
//
|
|
302
|
+
// put the altitudes of all the B-spline poles in one array
|
|
274
303
|
for (let i = 0; i < numPole; i++) {
|
|
275
304
|
allCoffs[i] = plane.weightedAltitude(this.getPolePoint4d(i, point4d));
|
|
276
305
|
minMax.extendX(allCoffs[i]);
|
|
277
306
|
}
|
|
278
|
-
// A univariate
|
|
307
|
+
// A univariate B-spline through the altitude poles gives altitude as function of the B-spline knot.
|
|
279
308
|
// The (bspline) altitude function for each span is `order` consecutive altitudes.
|
|
280
309
|
// If those altitudes bracket zero, the span may potentially have a crossing.
|
|
281
|
-
// When that occurs,
|
|
282
310
|
let univariateBezier;
|
|
283
311
|
let numFound = 0;
|
|
284
312
|
let previousFraction = -1000.0;
|
|
285
313
|
if (minMax.containsX(0.0)) {
|
|
286
314
|
for (let spanIndex = 0; spanIndex < numSpan; spanIndex++) {
|
|
287
|
-
if (this._bcurve.knots.isIndexOfRealSpan(spanIndex)) { // ignore trivial knot intervals
|
|
315
|
+
if (this._bcurve.knots.isIndexOfRealSpan(spanIndex)) { // ignore trivial knot intervals
|
|
288
316
|
// outer range test ...
|
|
289
317
|
minMax.setNull();
|
|
290
318
|
minMax.extendArraySubset(allCoffs, spanIndex, order);
|
|
291
319
|
if (minMax.containsX(0.0)) {
|
|
292
|
-
// pack the
|
|
320
|
+
// pack the B-spline support into a univariate bezier
|
|
293
321
|
univariateBezier = UnivariateBezier.createArraySubset(allCoffs, spanIndex, order, univariateBezier);
|
|
294
322
|
// saturate and solve the bezier
|
|
295
323
|
Bezier1dNd.saturate1dInPlace(univariateBezier.coffs, this._bcurve.knots, spanIndex);
|
|
296
324
|
const roots = univariateBezier.roots(0.0, true);
|
|
297
325
|
if (roots) {
|
|
298
326
|
for (const spanFraction of roots) {
|
|
299
|
-
// promote each local bezier fraction to global fraction
|
|
300
|
-
// save the curve evaluation at that fraction.
|
|
327
|
+
// promote each local bezier fraction to global fraction and save the curve evaluation at that fraction
|
|
301
328
|
numFound++;
|
|
302
329
|
const fraction = this._bcurve.knots.spanFractionToFraction(spanIndex, spanFraction);
|
|
303
330
|
if (!Geometry.isAlmostEqualNumber(fraction, previousFraction)) {
|
|
@@ -316,9 +343,7 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
316
343
|
}
|
|
317
344
|
/**
|
|
318
345
|
* Construct an offset of the instance curve as viewed in the xy-plane (ignoring z).
|
|
319
|
-
*
|
|
320
|
-
* for an aggregate instance (e.g., LineString3d, CurveChainWithDistanceIndex), use RegionOps.constructCurveXYOffset() instead.
|
|
321
|
-
* @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object
|
|
346
|
+
* @param offsetDistanceOrOptions offset distance (positive to left of the instance curve), or options object.
|
|
322
347
|
*/
|
|
323
348
|
constructOffsetXY(offsetDistanceOrOptions) {
|
|
324
349
|
const options = OffsetOptions.create(offsetDistanceOrOptions);
|
|
@@ -326,18 +351,21 @@ export class BSplineCurve3dBase extends CurvePrimitive {
|
|
|
326
351
|
this.emitStrokableParts(handler, options.strokeOptions);
|
|
327
352
|
return handler.claimResult();
|
|
328
353
|
}
|
|
329
|
-
/**
|
|
354
|
+
/**
|
|
355
|
+
* Project instance geometry (via dispatch) onto the given ray, and return the extreme fractional parameters
|
|
356
|
+
* of projection.
|
|
330
357
|
* @param ray ray onto which the instance is projected. A `Vector3d` is treated as a `Ray3d` with zero origin.
|
|
331
|
-
* @param lowHigh optional receiver for output
|
|
332
|
-
* @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the
|
|
358
|
+
* @param lowHigh optional receiver for output.
|
|
359
|
+
* @returns range of fractional projection parameters onto the ray, where 0.0 is start of the ray and 1.0 is the
|
|
360
|
+
* end of the ray.
|
|
333
361
|
*/
|
|
334
362
|
projectedParameterRange(ray, lowHigh) {
|
|
335
363
|
return PlaneAltitudeRangeContext.findExtremeFractionsAlongDirection(this, ray, lowHigh);
|
|
336
364
|
}
|
|
337
365
|
}
|
|
338
366
|
/**
|
|
339
|
-
* A BSplineCurve3d is a
|
|
340
|
-
* See BSplineCurve3dBase for description of knots, order, degree.
|
|
367
|
+
* A BSplineCurve3d is a B-spline curve whose poles are Point3d.
|
|
368
|
+
* See BSplineCurve3dBase for description of knots, order, degree, and poles.
|
|
341
369
|
* @public
|
|
342
370
|
*/
|
|
343
371
|
export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
@@ -347,11 +375,19 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
347
375
|
this._workBezier = BezierCurve3d.createOrder(this.order);
|
|
348
376
|
return this._workBezier;
|
|
349
377
|
}
|
|
350
|
-
|
|
351
|
-
|
|
378
|
+
constructor(numPoles, order, knots) {
|
|
379
|
+
super(3, numPoles, order, knots);
|
|
380
|
+
}
|
|
381
|
+
/** Test if `other` is an instance of BSplineCurve3d. */
|
|
382
|
+
isSameGeometryClass(other) {
|
|
383
|
+
return other instanceof BSplineCurve3d;
|
|
384
|
+
}
|
|
352
385
|
/** Apply `transform` to the poles. */
|
|
353
|
-
tryTransformInPlace(transform) {
|
|
354
|
-
|
|
386
|
+
tryTransformInPlace(transform) {
|
|
387
|
+
Point3dArray.multiplyInPlace(transform, this._bcurve.packedData);
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
/** Get a pole as a simple Point3d. */
|
|
355
391
|
getPolePoint3d(poleIndex, result) {
|
|
356
392
|
const k = this.poleIndexToDataIndex(poleIndex);
|
|
357
393
|
if (k !== undefined) {
|
|
@@ -360,7 +396,7 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
360
396
|
}
|
|
361
397
|
return undefined;
|
|
362
398
|
}
|
|
363
|
-
/** Get a pole as Point4d with weight 1 */
|
|
399
|
+
/** Get a pole as Point4d with weight 1. */
|
|
364
400
|
getPolePoint4d(poleIndex, result) {
|
|
365
401
|
const k = this.poleIndexToDataIndex(poleIndex);
|
|
366
402
|
if (k !== undefined) {
|
|
@@ -369,23 +405,26 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
369
405
|
}
|
|
370
406
|
return undefined;
|
|
371
407
|
}
|
|
372
|
-
/** Convert `spanIndex` and `localFraction` to a knot. */
|
|
373
|
-
spanFractionToKnot(span, localFraction) {
|
|
374
|
-
return this._bcurve.spanFractionToKnot(span, localFraction);
|
|
375
|
-
}
|
|
376
|
-
constructor(numPoles, order, knots) {
|
|
377
|
-
super(3, numPoles, order, knots);
|
|
378
|
-
}
|
|
379
|
-
/** Return a simple array of arrays with the control points as `[[x,y,z],[x,y,z],..]` */
|
|
380
|
-
copyPoints() { return Point3dArray.unpackNumbersToNestedArrays(this._bcurve.packedData, 3); }
|
|
381
|
-
/** Return a simple array of the control points coordinates */
|
|
382
|
-
copyPointsFloat64Array() { return this._bcurve.packedData.slice(); }
|
|
383
408
|
/**
|
|
384
|
-
*
|
|
385
|
-
* in
|
|
409
|
+
* Convert the fractional position in the given span to a knot.
|
|
410
|
+
* * The returned value is not necessarily a knot, but it is a valid parameter in the domain of the B-spline curve.
|
|
386
411
|
*/
|
|
387
|
-
|
|
388
|
-
|
|
412
|
+
spanFractionToKnot(spanIndex, spanFraction) {
|
|
413
|
+
return this._bcurve.spanFractionToKnot(spanIndex, spanFraction);
|
|
414
|
+
}
|
|
415
|
+
/** Return a simple array of arrays with the poles as `[[x,y,z],[x,y,z],..]`. */
|
|
416
|
+
copyPoints() {
|
|
417
|
+
return Point3dArray.unpackNumbersToNestedArrays(this._bcurve.packedData, 3);
|
|
418
|
+
}
|
|
419
|
+
/** Return a simple array of poles' coordinates. */
|
|
420
|
+
copyPointsFloat64Array() {
|
|
421
|
+
return this._bcurve.packedData.slice();
|
|
422
|
+
}
|
|
423
|
+
/** Return a simple array form of the knots. Optionally replicate the first and last in classic over-clamped manner. */
|
|
424
|
+
copyKnots(includeExtraEndKnot) {
|
|
425
|
+
return this._bcurve.knots.copyKnots(includeExtraEndKnot);
|
|
426
|
+
}
|
|
427
|
+
/** Create a B-spline with uniform knots. */
|
|
389
428
|
static createUniformKnots(poles, order) {
|
|
390
429
|
const numPoles = poles instanceof Float64Array ? poles.length / 3 : poles.length;
|
|
391
430
|
if (order < 2 || numPoles < order)
|
|
@@ -409,9 +448,10 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
409
448
|
}
|
|
410
449
|
return curve;
|
|
411
450
|
}
|
|
412
|
-
/**
|
|
413
|
-
*
|
|
414
|
-
|
|
451
|
+
/**
|
|
452
|
+
* Create a smoothly closed B-spline curve with uniform knots.
|
|
453
|
+
* * Note that the curve does not start at the first pole.
|
|
454
|
+
*/
|
|
415
455
|
static createPeriodicUniformKnots(poles, order) {
|
|
416
456
|
if (order < 2)
|
|
417
457
|
return undefined;
|
|
@@ -482,21 +522,23 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
482
522
|
return BSplineCurveOps.createThroughPointsC2Cubic(options);
|
|
483
523
|
}
|
|
484
524
|
/**
|
|
485
|
-
*
|
|
525
|
+
* Create a B-spline curve from an Akima curve.
|
|
486
526
|
* @param options collection of points and end conditions.
|
|
487
527
|
*/
|
|
488
528
|
static createFromAkimaCurve3dOptions(options) {
|
|
489
529
|
return BSplineCurveOps.createThroughPoints(options.fitPoints, 4); // temporary
|
|
490
530
|
}
|
|
491
531
|
/**
|
|
492
|
-
* Create a
|
|
532
|
+
* Create a B-spline curve with given knots.
|
|
493
533
|
* * The poles have several variants:
|
|
494
|
-
* * Float64Array(3 * numPoles) in blocks of [x,y,z]
|
|
495
|
-
* * Point3d[]
|
|
496
|
-
* * number[][], with inner dimension 3
|
|
534
|
+
* * Float64Array(3 * numPoles) in blocks of [x,y,z].
|
|
535
|
+
* * Point3d[].
|
|
536
|
+
* * number[][], with inner dimension 3.
|
|
497
537
|
* * Two count conditions are recognized:
|
|
498
|
-
* * If poleArray.length + order === knotArray.length, the first and last are assumed to be the extraneous knots
|
|
538
|
+
* * If poleArray.length + order === knotArray.length, the first and last are assumed to be the extraneous knots
|
|
539
|
+
* of classic clamping.
|
|
499
540
|
* * If poleArray.length + order === knotArray.length + 2, the knots are in modern form.
|
|
541
|
+
* * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/
|
|
500
542
|
*/
|
|
501
543
|
static create(poleArray, knotArray, order) {
|
|
502
544
|
if (order < 2)
|
|
@@ -534,31 +576,42 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
534
576
|
}
|
|
535
577
|
return curve;
|
|
536
578
|
}
|
|
537
|
-
/** Return a deep clone */
|
|
579
|
+
/** Return a deep clone. */
|
|
538
580
|
clone() {
|
|
539
|
-
const
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
return
|
|
581
|
+
const knotVector = this._bcurve.knots.clone();
|
|
582
|
+
const curve = new BSplineCurve3d(this.numPoles, this.order, knotVector);
|
|
583
|
+
curve._bcurve.packedData = this._bcurve.packedData.slice();
|
|
584
|
+
return curve;
|
|
543
585
|
}
|
|
544
|
-
/** Evaluate at a
|
|
586
|
+
/** Evaluate the curve at a fractional position within a given span. */
|
|
545
587
|
evaluatePointInSpan(spanIndex, spanFraction) {
|
|
546
588
|
this._bcurve.evaluateBuffersInSpan(spanIndex, spanFraction);
|
|
547
589
|
return Point3d.createFrom(this._bcurve.poleBuffer);
|
|
548
590
|
}
|
|
549
|
-
/**
|
|
550
|
-
*
|
|
591
|
+
/**
|
|
592
|
+
* Evaluate the curve and derivative at a fractional position within a given span.
|
|
593
|
+
* * The derivative is with respect to the span fractional parameter, _not_ to the curve's parameter or fractional parameter.
|
|
551
594
|
*/
|
|
552
595
|
evaluatePointAndDerivativeInSpan(spanIndex, spanFraction) {
|
|
553
596
|
this._bcurve.evaluateBuffersInSpan1(spanIndex, spanFraction);
|
|
554
597
|
return Ray3d.createCapture(Point3d.createFrom(this._bcurve.poleBuffer), Vector3d.createFrom(this._bcurve.poleBuffer1));
|
|
555
598
|
}
|
|
556
|
-
/**
|
|
599
|
+
/**
|
|
600
|
+
* Evaluate the curve at the given parameter.
|
|
601
|
+
* @param u parameter in curve domain.
|
|
602
|
+
* @param result optional result.
|
|
603
|
+
* @returns the point on the curve.
|
|
604
|
+
*/
|
|
557
605
|
knotToPoint(u, result) {
|
|
558
606
|
this._bcurve.evaluateBuffersAtKnot(u);
|
|
559
607
|
return Point3d.createFrom(this._bcurve.poleBuffer, result);
|
|
560
608
|
}
|
|
561
|
-
/**
|
|
609
|
+
/**
|
|
610
|
+
* Evaluate the curve and derivative at the given parameter.
|
|
611
|
+
* @param u parameter in curve domain.
|
|
612
|
+
* @param result optional result.
|
|
613
|
+
* @returns the ray with origin at the curve point and direction as the derivative.
|
|
614
|
+
*/
|
|
562
615
|
knotToPointAndDerivative(u, result) {
|
|
563
616
|
this._bcurve.evaluateBuffersAtKnot(u, 1);
|
|
564
617
|
if (!result)
|
|
@@ -567,12 +620,17 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
567
620
|
result.direction.setFrom(this._bcurve.poleBuffer1);
|
|
568
621
|
return result;
|
|
569
622
|
}
|
|
570
|
-
/**
|
|
623
|
+
/**
|
|
624
|
+
* Evaluate the curve and two derivatives at the given parameter.
|
|
625
|
+
* @param u parameter in the curve domain.
|
|
626
|
+
* @param result optional result.
|
|
627
|
+
* @returns the plane with origin at the curve point, vectorU as the 1st derivative, and vectorV as the 2nd derivative.
|
|
628
|
+
*/
|
|
571
629
|
knotToPointAnd2Derivatives(u, result) {
|
|
572
630
|
this._bcurve.evaluateBuffersAtKnot(u, 2);
|
|
573
631
|
return Plane3dByOriginAndVectors.createOriginAndVectorsXYZ(this._bcurve.poleBuffer[0], this._bcurve.poleBuffer[1], this._bcurve.poleBuffer[2], this._bcurve.poleBuffer1[0], this._bcurve.poleBuffer1[1], this._bcurve.poleBuffer1[2], this._bcurve.poleBuffer2[0], this._bcurve.poleBuffer2[1], this._bcurve.poleBuffer2[2], result);
|
|
574
632
|
}
|
|
575
|
-
/**
|
|
633
|
+
/** Test if `this` is almost the same curve as `other`. */
|
|
576
634
|
isAlmostEqual(other) {
|
|
577
635
|
if (other instanceof BSplineCurve3d) {
|
|
578
636
|
return this._bcurve.knots.isAlmostEqual(other._bcurve.knots)
|
|
@@ -580,15 +638,19 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
580
638
|
}
|
|
581
639
|
return false;
|
|
582
640
|
}
|
|
583
|
-
/**
|
|
641
|
+
/** Test if this curve lies entirely in the given plane. */
|
|
584
642
|
isInPlane(plane) {
|
|
585
643
|
return Point3dArray.isCloseToPlane(this._bcurve.packedData, plane);
|
|
586
644
|
}
|
|
587
|
-
/**
|
|
588
|
-
|
|
589
|
-
|
|
645
|
+
/**
|
|
646
|
+
* Return the control polygon length as an approximation to the curve length.
|
|
647
|
+
* * The returned length is always an overestimate.
|
|
648
|
+
*/
|
|
649
|
+
quickLength() {
|
|
650
|
+
return Point3dArray.sumEdgeLengths(this._bcurve.packedData);
|
|
651
|
+
}
|
|
652
|
+
/** Emit Beziers or strokes (selected by the stroke options) to the handler. */
|
|
590
653
|
emitStrokableParts(handler, options) {
|
|
591
|
-
const needBeziers = handler.announceBezierCurve !== undefined;
|
|
592
654
|
const workBezier = this.initializeWorkBezier();
|
|
593
655
|
const numSpan = this.numSpan;
|
|
594
656
|
let numStrokes;
|
|
@@ -596,7 +658,7 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
596
658
|
const bezier = this.getSaturatedBezierSpan3dOr3dH(spanIndex, false, workBezier);
|
|
597
659
|
if (bezier) {
|
|
598
660
|
numStrokes = bezier.computeStrokeCountForOptions(options);
|
|
599
|
-
if (
|
|
661
|
+
if (handler.announceBezierCurve) {
|
|
600
662
|
handler.announceBezierCurve(bezier, numStrokes, this, spanIndex, this._bcurve.knots.spanFractionToFraction(spanIndex, 0.0), this._bcurve.knots.spanFractionToFraction(spanIndex, 1.0));
|
|
601
663
|
}
|
|
602
664
|
else {
|
|
@@ -621,7 +683,7 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
621
683
|
return numStroke;
|
|
622
684
|
}
|
|
623
685
|
/**
|
|
624
|
-
* Compute individual segment stroke counts.
|
|
686
|
+
* Compute individual segment stroke counts. Attach in a StrokeCountMap.
|
|
625
687
|
* @param options StrokeOptions that determine count
|
|
626
688
|
* @param parentStrokeMap evolving parent map.
|
|
627
689
|
* @alpha
|
|
@@ -640,7 +702,7 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
640
702
|
}
|
|
641
703
|
CurvePrimitive.installStrokeCountMap(this, myData, parentStrokeMap);
|
|
642
704
|
}
|
|
643
|
-
/** Append strokes to
|
|
705
|
+
/** Append strokes to the given linestring. */
|
|
644
706
|
emitStrokes(dest, options) {
|
|
645
707
|
const workBezier = this.initializeWorkBezier();
|
|
646
708
|
const numSpan = this.numSpan;
|
|
@@ -651,16 +713,17 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
651
713
|
}
|
|
652
714
|
}
|
|
653
715
|
/**
|
|
654
|
-
* Test knots and
|
|
716
|
+
* Test knots and poles to determine if it is possible to close (aka "wrap") the curve.
|
|
655
717
|
* @returns the manner in which it is possible to close the curve. See `BSplineWrapMode` for particulars of each mode.
|
|
656
718
|
*/
|
|
657
719
|
get isClosable() {
|
|
658
720
|
return this.isClosableCurve;
|
|
659
721
|
}
|
|
660
722
|
/**
|
|
661
|
-
* Return
|
|
662
|
-
*
|
|
663
|
-
* @param
|
|
723
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
724
|
+
* * The concrete return type may be [[BezierCurve3d]] or [[BezierCurve3dH]] according to the instance type and `prefer3dH`.
|
|
725
|
+
* @param spanIndex index of span.
|
|
726
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
664
727
|
*/
|
|
665
728
|
getSaturatedBezierSpan3dOr3dH(spanIndex, prefer3dH, result) {
|
|
666
729
|
if (prefer3dH)
|
|
@@ -668,9 +731,9 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
668
731
|
return this.getSaturatedBezierSpan3d(spanIndex, result);
|
|
669
732
|
}
|
|
670
733
|
/**
|
|
671
|
-
* Return
|
|
672
|
-
* @param spanIndex
|
|
673
|
-
* @param result optional reusable curve.
|
|
734
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
735
|
+
* @param spanIndex index of span.
|
|
736
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
674
737
|
*/
|
|
675
738
|
getSaturatedBezierSpan3d(spanIndex, result) {
|
|
676
739
|
if (spanIndex < 0 || spanIndex >= this.numSpan)
|
|
@@ -681,13 +744,13 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
681
744
|
const bezier = result;
|
|
682
745
|
bezier.loadSpanPoles(this._bcurve.packedData, spanIndex);
|
|
683
746
|
if (bezier.saturateInPlace(this._bcurve.knots, spanIndex))
|
|
684
|
-
return
|
|
747
|
+
return bezier;
|
|
685
748
|
return undefined;
|
|
686
749
|
}
|
|
687
750
|
/**
|
|
688
|
-
* Return
|
|
689
|
-
* @param spanIndex
|
|
690
|
-
* @param result optional reusable curve.
|
|
751
|
+
* Return the Bezier fragment corresponding to the given span of this curve.
|
|
752
|
+
* @param spanIndex index of span.
|
|
753
|
+
* @param result optional reusable curve. This will only be reused if its type and order matches.
|
|
691
754
|
*/
|
|
692
755
|
getSaturatedBezierSpan3dH(spanIndex, result) {
|
|
693
756
|
if (spanIndex < 0 || spanIndex >= this.numSpan)
|
|
@@ -701,15 +764,16 @@ export class BSplineCurve3d extends BSplineCurve3dBase {
|
|
|
701
764
|
return bezier;
|
|
702
765
|
return undefined;
|
|
703
766
|
}
|
|
704
|
-
/** Second step of double dispatch:
|
|
767
|
+
/** Second step of double dispatch: call `handler.handleBSplineCurve3d(this)`. */
|
|
705
768
|
dispatchToGeometryHandler(handler) {
|
|
706
769
|
return handler.handleBSplineCurve3d(this);
|
|
707
770
|
}
|
|
708
771
|
/**
|
|
709
|
-
* Extend a range so
|
|
710
|
-
* *
|
|
711
|
-
*
|
|
712
|
-
* @param
|
|
772
|
+
* Extend a range so it contains the range of this curve.
|
|
773
|
+
* * This computation is based on the poles, not the curve itself, so the returned range is generally larger than the
|
|
774
|
+
* tightest possible range.
|
|
775
|
+
* @param rangeToExtend range to extend.
|
|
776
|
+
* @param transform transform to apply to the poles as they are entered into the range.
|
|
713
777
|
*/
|
|
714
778
|
extendRange(rangeToExtend, transform) {
|
|
715
779
|
const buffer = this._bcurve.packedData;
|