@itwin/core-geometry 5.0.0-dev.62 → 5.0.0-dev.64

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.
Files changed (55) hide show
  1. package/lib/cjs/bspline/BSpline1dNd.d.ts +90 -54
  2. package/lib/cjs/bspline/BSpline1dNd.d.ts.map +1 -1
  3. package/lib/cjs/bspline/BSpline1dNd.js +134 -99
  4. package/lib/cjs/bspline/BSpline1dNd.js.map +1 -1
  5. package/lib/cjs/bspline/BSplineCurve.d.ts +193 -155
  6. package/lib/cjs/bspline/BSplineCurve.d.ts.map +1 -1
  7. package/lib/cjs/bspline/BSplineCurve.js +245 -181
  8. package/lib/cjs/bspline/BSplineCurve.js.map +1 -1
  9. package/lib/cjs/bspline/BezierCurve3d.d.ts +3 -1
  10. package/lib/cjs/bspline/BezierCurve3d.d.ts.map +1 -1
  11. package/lib/cjs/bspline/BezierCurve3d.js +3 -5
  12. package/lib/cjs/bspline/BezierCurve3d.js.map +1 -1
  13. package/lib/cjs/bspline/KnotVector.d.ts +74 -54
  14. package/lib/cjs/bspline/KnotVector.d.ts.map +1 -1
  15. package/lib/cjs/bspline/KnotVector.js +127 -80
  16. package/lib/cjs/bspline/KnotVector.js.map +1 -1
  17. package/lib/cjs/curve/Arc3d.d.ts +2 -0
  18. package/lib/cjs/curve/Arc3d.d.ts.map +1 -1
  19. package/lib/cjs/curve/Arc3d.js +2 -0
  20. package/lib/cjs/curve/Arc3d.js.map +1 -1
  21. package/lib/cjs/geometry3d/PointHelpers.d.ts +3 -3
  22. package/lib/cjs/geometry3d/PointHelpers.js +3 -3
  23. package/lib/cjs/geometry3d/PointHelpers.js.map +1 -1
  24. package/lib/cjs/geometry3d/Ray3d.d.ts +2 -2
  25. package/lib/cjs/geometry3d/Ray3d.d.ts.map +1 -1
  26. package/lib/cjs/geometry3d/Ray3d.js +8 -11
  27. package/lib/cjs/geometry3d/Ray3d.js.map +1 -1
  28. package/lib/esm/bspline/BSpline1dNd.d.ts +90 -54
  29. package/lib/esm/bspline/BSpline1dNd.d.ts.map +1 -1
  30. package/lib/esm/bspline/BSpline1dNd.js +134 -99
  31. package/lib/esm/bspline/BSpline1dNd.js.map +1 -1
  32. package/lib/esm/bspline/BSplineCurve.d.ts +193 -155
  33. package/lib/esm/bspline/BSplineCurve.d.ts.map +1 -1
  34. package/lib/esm/bspline/BSplineCurve.js +245 -181
  35. package/lib/esm/bspline/BSplineCurve.js.map +1 -1
  36. package/lib/esm/bspline/BezierCurve3d.d.ts +3 -1
  37. package/lib/esm/bspline/BezierCurve3d.d.ts.map +1 -1
  38. package/lib/esm/bspline/BezierCurve3d.js +3 -5
  39. package/lib/esm/bspline/BezierCurve3d.js.map +1 -1
  40. package/lib/esm/bspline/KnotVector.d.ts +74 -54
  41. package/lib/esm/bspline/KnotVector.d.ts.map +1 -1
  42. package/lib/esm/bspline/KnotVector.js +127 -80
  43. package/lib/esm/bspline/KnotVector.js.map +1 -1
  44. package/lib/esm/curve/Arc3d.d.ts +2 -0
  45. package/lib/esm/curve/Arc3d.d.ts.map +1 -1
  46. package/lib/esm/curve/Arc3d.js +2 -0
  47. package/lib/esm/curve/Arc3d.js.map +1 -1
  48. package/lib/esm/geometry3d/PointHelpers.d.ts +3 -3
  49. package/lib/esm/geometry3d/PointHelpers.js +3 -3
  50. package/lib/esm/geometry3d/PointHelpers.js.map +1 -1
  51. package/lib/esm/geometry3d/Ray3d.d.ts +2 -2
  52. package/lib/esm/geometry3d/Ray3d.d.ts.map +1 -1
  53. package/lib/esm/geometry3d/Ray3d.js +8 -11
  54. package/lib/esm/geometry3d/Ray3d.js.map +1 -1
  55. package/package.json +3 -3
@@ -5,82 +5,115 @@
5
5
  /** @packageDocumentation
6
6
  * @module Bspline
7
7
  */
8
- // import { Point2d } from "../Geometry2d";
9
8
  import { Geometry } from "../Geometry";
10
9
  import { Point3d } from "../geometry3d/Point3dVector3d";
11
10
  import { BSplineWrapMode, KnotVector } from "./KnotVector";
12
- /** Bspline knots and poles for 1d-to-Nd.
11
+ /**
12
+ * Knots and poles for a B-spline function mapping R to R^n.
13
13
  * * The "pole" (aka control point) of this class is a block of `poleLength` numbers.
14
14
  * * Derived classes (not this class) assign meaning such as x,y,z,w.
15
- * * for instance, an instance of this class with `poleLength===3` does not know if its poles are x,y,z or weighted 2D x,y,w
15
+ * * For instance, an instance of this class with `poleLength===3` does not know if its poles are x,y,z or
16
+ * weighted 2D x,y,w.
16
17
  * @public
17
18
  */
18
19
  export class BSpline1dNd {
19
- /** knots of the bspline */
20
+ /** Knots of the bspline. */
20
21
  knots;
21
- /** poles, packed in blocks of `poleLength` doubles. */
22
+ /** Poles packed in blocks of `poleLength` doubles. */
22
23
  packedData;
23
- /** (property accessor) Return the number of numeric values per pole. */
24
+ /** The number of numeric values per pole. */
24
25
  poleLength;
25
26
  /** (property accessor) Return the degree of the polynomials. */
26
- get degree() { return this.knots.degree; }
27
- /** (property accessor) Return the number of order (one more than degree) of the polynomials */
28
- get order() { return this.knots.degree + 1; }
29
- /** (property accessor) Return the number of bezier spans (including null spans at multiple knots)*/
30
- get numSpan() { return this.numPoles - this.knots.degree; }
31
- /** (property accessor) Return the number of poles*/
32
- get numPoles() { return this.packedData.length / this.poleLength; }
33
- /** copy 3 values of pole `i` into a point.
27
+ get degree() {
28
+ return this.knots.degree;
29
+ }
30
+ /** (property accessor) Return the order (one more than degree) of the polynomials. */
31
+ get order() {
32
+ return this.knots.degree + 1;
33
+ }
34
+ /** (property accessor) Return the number of bezier spans (including null spans at multiple knots). */
35
+ get numSpan() {
36
+ return this.numPoles - this.knots.degree;
37
+ }
38
+ /** (property accessor) Return the number of poles. */
39
+ get numPoles() {
40
+ return this.packedData.length / this.poleLength;
41
+ }
42
+ /**
43
+ * Copy 3 values of pole `i` into a point.
34
44
  * * The calling class is responsible for knowing if this is an appropriate access to the blocked data.
35
45
  */
36
- getPoint3dPole(i, result) { return Point3d.createFromPacked(this.packedData, i, result); }
37
- /** preallocated array (length === `order`) used as temporary in evaluations */
38
- basisBuffer; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE
39
- /** preallocated array (length === `poleLength`) used as temporary in evaluations */
40
- poleBuffer; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE
41
- /** preallocated array (length === `order`) used as temporary in evaluations */
42
- basisBuffer1; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE
43
- /** preallocated array (length === `order`) used as temporary in evaluations */
44
- basisBuffer2; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE
45
- /** preallocated array (length === `poleLength`) used as temporary in evaluations */
46
- poleBuffer1; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE
47
- /** preallocated array (length === `poleLength`) used as temporary in evaluations */
48
- poleBuffer2; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE
46
+ getPoint3dPole(i, result) {
47
+ return Point3d.createFromPacked(this.packedData, i, result);
48
+ }
49
+ /**
50
+ * Values of the `order` relevant B-spline basis functions at a parameter.
51
+ * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.
52
+ */
53
+ basisBuffer;
54
+ /**
55
+ * Derivatives of the `order` relevant B-spline basis functions at a parameter.
56
+ * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.
57
+ */
58
+ basisBuffer1;
59
+ /**
60
+ * Second derivatives of the `order` relevant B-spline basis functions at a parameter.
61
+ * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.
62
+ */
63
+ basisBuffer2;
64
+ /**
65
+ * Temporary to hold a single point.
66
+ * * Preallocated to length `poleLength` in the constructor.
67
+ */
68
+ poleBuffer;
69
+ /**
70
+ * Temporary to hold a single derivative vector.
71
+ * * Preallocated to length `poleLength` in the constructor.
72
+ */
73
+ poleBuffer1;
74
+ /**
75
+ * Temporary to hold a single second derivative vector.
76
+ * * Preallocated to length `poleLength` in the constructor.
77
+ */
78
+ poleBuffer2;
49
79
  /**
50
- * initialize arrays for given spline dimensions.
51
- * @param numPoles number of poles
52
- * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted, 3 for 2d weighted)
53
- * @param order number of poles in support for a section of the bspline
54
- * @param knots KnotVector. This is captured, not cloned.
80
+ * Initialize arrays for given spline dimensions.
81
+ * @param numPoles number of poles.
82
+ * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted,
83
+ * 3 for 2d weighted).
84
+ * @param order number of poles defining a Bezier segment of the B-spline function.
85
+ * @param knots the KnotVector. This is captured, not cloned.
55
86
  */
56
87
  constructor(numPoles, poleLength, order, knots) {
57
88
  this.knots = knots;
58
89
  this.packedData = new Float64Array(numPoles * poleLength);
59
90
  this.poleLength = poleLength;
60
91
  this.basisBuffer = new Float64Array(order);
61
- this.poleBuffer = new Float64Array(poleLength);
62
92
  this.basisBuffer1 = new Float64Array(order);
63
93
  this.basisBuffer2 = new Float64Array(order);
94
+ this.poleBuffer = new Float64Array(poleLength);
64
95
  this.poleBuffer1 = new Float64Array(poleLength);
65
96
  this.poleBuffer2 = new Float64Array(poleLength);
66
97
  }
67
98
  /**
68
- * create a 1Bspline1dNd`
69
- * @param numPoles number of poles
70
- * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted, 3 for 2d weighted)
71
- * @param order number of poles in support for a section of the bspline
72
- * @param knots KnotVector. This is captured, not cloned.
99
+ * Create a `BSpline1dNd`.
100
+ * @param numPoles number of poles.
101
+ * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted,
102
+ * 3 for 2d weighted).
103
+ * @param order number of poles defining a Bezier segment of the B-spline function.
104
+ * @param knots the KnotVector. This is captured, not cloned.
73
105
  */
74
106
  static create(numPoles, poleLength, order, knots) {
75
107
  return new BSpline1dNd(numPoles, poleLength, order, knots);
76
108
  }
77
- /** Map a span index and local fraction to knot value. */
78
- spanFractionToKnot(span, localFraction) {
79
- return this.knots.spanFractionToKnot(span, localFraction);
109
+ /** Map a span index and span fraction to knot value. */
110
+ spanFractionToKnot(spanIndex, spanFraction) {
111
+ return this.knots.spanFractionToKnot(spanIndex, spanFraction);
80
112
  }
81
113
  /**
82
- * Evaluate the `order` basis functions (and optionally one or two derivatives) at a given fractional position within indexed span.
83
- * @returns true if and only if output arrays are sufficiently sized
114
+ * Evaluate the `order` basis functions (and optionally one or two derivatives) at a given fractional position within
115
+ * indexed span.
116
+ * @returns true if and only if output arrays are sufficiently sized.
84
117
  */
85
118
  evaluateBasisFunctionsInSpan(spanIndex, spanFraction, f, df, ddf) {
86
119
  if (spanIndex < 0)
@@ -94,57 +127,64 @@ export class BSpline1dNd {
94
127
  this.knots.evaluateBasisFunctions(knotIndex0, globalKnot, f);
95
128
  }
96
129
  /**
97
- * * Evaluate the basis functions at spanIndex and fraction.
98
- * * Evaluations are stored in the preallocated `this.basisBuffer`
99
- * * Immediately do the summations of the basis values times the respective control points
100
- * * Summations are stored in the preallocated `this.poleBuffer`
101
- * */
102
- evaluateBuffersInSpan(spanIndex, spanFraction) {
103
- this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer);
104
- this.sumPoleBufferForSpan(spanIndex);
105
- }
106
- /**
107
- * * Evaluate the basis functions and one derivative at spanIndex and fraction.
108
- * * Evaluations are stored in the preallocated `this.basisBuffer`
109
- * * Immediately do the summations of the basis values times the respective control points
110
- * * Summations are stored in the preallocated `this.poleBuffer` and `this.poleBuffer1`
111
- * */
112
- evaluateBuffersInSpan1(spanIndex, spanFraction) {
113
- this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer, this.basisBuffer1);
114
- this.sumPoleBufferForSpan(spanIndex);
115
- this.sumPoleBuffer1ForSpan(spanIndex);
116
- }
117
- /** sum poles in `poleBuffer` at span `spanIndex` by the weights in the `basisBuffer` */
130
+ * Compute the linear combination of the given span's poles and the weights in `basisBuffer`, and store this point
131
+ * in `poleBuffer`.
132
+ */
118
133
  sumPoleBufferForSpan(spanIndex) {
119
134
  this.poleBuffer.fill(0);
120
135
  let k = spanIndex * this.poleLength;
121
- for (const f of this.basisBuffer) {
122
- for (let j = 0; j < this.poleLength; j++) {
136
+ for (const f of this.basisBuffer)
137
+ for (let j = 0; j < this.poleLength; j++)
123
138
  this.poleBuffer[j] += f * this.packedData[k++];
124
- }
125
- }
126
139
  }
127
- /** sum poles in `poleBuffer1` at span `spanIndex` by the weights in the `basisBuffer1`, i.e. form first derivatives */
140
+ /**
141
+ * Compute the linear combination of the given span's poles and the weights in `basisBuffer1`, and store this
142
+ * derivative vector in `poleBuffer1`.
143
+ */
128
144
  sumPoleBuffer1ForSpan(spanIndex) {
129
145
  this.poleBuffer1.fill(0);
130
146
  let k = spanIndex * this.poleLength;
131
- for (const f of this.basisBuffer1) {
132
- for (let j = 0; j < this.poleLength; j++) {
147
+ for (const f of this.basisBuffer1)
148
+ for (let j = 0; j < this.poleLength; j++)
133
149
  this.poleBuffer1[j] += f * this.packedData[k++];
134
- }
135
- }
136
150
  }
137
- /** sum poles in `poleBuffer2` at span `spanIndex` by the weights in the `basisBuffer2`, i.e. form second derivatives */
151
+ /**
152
+ * Compute the linear combination of the given span's poles and the weights in `basisBuffer2`, and store this
153
+ * second derivative vector in `poleBuffer2`.
154
+ */
138
155
  sumPoleBuffer2ForSpan(spanIndex) {
139
156
  this.poleBuffer2.fill(0);
140
157
  let k = spanIndex * this.poleLength;
141
158
  for (const f of this.basisBuffer2) {
142
- for (let j = 0; j < this.poleLength; j++) {
159
+ for (let j = 0; j < this.poleLength; j++)
143
160
  this.poleBuffer2[j] += f * this.packedData[k++];
144
- }
145
161
  }
146
162
  }
147
- /** Evaluate the function values and 1 or 2 derivatives into `this.poleBuffer`, `this.poleBuffer1` and `this.poleBuffer2` */
163
+ /**
164
+ * * Evaluate the basis functions at spanIndex and fraction.
165
+ * * Evaluations are stored in the preallocated `this.basisBuffer`.
166
+ * * Immediately do the summations of the basis values times the respective poles.
167
+ * * Summations are stored in the preallocated `this.poleBuffer`
168
+ * */
169
+ evaluateBuffersInSpan(spanIndex, spanFraction) {
170
+ this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer);
171
+ this.sumPoleBufferForSpan(spanIndex);
172
+ }
173
+ /**
174
+ * * Evaluate the basis functions and one derivative at spanIndex and fraction.
175
+ * * Function evaluations are stored in the preallocated `this.basisBuffer`; derivative evaluations in `this.basisBuffer1`.
176
+ * * Immediately do the summations of the basis values times the respective poles.
177
+ * * Summations are stored in the preallocated `this.poleBuffer` and `this.poleBuffer1`
178
+ * */
179
+ evaluateBuffersInSpan1(spanIndex, spanFraction) {
180
+ this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer, this.basisBuffer1);
181
+ this.sumPoleBufferForSpan(spanIndex);
182
+ this.sumPoleBuffer1ForSpan(spanIndex);
183
+ }
184
+ /**
185
+ * Evaluate the B-spline function and optional derivatives at the given parameter in knot space.
186
+ * * Function value is stored in `poleBuffer`; optional derivative vectors in `poleBuffer1` and `poleBuffer2`.
187
+ */
148
188
  evaluateBuffersAtKnot(u, numDerivative = 0) {
149
189
  const knotIndex0 = this.knots.knotToLeftKnotIndex(u);
150
190
  if (numDerivative < 1) {
@@ -163,36 +203,30 @@ export class BSpline1dNd {
163
203
  this.sumPoleBuffer2ForSpan(knotIndex0 - this.degree + 1);
164
204
  }
165
205
  }
166
- /**
167
- * Reverse the (blocked) poles (in `this.packedData` in place.
168
- */
206
+ /** Reverse the instance poles and knots in place. */
169
207
  reverseInPlace() {
170
- // reverse poles in blocks ...
171
- const b = this.poleLength;
208
+ const pLen = this.poleLength;
172
209
  const data = this.packedData;
173
- for (let i0 = 0, j0 = b * (this.numPoles - 1); i0 < j0; i0 += b, j0 -= b) {
174
- let t = 0;
175
- for (let i = 0; i < b; i++) {
176
- t = data[i0 + i];
177
- data[i0 + i] = data[j0 + i];
178
- data[j0 + i] = t;
179
- }
210
+ for (let i0 = 0, j0 = pLen * (this.numPoles - 1); i0 < j0; i0 += pLen, j0 -= pLen) {
211
+ for (let i = 0; i < pLen; i++)
212
+ [data[i0 + i], data[j0 + i]] = [data[j0 + i], data[i0 + i]];
180
213
  }
181
214
  this.knots.reflectKnots();
182
215
  }
183
216
  /**
184
- * Test if the leading and trailing polygon coordinates are replicated in the manner of a "closed" bspline polygon which has been expanded
185
- * to act as a normal bspline.
186
- * @returns true if `degree` leading and trailing polygon blocks match
187
- * @deprecated in 4.x. Use testClosablePolygon instead.
217
+ * Test if the leading and trailing polygon coordinates are replicated in the manner of a "closed" bspline polygon
218
+ * which has been expanded to act as a normal bspline.
219
+ * @returns true if `degree` leading and trailing polygon blocks match.
220
+ * @deprecated in 4.x. Use `testClosablePolygon` instead.
188
221
  */
189
222
  testCloseablePolygon(mode) {
190
223
  return this.testClosablePolygon(mode);
191
224
  }
192
225
  /**
193
- * Test if the leading and trailing polygon coordinates are replicated in the manner of a "closed" bspline polygon which has been expanded
194
- * to act as a normal bspline.
195
- * @returns true if `degree` leading and trailing polygon blocks match
226
+ * Test if the leading and trailing poles are replicated in the manner of a "closed" B-spline function with wraparound
227
+ * control polygon.
228
+ * @param mode wrap mode, indicating the number of wraparound poles to check. If undefined, `knots.wrappable` is used.
229
+ * @returns true if the expected leading and trailing poles match, according to `mode`.
196
230
  */
197
231
  testClosablePolygon(mode) {
198
232
  if (mode === undefined)
@@ -214,9 +248,10 @@ export class BSpline1dNd {
214
248
  }
215
249
  return true;
216
250
  }
217
- /** Insert knot and resulting pole into the instance, optionally multiple times.
218
- * @param knot the knot to be inserted (may already exist in the KnotVector)
219
- * @param totalMultiplicity the total multiplicity of the knot on return
251
+ /**
252
+ * Insert the knot and resulting pole into the instance, optionally multiple times.
253
+ * @param knot the knot to be inserted (may already exist in the KnotVector).
254
+ * @param totalMultiplicity the total multiplicity of the knot on return.
220
255
  */
221
256
  addKnot(knot, totalMultiplicity) {
222
257
  if (knot < this.knots.leftKnot || knot > this.knots.rightKnot)
@@ -1 +1 @@
1
- {"version":3,"file":"BSpline1dNd.js","sourceRoot":"","sources":["../../../src/bspline/BSpline1dNd.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Bspline\n */\n\n// import { Point2d } from \"../Geometry2d\";\nimport { Geometry } from \"../Geometry\";\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\nimport { BSplineWrapMode, KnotVector } from \"./KnotVector\";\n\n/** Bspline knots and poles for 1d-to-Nd.\n * * The \"pole\" (aka control point) of this class is a block of `poleLength` numbers.\n * * Derived classes (not this class) assign meaning such as x,y,z,w.\n * * for instance, an instance of this class with `poleLength===3` does not know if its poles are x,y,z or weighted 2D x,y,w\n * @public\n */\nexport class BSpline1dNd {\n /** knots of the bspline */\n public knots: KnotVector;\n /** poles, packed in blocks of `poleLength` doubles. */\n public packedData: Float64Array;\n /** (property accessor) Return the number of numeric values per pole. */\n public poleLength: number;\n /** (property accessor) Return the degree of the polynomials. */\n public get degree(): number { return this.knots.degree; }\n /** (property accessor) Return the number of order (one more than degree) of the polynomials */\n public get order(): number { return this.knots.degree + 1; }\n /** (property accessor) Return the number of bezier spans (including null spans at multiple knots)*/\n public get numSpan(): number { return this.numPoles - this.knots.degree; }\n /** (property accessor) Return the number of poles*/\n public get numPoles(): number { return this.packedData.length / this.poleLength; }\n /** copy 3 values of pole `i` into a point.\n * * The calling class is responsible for knowing if this is an appropriate access to the blocked data.\n */\n public getPoint3dPole(i: number, result?: Point3d): Point3d | undefined { return Point3d.createFromPacked(this.packedData, i, result); }\n /** preallocated array (length === `order`) used as temporary in evaluations */\n public basisBuffer: Float64Array; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n /** preallocated array (length === `poleLength`) used as temporary in evaluations */\n public poleBuffer: Float64Array; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n /** preallocated array (length === `order`) used as temporary in evaluations */\n public basisBuffer1: Float64Array; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n /** preallocated array (length === `order`) used as temporary in evaluations */\n public basisBuffer2: Float64Array; // one set of basis function values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n /** preallocated array (length === `poleLength`) used as temporary in evaluations */\n public poleBuffer1: Float64Array; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n /** preallocated array (length === `poleLength`) used as temporary in evaluations */\n public poleBuffer2: Float64Array; // one set of target values. ALLOCATED BY CTOR FOR FREQUENT REUSE\n\n /**\n * initialize arrays for given spline dimensions.\n * @param numPoles number of poles\n * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted, 3 for 2d weighted)\n * @param order number of poles in support for a section of the bspline\n * @param knots KnotVector. This is captured, not cloned.\n */\n protected constructor(numPoles: number, poleLength: number, order: number, knots: KnotVector) {\n this.knots = knots;\n this.packedData = new Float64Array(numPoles * poleLength);\n this.poleLength = poleLength;\n this.basisBuffer = new Float64Array(order);\n this.poleBuffer = new Float64Array(poleLength);\n this.basisBuffer1 = new Float64Array(order);\n this.basisBuffer2 = new Float64Array(order);\n this.poleBuffer1 = new Float64Array(poleLength);\n this.poleBuffer2 = new Float64Array(poleLength);\n }\n\n /**\n * create a 1Bspline1dNd`\n * @param numPoles number of poles\n * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted, 3 for 2d weighted)\n * @param order number of poles in support for a section of the bspline\n * @param knots KnotVector. This is captured, not cloned.\n */\n public static create(numPoles: number, poleLength: number, order: number, knots: KnotVector): BSpline1dNd | undefined {\n return new BSpline1dNd(numPoles, poleLength, order, knots);\n }\n /** Map a span index and local fraction to knot value. */\n public spanFractionToKnot(span: number, localFraction: number): number {\n return this.knots.spanFractionToKnot(span, localFraction);\n }\n\n /**\n * Evaluate the `order` basis functions (and optionally one or two derivatives) at a given fractional position within indexed span.\n * @returns true if and only if output arrays are sufficiently sized\n */\n public evaluateBasisFunctionsInSpan(spanIndex: number, spanFraction: number, f: Float64Array, df?: Float64Array, ddf?: Float64Array): boolean {\n if (spanIndex < 0) spanIndex = 0;\n if (spanIndex >= this.numSpan) spanIndex = this.numSpan - 1;\n const knotIndex0 = spanIndex + this.degree - 1;\n const globalKnot = this.knots.baseKnotFractionToKnot(knotIndex0, spanFraction);\n return df ?\n this.knots.evaluateBasisFunctions1(knotIndex0, globalKnot, f, df, ddf) :\n this.knots.evaluateBasisFunctions(knotIndex0, globalKnot, f);\n }\n /**\n * * Evaluate the basis functions at spanIndex and fraction.\n * * Evaluations are stored in the preallocated `this.basisBuffer`\n * * Immediately do the summations of the basis values times the respective control points\n * * Summations are stored in the preallocated `this.poleBuffer`\n * */\n public evaluateBuffersInSpan(spanIndex: number, spanFraction: number) {\n this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer);\n this.sumPoleBufferForSpan(spanIndex);\n }\n /**\n * * Evaluate the basis functions and one derivative at spanIndex and fraction.\n * * Evaluations are stored in the preallocated `this.basisBuffer`\n * * Immediately do the summations of the basis values times the respective control points\n * * Summations are stored in the preallocated `this.poleBuffer` and `this.poleBuffer1`\n * */\n public evaluateBuffersInSpan1(spanIndex: number, spanFraction: number) {\n this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer, this.basisBuffer1);\n this.sumPoleBufferForSpan(spanIndex);\n this.sumPoleBuffer1ForSpan(spanIndex);\n }\n /** sum poles in `poleBuffer` at span `spanIndex` by the weights in the `basisBuffer` */\n public sumPoleBufferForSpan(spanIndex: number) {\n this.poleBuffer.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer) {\n for (let j = 0; j < this.poleLength; j++) { this.poleBuffer[j] += f * this.packedData[k++]; }\n }\n }\n /** sum poles in `poleBuffer1` at span `spanIndex` by the weights in the `basisBuffer1`, i.e. form first derivatives */\n public sumPoleBuffer1ForSpan(spanIndex: number) {\n this.poleBuffer1.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer1) {\n for (let j = 0; j < this.poleLength; j++) {\n this.poleBuffer1[j] += f * this.packedData[k++];\n }\n }\n }\n /** sum poles in `poleBuffer2` at span `spanIndex` by the weights in the `basisBuffer2`, i.e. form second derivatives */\n public sumPoleBuffer2ForSpan(spanIndex: number) {\n this.poleBuffer2.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer2) {\n for (let j = 0; j < this.poleLength; j++) {\n this.poleBuffer2[j] += f * this.packedData[k++];\n }\n }\n }\n /** Evaluate the function values and 1 or 2 derivatives into `this.poleBuffer`, `this.poleBuffer1` and `this.poleBuffer2` */\n public evaluateBuffersAtKnot(u: number, numDerivative: number = 0) {\n const knotIndex0 = this.knots.knotToLeftKnotIndex(u);\n if (numDerivative < 1) {\n this.knots.evaluateBasisFunctions(knotIndex0, u, this.basisBuffer);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n } else if (numDerivative === 1) {\n this.knots.evaluateBasisFunctions1(knotIndex0, u, this.basisBuffer, this.basisBuffer1);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer1ForSpan(knotIndex0 - this.degree + 1);\n } else {\n this.knots.evaluateBasisFunctions1(knotIndex0, u, this.basisBuffer, this.basisBuffer1, this.basisBuffer2);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer1ForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer2ForSpan(knotIndex0 - this.degree + 1);\n }\n }\n /**\n * Reverse the (blocked) poles (in `this.packedData` in place.\n */\n public reverseInPlace(): void {\n // reverse poles in blocks ...\n const b = this.poleLength;\n const data = this.packedData;\n for (let i0 = 0, j0 = b * (this.numPoles - 1);\n i0 < j0;\n i0 += b, j0 -= b) {\n let t = 0;\n for (let i = 0; i < b; i++) {\n t = data[i0 + i];\n data[i0 + i] = data[j0 + i];\n data[j0 + i] = t;\n }\n }\n this.knots.reflectKnots();\n }\n /**\n * Test if the leading and trailing polygon coordinates are replicated in the manner of a \"closed\" bspline polygon which has been expanded\n * to act as a normal bspline.\n * @returns true if `degree` leading and trailing polygon blocks match\n * @deprecated in 4.x. Use testClosablePolygon instead.\n */\n public testCloseablePolygon(mode?: BSplineWrapMode): boolean {\n return this.testClosablePolygon(mode);\n }\n /**\n * Test if the leading and trailing polygon coordinates are replicated in the manner of a \"closed\" bspline polygon which has been expanded\n * to act as a normal bspline.\n * @returns true if `degree` leading and trailing polygon blocks match\n */\n public testClosablePolygon(mode?: BSplineWrapMode): boolean {\n if (mode === undefined)\n mode = this.knots.wrappable;\n let numPolesToTest = 0;\n if (mode === BSplineWrapMode.OpenByAddingControlPoints)\n numPolesToTest = this.degree;\n else if (mode === BSplineWrapMode.OpenByRemovingKnots)\n numPolesToTest = 1;\n else\n return false;\n // check for wraparound poles\n const blockSize = this.poleLength;\n const indexDelta = (this.numPoles - numPolesToTest) * blockSize;\n const numValuesToTest = numPolesToTest * blockSize;\n for (let i0 = 0; i0 < numValuesToTest; i0++) {\n if (!Geometry.isSameCoordinate(this.packedData[i0], this.packedData[i0 + indexDelta]))\n return false;\n }\n return true;\n }\n\n /** Insert knot and resulting pole into the instance, optionally multiple times.\n * @param knot the knot to be inserted (may already exist in the KnotVector)\n * @param totalMultiplicity the total multiplicity of the knot on return\n */\n public addKnot(knot: number, totalMultiplicity: number): boolean {\n if (knot < this.knots.leftKnot || knot > this.knots.rightKnot)\n return false; // invalid input\n let iLeftKnot = this.knots.knotToLeftKnotIndex(knot);\n\n // snap input if too close to an existing knot\n if (Math.abs(knot - this.knots.knots[iLeftKnot]) < KnotVector.knotTolerance) {\n knot = this.knots.knots[iLeftKnot]; // snap to left knot of bracket\n } else if (Math.abs(knot - this.knots.knots[iLeftKnot + 1]) < KnotVector.knotTolerance) {\n iLeftKnot += this.knots.getKnotMultiplicityAtIndex(iLeftKnot + 1);\n if (iLeftKnot > this.knots.rightKnotIndex)\n return true; // nothing to do\n knot = this.knots.knots[iLeftKnot]; // snap to left knot of next bracket\n }\n const numKnotsToAdd = Math.min(totalMultiplicity, this.degree) - this.knots.getKnotMultiplicity(knot);\n if (numKnotsToAdd <= 0)\n return true; // nothing to do\n\n // working arrays and pole buffer\n let currKnotCount = this.knots.knots.length;\n const newKnots = new Float64Array(currKnotCount + numKnotsToAdd);\n for (let i = 0; i < currKnotCount; ++i)\n newKnots[i] = this.knots.knots[i];\n let currPoleCount = this.numPoles;\n const newPackedData = new Float64Array(this.packedData.length + (numKnotsToAdd * this.poleLength));\n for (let i = 0; i < this.packedData.length; ++i)\n newPackedData[i] = this.packedData[i];\n const dataBuf = new Float64Array(this.degree * this.poleLength); // holds degree poles\n\n // each iteration adds one knot and one pole to the working arrays (cf. Farin 4e)\n for (let iter = 0; iter < numKnotsToAdd; ++iter) {\n // fill the buffer with new poles obtained from control polygon corner cutting\n let iBuf = 0;\n const iStart = iLeftKnot - this.degree + 2;\n for (let i = iStart; i < iStart + this.degree; ++i) {\n const fraction = (knot - newKnots[i - 1]) / (newKnots[i + this.degree - 1] - newKnots[i - 1]);\n for (let j = i * this.poleLength; j < (i + 1) * this.poleLength; ++j) {\n dataBuf[iBuf++] = Geometry.interpolate(newPackedData[j - this.poleLength], fraction, newPackedData[j]);\n }\n }\n\n // overwrite degree-1 poles with degree new poles, shifting tail to the right by one\n newPackedData.copyWithin((iStart + this.degree) * this.poleLength, (iStart + this.degree - 1) * this.poleLength, currPoleCount * this.poleLength);\n let iData = iStart * this.poleLength;\n for (const d of dataBuf)\n newPackedData[iData++] = d; // overwrite degree new poles\n\n // add the knot to newKnots in position, shifting tail to the right by one\n newKnots.copyWithin(iLeftKnot + 2, iLeftKnot + 1, currKnotCount);\n newKnots[iLeftKnot + 1] = knot;\n\n ++iLeftKnot;\n ++currKnotCount;\n ++currPoleCount;\n }\n this.knots.setKnotsCapture(newKnots);\n this.packedData = newPackedData;\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"BSpline1dNd.js","sourceRoot":"","sources":["../../../src/bspline/BSpline1dNd.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module Bspline\n */\n\nimport { Geometry } from \"../Geometry\";\nimport { Point3d } from \"../geometry3d/Point3dVector3d\";\nimport { BSplineWrapMode, KnotVector } from \"./KnotVector\";\n\n/**\n * Knots and poles for a B-spline function mapping R to R^n.\n * * The \"pole\" (aka control point) of this class is a block of `poleLength` numbers.\n * * Derived classes (not this class) assign meaning such as x,y,z,w.\n * * For instance, an instance of this class with `poleLength===3` does not know if its poles are x,y,z or\n * weighted 2D x,y,w.\n * @public\n */\nexport class BSpline1dNd {\n /** Knots of the bspline. */\n public knots: KnotVector;\n /** Poles packed in blocks of `poleLength` doubles. */\n public packedData: Float64Array;\n /** The number of numeric values per pole. */\n public poleLength: number;\n /** (property accessor) Return the degree of the polynomials. */\n public get degree(): number {\n return this.knots.degree;\n }\n /** (property accessor) Return the order (one more than degree) of the polynomials. */\n public get order(): number {\n return this.knots.degree + 1;\n }\n /** (property accessor) Return the number of bezier spans (including null spans at multiple knots). */\n public get numSpan(): number {\n return this.numPoles - this.knots.degree;\n }\n /** (property accessor) Return the number of poles. */\n public get numPoles(): number {\n return this.packedData.length / this.poleLength;\n }\n /**\n * Copy 3 values of pole `i` into a point.\n * * The calling class is responsible for knowing if this is an appropriate access to the blocked data.\n */\n public getPoint3dPole(i: number, result?: Point3d): Point3d | undefined {\n return Point3d.createFromPacked(this.packedData, i, result);\n }\n /**\n * Values of the `order` relevant B-spline basis functions at a parameter.\n * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.\n */\n public basisBuffer: Float64Array;\n /**\n * Derivatives of the `order` relevant B-spline basis functions at a parameter.\n * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.\n */\n public basisBuffer1: Float64Array;\n /**\n * Second derivatives of the `order` relevant B-spline basis functions at a parameter.\n * * Preallocated to length `order` in the constructor and used as a temporary in evaluations.\n */\n public basisBuffer2: Float64Array;\n /**\n * Temporary to hold a single point.\n * * Preallocated to length `poleLength` in the constructor.\n */\n public poleBuffer: Float64Array;\n /**\n * Temporary to hold a single derivative vector.\n * * Preallocated to length `poleLength` in the constructor.\n */\n public poleBuffer1: Float64Array;\n /**\n * Temporary to hold a single second derivative vector.\n * * Preallocated to length `poleLength` in the constructor.\n */\n public poleBuffer2: Float64Array;\n /**\n * Initialize arrays for given spline dimensions.\n * @param numPoles number of poles.\n * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted,\n * 3 for 2d weighted).\n * @param order number of poles defining a Bezier segment of the B-spline function.\n * @param knots the KnotVector. This is captured, not cloned.\n */\n protected constructor(numPoles: number, poleLength: number, order: number, knots: KnotVector) {\n this.knots = knots;\n this.packedData = new Float64Array(numPoles * poleLength);\n this.poleLength = poleLength;\n this.basisBuffer = new Float64Array(order);\n this.basisBuffer1 = new Float64Array(order);\n this.basisBuffer2 = new Float64Array(order);\n this.poleBuffer = new Float64Array(poleLength);\n this.poleBuffer1 = new Float64Array(poleLength);\n this.poleBuffer2 = new Float64Array(poleLength);\n }\n /**\n * Create a `BSpline1dNd`.\n * @param numPoles number of poles.\n * @param poleLength number of coordinates per pole (e.g.. 3 for 3D unweighted, 4 for 3d weighted, 2 for 2d unweighted,\n * 3 for 2d weighted).\n * @param order number of poles defining a Bezier segment of the B-spline function.\n * @param knots the KnotVector. This is captured, not cloned.\n */\n public static create(numPoles: number, poleLength: number, order: number, knots: KnotVector): BSpline1dNd {\n return new BSpline1dNd(numPoles, poleLength, order, knots);\n }\n /** Map a span index and span fraction to knot value. */\n public spanFractionToKnot(spanIndex: number, spanFraction: number): number {\n return this.knots.spanFractionToKnot(spanIndex, spanFraction);\n }\n /**\n * Evaluate the `order` basis functions (and optionally one or two derivatives) at a given fractional position within\n * indexed span.\n * @returns true if and only if output arrays are sufficiently sized.\n */\n public evaluateBasisFunctionsInSpan(\n spanIndex: number, spanFraction: number, f: Float64Array, df?: Float64Array, ddf?: Float64Array,\n ): boolean {\n if (spanIndex < 0)\n spanIndex = 0;\n if (spanIndex >= this.numSpan)\n spanIndex = this.numSpan - 1;\n const knotIndex0 = spanIndex + this.degree - 1;\n const globalKnot = this.knots.baseKnotFractionToKnot(knotIndex0, spanFraction);\n return df ?\n this.knots.evaluateBasisFunctions1(knotIndex0, globalKnot, f, df, ddf) :\n this.knots.evaluateBasisFunctions(knotIndex0, globalKnot, f);\n }\n /**\n * Compute the linear combination of the given span's poles and the weights in `basisBuffer`, and store this point\n * in `poleBuffer`.\n */\n public sumPoleBufferForSpan(spanIndex: number) {\n this.poleBuffer.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer)\n for (let j = 0; j < this.poleLength; j++)\n this.poleBuffer[j] += f * this.packedData[k++];\n }\n /**\n * Compute the linear combination of the given span's poles and the weights in `basisBuffer1`, and store this\n * derivative vector in `poleBuffer1`.\n */\n public sumPoleBuffer1ForSpan(spanIndex: number) {\n this.poleBuffer1.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer1)\n for (let j = 0; j < this.poleLength; j++)\n this.poleBuffer1[j] += f * this.packedData[k++];\n }\n /**\n * Compute the linear combination of the given span's poles and the weights in `basisBuffer2`, and store this\n * second derivative vector in `poleBuffer2`.\n */\n public sumPoleBuffer2ForSpan(spanIndex: number) {\n this.poleBuffer2.fill(0);\n let k = spanIndex * this.poleLength;\n for (const f of this.basisBuffer2) {\n for (let j = 0; j < this.poleLength; j++)\n this.poleBuffer2[j] += f * this.packedData[k++];\n }\n }\n /**\n * * Evaluate the basis functions at spanIndex and fraction.\n * * Evaluations are stored in the preallocated `this.basisBuffer`.\n * * Immediately do the summations of the basis values times the respective poles.\n * * Summations are stored in the preallocated `this.poleBuffer`\n * */\n public evaluateBuffersInSpan(spanIndex: number, spanFraction: number) {\n this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer);\n this.sumPoleBufferForSpan(spanIndex);\n }\n /**\n * * Evaluate the basis functions and one derivative at spanIndex and fraction.\n * * Function evaluations are stored in the preallocated `this.basisBuffer`; derivative evaluations in `this.basisBuffer1`.\n * * Immediately do the summations of the basis values times the respective poles.\n * * Summations are stored in the preallocated `this.poleBuffer` and `this.poleBuffer1`\n * */\n public evaluateBuffersInSpan1(spanIndex: number, spanFraction: number) {\n this.evaluateBasisFunctionsInSpan(spanIndex, spanFraction, this.basisBuffer, this.basisBuffer1);\n this.sumPoleBufferForSpan(spanIndex);\n this.sumPoleBuffer1ForSpan(spanIndex);\n }\n /**\n * Evaluate the B-spline function and optional derivatives at the given parameter in knot space.\n * * Function value is stored in `poleBuffer`; optional derivative vectors in `poleBuffer1` and `poleBuffer2`.\n */\n public evaluateBuffersAtKnot(u: number, numDerivative: number = 0) {\n const knotIndex0 = this.knots.knotToLeftKnotIndex(u);\n if (numDerivative < 1) {\n this.knots.evaluateBasisFunctions(knotIndex0, u, this.basisBuffer);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n } else if (numDerivative === 1) {\n this.knots.evaluateBasisFunctions1(knotIndex0, u, this.basisBuffer, this.basisBuffer1);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer1ForSpan(knotIndex0 - this.degree + 1);\n } else {\n this.knots.evaluateBasisFunctions1(knotIndex0, u, this.basisBuffer, this.basisBuffer1, this.basisBuffer2);\n this.sumPoleBufferForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer1ForSpan(knotIndex0 - this.degree + 1);\n this.sumPoleBuffer2ForSpan(knotIndex0 - this.degree + 1);\n }\n }\n /** Reverse the instance poles and knots in place. */\n public reverseInPlace(): void {\n const pLen = this.poleLength;\n const data = this.packedData;\n for (let i0 = 0, j0 = pLen * (this.numPoles - 1); i0 < j0; i0 += pLen, j0 -= pLen) {\n for (let i = 0; i < pLen; i++)\n [data[i0 + i], data[j0 + i]] = [data[j0 + i], data[i0 + i]];\n }\n this.knots.reflectKnots();\n }\n /**\n * Test if the leading and trailing polygon coordinates are replicated in the manner of a \"closed\" bspline polygon\n * which has been expanded to act as a normal bspline.\n * @returns true if `degree` leading and trailing polygon blocks match.\n * @deprecated in 4.x. Use `testClosablePolygon` instead.\n */\n public testCloseablePolygon(mode?: BSplineWrapMode): boolean {\n return this.testClosablePolygon(mode);\n }\n /**\n * Test if the leading and trailing poles are replicated in the manner of a \"closed\" B-spline function with wraparound\n * control polygon.\n * @param mode wrap mode, indicating the number of wraparound poles to check. If undefined, `knots.wrappable` is used.\n * @returns true if the expected leading and trailing poles match, according to `mode`.\n */\n public testClosablePolygon(mode?: BSplineWrapMode): boolean {\n if (mode === undefined)\n mode = this.knots.wrappable;\n let numPolesToTest = 0;\n if (mode === BSplineWrapMode.OpenByAddingControlPoints)\n numPolesToTest = this.degree;\n else if (mode === BSplineWrapMode.OpenByRemovingKnots)\n numPolesToTest = 1;\n else\n return false;\n // check for wraparound poles\n const blockSize = this.poleLength;\n const indexDelta = (this.numPoles - numPolesToTest) * blockSize;\n const numValuesToTest = numPolesToTest * blockSize;\n for (let i0 = 0; i0 < numValuesToTest; i0++) {\n if (!Geometry.isSameCoordinate(this.packedData[i0], this.packedData[i0 + indexDelta]))\n return false;\n }\n return true;\n }\n /**\n * Insert the knot and resulting pole into the instance, optionally multiple times.\n * @param knot the knot to be inserted (may already exist in the KnotVector).\n * @param totalMultiplicity the total multiplicity of the knot on return.\n */\n public addKnot(knot: number, totalMultiplicity: number): boolean {\n if (knot < this.knots.leftKnot || knot > this.knots.rightKnot)\n return false; // invalid input\n let iLeftKnot = this.knots.knotToLeftKnotIndex(knot);\n // snap input if too close to an existing knot\n if (Math.abs(knot - this.knots.knots[iLeftKnot]) < KnotVector.knotTolerance) {\n knot = this.knots.knots[iLeftKnot]; // snap to left knot of bracket\n } else if (Math.abs(knot - this.knots.knots[iLeftKnot + 1]) < KnotVector.knotTolerance) {\n iLeftKnot += this.knots.getKnotMultiplicityAtIndex(iLeftKnot + 1);\n if (iLeftKnot > this.knots.rightKnotIndex)\n return true; // nothing to do\n knot = this.knots.knots[iLeftKnot]; // snap to left knot of next bracket\n }\n const numKnotsToAdd = Math.min(totalMultiplicity, this.degree) - this.knots.getKnotMultiplicity(knot);\n if (numKnotsToAdd <= 0)\n return true; // nothing to do\n // working arrays and pole buffer\n let currKnotCount = this.knots.knots.length;\n const newKnots = new Float64Array(currKnotCount + numKnotsToAdd);\n for (let i = 0; i < currKnotCount; ++i)\n newKnots[i] = this.knots.knots[i];\n let currPoleCount = this.numPoles;\n const newPackedData = new Float64Array(this.packedData.length + (numKnotsToAdd * this.poleLength));\n for (let i = 0; i < this.packedData.length; ++i)\n newPackedData[i] = this.packedData[i];\n const dataBuf = new Float64Array(this.degree * this.poleLength); // holds degree poles\n // each iteration adds one knot and one pole to the working arrays (cf. Farin 4e)\n for (let iter = 0; iter < numKnotsToAdd; ++iter) {\n // fill the buffer with new poles obtained from control polygon corner cutting\n let iBuf = 0;\n const iStart = iLeftKnot - this.degree + 2;\n for (let i = iStart; i < iStart + this.degree; ++i) {\n const fraction = (knot - newKnots[i - 1]) / (newKnots[i + this.degree - 1] - newKnots[i - 1]);\n for (let j = i * this.poleLength; j < (i + 1) * this.poleLength; ++j) {\n dataBuf[iBuf++] = Geometry.interpolate(newPackedData[j - this.poleLength], fraction, newPackedData[j]);\n }\n }\n // overwrite degree-1 poles with degree new poles, shifting tail to the right by one\n newPackedData.copyWithin((iStart + this.degree) * this.poleLength, (iStart + this.degree - 1) * this.poleLength, currPoleCount * this.poleLength);\n let iData = iStart * this.poleLength;\n for (const d of dataBuf)\n newPackedData[iData++] = d; // overwrite degree new poles\n // add the knot to newKnots in position, shifting tail to the right by one\n newKnots.copyWithin(iLeftKnot + 2, iLeftKnot + 1, currKnotCount);\n newKnots[iLeftKnot + 1] = knot;\n ++iLeftKnot;\n ++currKnotCount;\n ++currPoleCount;\n }\n this.knots.setKnotsCapture(newKnots);\n this.packedData = newPackedData;\n return true;\n }\n}\n"]}