@itwin/core-geometry 4.0.0-dev.46 → 4.0.0-dev.50

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 (79) hide show
  1. package/lib/cjs/clipping/ClipPrimitive.d.ts +0 -1
  2. package/lib/cjs/clipping/ClipPrimitive.d.ts.map +1 -1
  3. package/lib/cjs/clipping/ClipPrimitive.js +0 -1
  4. package/lib/cjs/clipping/ClipPrimitive.js.map +1 -1
  5. package/lib/cjs/clipping/ClipUtils.d.ts +19 -5
  6. package/lib/cjs/clipping/ClipUtils.d.ts.map +1 -1
  7. package/lib/cjs/clipping/ClipUtils.js +32 -5
  8. package/lib/cjs/clipping/ClipUtils.js.map +1 -1
  9. package/lib/cjs/curve/CurveCurve.d.ts +2 -5
  10. package/lib/cjs/curve/CurveCurve.d.ts.map +1 -1
  11. package/lib/cjs/curve/CurveCurve.js +2 -5
  12. package/lib/cjs/curve/CurveCurve.js.map +1 -1
  13. package/lib/cjs/curve/CurveCurveIntersectXY.js +1 -1
  14. package/lib/cjs/curve/CurveCurveIntersectXY.js.map +1 -1
  15. package/lib/cjs/curve/CurveCurveIntersectXYZ.js +1 -1
  16. package/lib/cjs/curve/CurveCurveIntersectXYZ.js.map +1 -1
  17. package/lib/cjs/geometry3d/Matrix3d.d.ts +17 -4
  18. package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
  19. package/lib/cjs/geometry3d/Matrix3d.js +18 -6
  20. package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
  21. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.d.ts +0 -1
  22. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.d.ts.map +1 -1
  23. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js +0 -1
  24. package/lib/cjs/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  25. package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.d.ts +1 -1
  26. package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.js +1 -1
  27. package/lib/cjs/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  28. package/lib/cjs/geometry3d/Transform.d.ts +159 -107
  29. package/lib/cjs/geometry3d/Transform.d.ts.map +1 -1
  30. package/lib/cjs/geometry3d/Transform.js +238 -137
  31. package/lib/cjs/geometry3d/Transform.js.map +1 -1
  32. package/lib/cjs/geometry3d/XYZProps.d.ts +22 -21
  33. package/lib/cjs/geometry3d/XYZProps.d.ts.map +1 -1
  34. package/lib/cjs/geometry3d/XYZProps.js +2 -1
  35. package/lib/cjs/geometry3d/XYZProps.js.map +1 -1
  36. package/lib/cjs/polyface/PolyfaceBuilder.d.ts +7 -5
  37. package/lib/cjs/polyface/PolyfaceBuilder.d.ts.map +1 -1
  38. package/lib/cjs/polyface/PolyfaceBuilder.js +17 -7
  39. package/lib/cjs/polyface/PolyfaceBuilder.js.map +1 -1
  40. package/lib/esm/clipping/ClipPrimitive.d.ts +0 -1
  41. package/lib/esm/clipping/ClipPrimitive.d.ts.map +1 -1
  42. package/lib/esm/clipping/ClipPrimitive.js +0 -1
  43. package/lib/esm/clipping/ClipPrimitive.js.map +1 -1
  44. package/lib/esm/clipping/ClipUtils.d.ts +19 -5
  45. package/lib/esm/clipping/ClipUtils.d.ts.map +1 -1
  46. package/lib/esm/clipping/ClipUtils.js +32 -5
  47. package/lib/esm/clipping/ClipUtils.js.map +1 -1
  48. package/lib/esm/curve/CurveCurve.d.ts +2 -5
  49. package/lib/esm/curve/CurveCurve.d.ts.map +1 -1
  50. package/lib/esm/curve/CurveCurve.js +2 -5
  51. package/lib/esm/curve/CurveCurve.js.map +1 -1
  52. package/lib/esm/curve/CurveCurveIntersectXY.js +1 -1
  53. package/lib/esm/curve/CurveCurveIntersectXY.js.map +1 -1
  54. package/lib/esm/curve/CurveCurveIntersectXYZ.js +1 -1
  55. package/lib/esm/curve/CurveCurveIntersectXYZ.js.map +1 -1
  56. package/lib/esm/geometry3d/Matrix3d.d.ts +17 -4
  57. package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
  58. package/lib/esm/geometry3d/Matrix3d.js +18 -6
  59. package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
  60. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.d.ts +0 -1
  61. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.d.ts.map +1 -1
  62. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js +0 -1
  63. package/lib/esm/geometry3d/Plane3dByOriginAndUnitNormal.js.map +1 -1
  64. package/lib/esm/geometry3d/Plane3dByOriginAndVectors.d.ts +1 -1
  65. package/lib/esm/geometry3d/Plane3dByOriginAndVectors.js +1 -1
  66. package/lib/esm/geometry3d/Plane3dByOriginAndVectors.js.map +1 -1
  67. package/lib/esm/geometry3d/Transform.d.ts +159 -107
  68. package/lib/esm/geometry3d/Transform.d.ts.map +1 -1
  69. package/lib/esm/geometry3d/Transform.js +238 -137
  70. package/lib/esm/geometry3d/Transform.js.map +1 -1
  71. package/lib/esm/geometry3d/XYZProps.d.ts +22 -21
  72. package/lib/esm/geometry3d/XYZProps.d.ts.map +1 -1
  73. package/lib/esm/geometry3d/XYZProps.js +2 -1
  74. package/lib/esm/geometry3d/XYZProps.js.map +1 -1
  75. package/lib/esm/polyface/PolyfaceBuilder.d.ts +7 -5
  76. package/lib/esm/polyface/PolyfaceBuilder.d.ts.map +1 -1
  77. package/lib/esm/polyface/PolyfaceBuilder.js +17 -7
  78. package/lib/esm/polyface/PolyfaceBuilder.js.map +1 -1
  79. package/package.json +3 -3
@@ -14,21 +14,25 @@ const Matrix3d_1 = require("./Matrix3d");
14
14
  const Point2dVector2d_1 = require("./Point2dVector2d");
15
15
  const Point3dVector3d_1 = require("./Point3dVector3d");
16
16
  const Range_1 = require("./Range");
17
- /** A transform is an origin and a Matrix3d.
18
- *
19
- * * This describes a coordinate frame with
20
- * this origin, with the columns of the Matrix3d being the
21
- * local x,y,z axis directions.
22
- * * Beware that for common transformations (e.g. scale about point,
23
- * rotate around line, mirror across a plane) the "fixed point" that is used
24
- * when describing the transform is NOT the "origin" stored in the transform.
25
- * Setup methods (e.g createFixedPointAndMatrix, createScaleAboutPoint)
26
- * take care of determining the appropriate origin coordinates.
17
+ /**
18
+ * A Transform consists of an origin and a Matrix3d. This describes a coordinate frame with this origin, with
19
+ * the columns of the Matrix3d being the local x,y,z axis directions.
20
+ * * The math for a Transform `T` consisting of a Matrix3d `M` and a Point3d `o` on a Vector3d `p` is: `Tp = M*p + o`.
21
+ * In other words, `T` is a combination of two operations on `p`: the action of matrix multiplication, followed by a
22
+ * translation. `Origin` is a traditional term for `o`, because `T` can be interpreted as a change of basis from the
23
+ * global axes centered at the global origin, to a new set of axes centered at `o`.
24
+ * * Beware that for common transformations (e.g. scale about point, rotate around an axis, mirror across a
25
+ * plane) the "fixed point" that is used when describing the transform is NOT the "origin" stored in the
26
+ * transform. Setup methods (e.g createFixedPointAndMatrix, createScaleAboutPoint) take care of determining
27
+ * the appropriate origin coordinates.
27
28
  * @public
28
29
  */
29
30
  class Transform {
30
- // Constructor accepts and uses POINTER to content .. no copy here.
31
- constructor(origin, matrix) { this._origin = origin; this._matrix = matrix; }
31
+ // Constructor accepts and uses pointer to content (no copy is done here).
32
+ constructor(origin, matrix) {
33
+ this._origin = origin;
34
+ this._matrix = matrix;
35
+ }
32
36
  /** The identity Transform. Value is frozen and cannot be modified. */
33
37
  static get identity() {
34
38
  if (undefined === this._identity) {
@@ -38,18 +42,31 @@ class Transform {
38
42
  return this._identity;
39
43
  }
40
44
  /** Freeze this instance (and its members) so it is read-only */
41
- freeze() { this._origin.freeze(); this._matrix.freeze(); return Object.freeze(this); }
45
+ freeze() {
46
+ this._origin.freeze();
47
+ this._matrix.freeze();
48
+ return Object.freeze(this);
49
+ }
42
50
  /**
43
51
  * Copy contents from other Transform into this Transform
44
52
  * @param other source transform
45
53
  */
46
- setFrom(other) { this._origin.setFrom(other._origin), this._matrix.setFrom(other._matrix); }
54
+ setFrom(other) {
55
+ this._origin.setFrom(other._origin);
56
+ this._matrix.setFrom(other._matrix);
57
+ }
47
58
  /** Set this Transform to be an identity. */
48
- setIdentity() { this._origin.setZero(); this._matrix.setIdentity(); }
49
- /** Set this Transform instance from flexible inputs:
50
- * * Any object (such as another Transform) that has `origin` and `matrix` members accepted by Point3d.setFromJSON and Matrix3d.setFromJSON
59
+ setIdentity() {
60
+ this._origin.setZero();
61
+ this._matrix.setIdentity();
62
+ }
63
+ /**
64
+ * Set this Transform instance from flexible inputs:
65
+ * * Any object (such as another Transform or TransformProps) that has `origin` and `matrix` members
66
+ * accepted by `Point3d.setFromJSON` and `Matrix3d.setFromJSON`
51
67
  * * An array of 3 number arrays, each with 4 entries which are rows in a 3x4 matrix.
52
68
  * * An array of 12 numbers, each block of 4 entries as a row 3x4 matrix.
69
+ * * If no input is provided, the identity Transform is returned.
53
70
  */
54
71
  setFromJSON(json) {
55
72
  if (json) {
@@ -74,25 +91,24 @@ class Transform {
74
91
  this.setIdentity();
75
92
  }
76
93
  /**
77
- * Test for near equality with other Transform. Comparison uses the isAlmostEqual methods on
78
- * the origin and matrix parts.
94
+ * Test for near equality with `other` Transform. Comparison uses the `isAlmostEqual` methods on the `origin` and
95
+ * `matrix` parts.
79
96
  * @param other Transform to compare to.
80
97
  */
81
- isAlmostEqual(other) { return this.origin.isAlmostEqual(other.origin) && this.matrix.isAlmostEqual(other.matrix); }
98
+ isAlmostEqual(other) {
99
+ return this.origin.isAlmostEqual(other.origin) && this.matrix.isAlmostEqual(other.matrix);
100
+ }
82
101
  /**
83
- * Test for near equality with other Transform. Comparison uses the isAlmostEqualAllowZRotation method of Matrix3d
84
- * the origin and matrix parts.
102
+ * Test for near equality with `other` Transform. Comparison uses the `isAlmostEqual` methods on the `origin` part
103
+ * and the `isAlmostEqualAllowZRotation` method on the `matrix` part.
85
104
  * @param other Transform to compare to.
86
105
  */
87
- isAlmostEqualAllowZRotation(other) { return this._origin.isAlmostEqual(other._origin) && this._matrix.isAlmostEqualAllowZRotation(other._matrix); }
88
- /** Return a 3 by 4 matrix containing the rows of this Transform
89
- * * This transform's origin is the [3] entry of the json arrays
90
- */
91
- toJSON() {
92
- return this.toRows();
106
+ isAlmostEqualAllowZRotation(other) {
107
+ return this._origin.isAlmostEqual(other._origin) && this._matrix.isAlmostEqualAllowZRotation(other._matrix);
93
108
  }
94
- /** Return a 3 by 4 matrix containing the rows of this Transform
95
- * * This transform's origin is the [3] entry of the json arrays
109
+ /**
110
+ * Return a 3 by 4 matrix containing the rows of this Transform.
111
+ * * The transform's origin coordinates are the last entries of the 3 json arrays
96
112
  */
97
113
  toRows() {
98
114
  return [
@@ -101,13 +117,20 @@ class Transform {
101
117
  [this._matrix.coffs[6], this._matrix.coffs[7], this._matrix.coffs[8], this._origin.z],
102
118
  ];
103
119
  }
104
- /** Return a new Transform initialized by `setFromJSON (json)` */
120
+ /**
121
+ * Return a 3 by 4 matrix containing the rows of this Transform.
122
+ * * The transform's origin coordinates are the last entries of the 3 json arrays
123
+ */
124
+ toJSON() {
125
+ return this.toRows();
126
+ }
127
+ /** Return a new Transform initialized by `Transform.setFromJSON` */
105
128
  static fromJSON(json) {
106
129
  const result = Transform.createIdentity();
107
130
  result.setFromJSON(json);
108
131
  return result;
109
132
  }
110
- /** Copy the contents of this transform into a new Transform (or to the result, if specified). */
133
+ /** Copy the contents of `this` transform into a new Transform (or to the result, if specified). */
111
134
  clone(result) {
112
135
  if (result) {
113
136
  result._matrix.setFrom(this._matrix);
@@ -116,18 +139,17 @@ class Transform {
116
139
  }
117
140
  return new Transform(Point3dVector3d_1.Point3d.createFrom(this._origin), this._matrix.clone());
118
141
  }
119
- /** Return a copy of this Transform, modified so that its axes are rigid
120
- * * The first axis direction named in axisOrder is preserved
121
- * * The plane of the first and second directions is preserved, and its vector in the rigid matrix has positive dot product with the corresponding vector if the instance
122
- * * The third named column is the cross product of the first and second.
142
+ /**
143
+ * Return a modified copy of `this` Transform so that its `matrix` part is rigid (`origin` part is untouched).
144
+ * * For details of how the matrix is modified to rigid, see documentation of `Matrix3d.axisOrderCrossProductsInPlace`
123
145
  */
124
146
  cloneRigid(axisOrder = Geometry_1.AxisOrder.XYZ) {
125
- const axes0 = Matrix3d_1.Matrix3d.createRigidFromMatrix3d(this.matrix, axisOrder);
126
- if (!axes0)
147
+ const modifiedMatrix = Matrix3d_1.Matrix3d.createRigidFromMatrix3d(this.matrix, axisOrder);
148
+ if (!modifiedMatrix)
127
149
  return undefined;
128
- return new Transform(this.origin.cloneAsPoint3d(), axes0);
150
+ return new Transform(this.origin.cloneAsPoint3d(), modifiedMatrix);
129
151
  }
130
- /** Create a copy with the given origin and matrix captured as the Transform origin and Matrix3d. */
152
+ /** Create a Transform with the given `origin` and `matrix`. */
131
153
  static createRefs(origin, matrix, result) {
132
154
  if (!origin)
133
155
  origin = Point3dVector3d_1.Point3d.createZero();
@@ -138,7 +160,7 @@ class Transform {
138
160
  }
139
161
  return new Transform(origin, matrix);
140
162
  }
141
- /** Create a transform with complete contents given */
163
+ /** Create a Transform with complete contents given */
142
164
  static createRowValues(qxx, qxy, qxz, ax, qyx, qyy, qyz, ay, qzx, qzy, qzz, az, result) {
143
165
  if (result) {
144
166
  result._origin.set(ax, ay, az);
@@ -147,42 +169,55 @@ class Transform {
147
169
  }
148
170
  return new Transform(Point3dVector3d_1.Point3d.create(ax, ay, az), Matrix3d_1.Matrix3d.createRowValues(qxx, qxy, qxz, qyx, qyy, qyz, qzx, qzy, qzz));
149
171
  }
150
- /** Create a transform with all zeros.
151
- */
172
+ /** Create a Transform with all zeros */
152
173
  static createZero(result) {
153
174
  return Transform.createRowValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, result);
154
175
  }
155
176
  /**
156
- * create a Transform with translation provided by x,y,z parts.
177
+ * Create a Transform with translation provided by x,y,z parts.
157
178
  * @param x x part of translation
158
179
  * @param y y part of translation
159
180
  * @param z z part of translation
160
- * @param result optional result
161
- * @returns new or updated transform.
181
+ * @param result optional pre-allocated Transform
182
+ * @returns new or updated transform
162
183
  */
163
184
  static createTranslationXYZ(x = 0, y = 0, z = 0, result) {
164
185
  return Transform.createRefs(Point3dVector3d_1.Vector3d.create(x, y, z), Matrix3d_1.Matrix3d.createIdentity(), result);
165
186
  }
166
- /** Create a matrix with specified translation part.
167
- * @param XYZ x,y,z parts of the translation.
168
- * @returns new or updated transform.
187
+ /**
188
+ * Create a Transform with specified `translation` part.
189
+ * @param translation x,y,z parts of the translation
190
+ * @param result optional pre-allocated Transform
191
+ * @returns new or updated transform
169
192
  */
170
193
  static createTranslation(translation, result) {
171
194
  return Transform.createRefs(translation, Matrix3d_1.Matrix3d.createIdentity(), result);
172
195
  }
173
- /** Return a reference to the matrix within the transform. (NOT a copy) */
174
- get matrix() { return this._matrix; }
175
- /** Return a reference to the origin within the transform. (NOT a copy) */
176
- get origin() { return this._origin; }
177
- /** return a (clone of) the origin part of the transform, as a Point3d */
178
- getOrigin() { return Point3dVector3d_1.Point3d.createFrom(this._origin); }
179
- /** return a (clone of) the origin part of the transform, as a Vector3d */
180
- getTranslation() { return Point3dVector3d_1.Vector3d.createFrom(this._origin); }
181
- /** test if the transform has 000 origin and identity Matrix3d */
196
+ /** Return a reference (and NOT a copy) to the `matrix` part of the Transform. */
197
+ get matrix() {
198
+ return this._matrix;
199
+ }
200
+ /** Return a reference (and NOT a copy) to the `origin` part of the Transform. */
201
+ get origin() {
202
+ return this._origin;
203
+ }
204
+ /** return a (clone of) the `origin` part of the Transform, as a `Point3d` */
205
+ getOrigin() {
206
+ return Point3dVector3d_1.Point3d.createFrom(this._origin);
207
+ }
208
+ /** return a (clone of) the `origin` part of the Transform, as a `Vector3d` */
209
+ getTranslation() {
210
+ return Point3dVector3d_1.Vector3d.createFrom(this._origin);
211
+ }
212
+ /** return a (clone of) the `matrix` part of the Transform, as a `Matrix3d` */
213
+ getMatrix() {
214
+ return this._matrix.clone();
215
+ }
216
+ /** test if the transform has `origin` = (0,0,0) and identity `matrix` */
182
217
  get isIdentity() {
183
218
  return this._matrix.isIdentity && this._origin.isAlmostZero;
184
219
  }
185
- /** Return an identity transform, optionally filling existing transform. */
220
+ /** Create an identity transform */
186
221
  static createIdentity(result) {
187
222
  if (result) {
188
223
  result._origin.setZero();
@@ -191,9 +226,12 @@ class Transform {
191
226
  }
192
227
  return Transform.createRefs(Point3dVector3d_1.Point3d.createZero(), Matrix3d_1.Matrix3d.createIdentity());
193
228
  }
194
- /** Create by directly installing origin and matrix
195
- * this is a the appropriate construction when the columns of the matrix are coordinate axes of a local-to-global mapping
196
- * Note there is a closely related createFixedPointAndMatrix whose point input is the fixed point of the global-to-global transformation.
229
+ /**
230
+ * Create a Transform using the given `origin` and `matrix`.
231
+ * * This is a the appropriate construction when the columns of the matrix are coordinate axes of a
232
+ * local-to-world mapping.
233
+ * * This function is a closely related to `createFixedPointAndMatrix` whose point input is the fixed point
234
+ * of the world-to-world transformation.
197
235
  */
198
236
  static createOriginAndMatrix(origin, matrix, result) {
199
237
  if (result) {
@@ -203,8 +241,13 @@ class Transform {
203
241
  }
204
242
  return Transform.createRefs(origin ? origin.cloneAsPoint3d() : Point3dVector3d_1.Point3d.createZero(), matrix === undefined ? Matrix3d_1.Matrix3d.createIdentity() : matrix.clone(), result);
205
243
  }
206
- /** Create by directly installing origin and columns of the matrix
207
- */
244
+ /** Create a Transform using the given `origin` and columns of the `matrix`. If `undefined` zero is used. */
245
+ setOriginAndMatrixColumns(origin, vectorX, vectorY, vectorZ) {
246
+ if (origin !== undefined)
247
+ this._origin.setFrom(origin);
248
+ this._matrix.setColumns(vectorX, vectorY, vectorZ);
249
+ }
250
+ /** Create a Transform using the given `origin` and columns of the `matrix` */
208
251
  static createOriginAndMatrixColumns(origin, vectorX, vectorY, vectorZ, result) {
209
252
  if (result)
210
253
  result.setOriginAndMatrixColumns(origin, vectorX, vectorY, vectorZ);
@@ -212,127 +255,177 @@ class Transform {
212
255
  result = Transform.createRefs(Point3dVector3d_1.Vector3d.createFrom(origin), Matrix3d_1.Matrix3d.createColumns(vectorX, vectorY, vectorZ));
213
256
  return result;
214
257
  }
215
- /** Create by with matrix from Matrix3d.createRigidFromColumns.
216
- * * Has careful logic for building up optional result without allocations.
258
+ /**
259
+ * Create a Transform such that its `matrix` part is rigid.
260
+ * * For details of how the matrix is created to be rigid, see documentation of `Matrix3d.createRigidFromColumns`
217
261
  */
218
262
  static createRigidFromOriginAndColumns(origin, vectorX, vectorY, axisOrder, result) {
219
263
  const matrix = Matrix3d_1.Matrix3d.createRigidFromColumns(vectorX, vectorY, axisOrder, result ? result._matrix : undefined);
220
264
  if (!matrix)
221
265
  return undefined;
222
266
  if (result) {
223
- // The matrix was already defined !!!
267
+ // result._matrix was already modified to become rigid via createRigidFromColumns
224
268
  result._origin.setFrom(origin);
225
269
  return result;
226
270
  }
227
- // cleanly capture the matrix and then the point ..
271
+ /**
272
+ * We don't want to pass "origin" to createRefs because createRefs does not clone "origin" and use its reference.
273
+ * That means if "origin" is changed via Transform at any point, the initial "origin" passed by the user is also
274
+ * changed. To avoid that, we pass undefined to createRefs. This would cause createRefs to create a new "origin"
275
+ * equals (0,0,0) which then we set it to the "origin" passed by user in the next line.
276
+ */
228
277
  result = Transform.createRefs(undefined, matrix);
229
278
  result._origin.setFromPoint3d(origin);
230
279
  return result;
231
280
  }
232
- /** Reinitialize by directly installing origin and columns of the matrix
233
- */
234
- setOriginAndMatrixColumns(origin, vectorX, vectorY, vectorZ) {
235
- if (origin !== undefined)
236
- this._origin.setFrom(origin);
237
- this._matrix.setColumns(vectorX, vectorY, vectorZ);
238
- }
239
- /** Create a transform with the specified matrix. Compute an origin (different from the given fixedPoint)
240
- * so that the fixedPoint maps back to itself.
281
+ /**
282
+ * Create a Transform with the specified `matrix`. Compute an `origin` (different from the given `fixedPoint`)
283
+ * so that the `fixedPoint` maps back to itself. The returned Transform, transforms a point `p` to `M*p + (f - M*f)`
284
+ * where `f` is the fixedPoint (i.e., `Tp = M*(p-f) + f`).
241
285
  */
242
286
  static createFixedPointAndMatrix(fixedPoint, matrix, result) {
243
287
  if (fixedPoint) {
288
+ /**
289
+ * if f is a fixed point, then Tf = M*f + o = f where M is the matrix and o is the origin.
290
+ * we define the origin o = f - M*f. Therefore, Tf = Mf + o = M*f + (f - M*f) = f.
291
+ */
244
292
  const origin = Matrix3d_1.Matrix3d.xyzMinusMatrixTimesXYZ(fixedPoint, matrix, fixedPoint);
245
293
  return Transform.createRefs(origin, matrix.clone(), result);
246
294
  }
247
295
  return Transform.createRefs(undefined, matrix.clone());
248
296
  }
249
- /** Create a transform with the specified matrix, acting on any `pointX `via
250
- * `pointY = matrix * (pointX - pointA) + pointB`
251
- * so that the fixedPoint maps back to itself.
297
+ /**
298
+ * Create a transform with the specified `matrix` and points `a` and `b`. The returned Transform, transforms
299
+ * point `p` to `M*(p-a) + b` (i.e., `Tp = M*(p-a) + b`) so transforms point `a` to 'b'.
252
300
  */
253
- static createMatrixPickupPutdown(matrix, pointA, pointB, result) {
254
- const origin = Matrix3d_1.Matrix3d.xyzMinusMatrixTimesXYZ(pointB, matrix, pointA);
301
+ static createMatrixPickupPutdown(matrix, a, b, result) {
302
+ // we define the origin o = b - M*a so Tp = M*p + o = M*p + (b - M*a) = M*(x-a) + b
303
+ const origin = Matrix3d_1.Matrix3d.xyzMinusMatrixTimesXYZ(b, matrix, a);
255
304
  return Transform.createRefs(origin, matrix.clone(), result);
256
305
  }
257
- /** Create a Transform which leaves the fixedPoint unchanged and
258
- * scales everything else around it by a single scale factor.
306
+ /**
307
+ * Create a Transform which leaves the fixedPoint unchanged and scales everything else around it by
308
+ * a single scale factor. The returned Transform, transforms a point `p` to `M*p + (f - M*f)`
309
+ * where `f` is the fixedPoint and M is the scale matrix (i.e., `Tp = M*(p-f) + f`).
259
310
  */
260
311
  static createScaleAboutPoint(fixedPoint, scale, result) {
261
312
  const matrix = Matrix3d_1.Matrix3d.createScale(scale, scale, scale);
313
+ /**
314
+ * if f is a fixed point, then Tf = M*f + o = f where M is the matrix and o is the origin.
315
+ * we define the origin o = f - M*f. Therefore, Tf = M*f + o = M*f + (f - M*f) = f.
316
+ */
262
317
  const origin = Matrix3d_1.Matrix3d.xyzMinusMatrixTimesXYZ(fixedPoint, matrix, fixedPoint);
263
318
  return Transform.createRefs(origin, matrix, result);
264
319
  }
265
- /** Transform the input 2d point. Return as a new point or in the pre-allocated result (if result is given) */
266
- multiplyPoint2d(source, result) {
267
- return Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix, source, result);
320
+ /** Transform the input 2d point. Return as a new point or in the pre-allocated result (if result is given). */
321
+ multiplyPoint2d(point, result) {
322
+ // Tx = Mx + o so we return Mx + o
323
+ return Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix, point, result);
268
324
  }
269
- /** Transform the input 3d point. Return as a new point or in the pre-allocated result (if result is given) */
325
+ /** Transform the input 3d point. Return as a new point or in the pre-allocated result (if result is given). */
270
326
  multiplyPoint3d(point, result) {
327
+ // Tx = Mx + o so we return Mx + o
271
328
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, point, result);
272
329
  }
273
- /** Transform the input object with x,y,z members */
330
+ /** Transform the input 3d point in place (override the input point by the transformed point). */
274
331
  multiplyXYAndZInPlace(point) {
332
+ // Tx = Mx + o so we override x by Mx + o
275
333
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZInPlace(this._origin, this._matrix, point);
276
334
  }
277
- /** Transform the input point. Return as a new point or in the pre-allocated result (if result is given) */
335
+ /** Transform the input point. Return as a new point or in the pre-allocated result (if result is given). */
278
336
  multiplyXYZ(x, y, z = 0, result) {
337
+ // Tx = Mx + o so we return Mx + o
279
338
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesCoordinates(this._origin, this._matrix, x, y, z, result);
280
339
  }
281
- /** Multiply a specific row of the transform times xyz. Return the (number). */
340
+ /**
341
+ * Multiply a specific row (component) of the transform matrix times xyz and add it to the origin element
342
+ * at the same row. Return the result.
343
+ */
282
344
  multiplyComponentXYZ(componentIndex, x, y, z = 0) {
283
345
  const coffs = this._matrix.coffs;
284
- const i0 = 3 * componentIndex;
285
- return this.origin.at(componentIndex) + coffs[i0] * x + coffs[i0 + 1] * y + coffs[i0 + 2] * z;
346
+ const idx = 3 * componentIndex;
347
+ return this.origin.at(componentIndex) + (coffs[idx] * x) + (coffs[idx + 1] * y) + (coffs[idx + 2] * z);
286
348
  }
287
- /** Multiply a specific row of the transform times (weighted!) xyzw. Return the (number). */
349
+ /**
350
+ * Multiply a specific row (component) of the transform matrix times xyz and add it to the origin element
351
+ * at the same row times w. Return the result.
352
+ */
288
353
  multiplyComponentXYZW(componentIndex, x, y, z, w) {
289
354
  const coffs = this._matrix.coffs;
290
- const i0 = 3 * componentIndex;
291
- return this.origin.at(componentIndex) * w +
292
- coffs[i0] * x + coffs[i0 + 1] * y + coffs[i0 + 2] * z;
355
+ const idx = 3 * componentIndex;
356
+ return (this.origin.at(componentIndex) * w) + (coffs[idx] * x) + (coffs[idx + 1] * y) + (coffs[idx + 2] * z);
293
357
  }
294
- /** Transform the input homogeneous point. Return as a new point or in the pre-allocated result (if result is given) */
358
+ /**
359
+ * If `p = (x,y,z)` then transform is `Tp = M*p + o*w`. This function returns the transformed point as a new
360
+ * point4d (`Tp` as first 3 elements and `w` as last element) or in the pre-allocated result (if result is given).
361
+ */
295
362
  multiplyXYZW(x, y, z, w, result) {
296
363
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesWeightedCoordinates(this._origin, this._matrix, x, y, z, w, result);
297
364
  }
298
- /** Transform the input homogeneous point. Return as a new point or in the pre-allocated result (if result is given) */
365
+ /**
366
+ * If `p = (x,y,z)` then transform is `Tp = M*p + o*w`. This function returns the transformed point as a new
367
+ * Float64Array with size 4 (`Tp` as first 3 elements and `w` as last element) or in the pre-allocated result
368
+ * (if result is given).
369
+ */
299
370
  multiplyXYZWToFloat64Array(x, y, z, w, result) {
300
371
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesWeightedCoordinatesToFloat64Array(this._origin, this._matrix, x, y, z, w, result);
301
372
  }
302
- /** Transform the input homogeneous point. Return as a new point or in the pre-allocated result (if result is given) */
373
+ /**
374
+ * If `p = (x,y,z)` then transform is `Tp = M*p + o`. This function returns the transformed point as a new
375
+ * Float64Array with size 3 (`Tp` as 3 elements) or in the pre-allocated result (if result is given).
376
+ */
303
377
  multiplyXYZToFloat64Array(x, y, z, result) {
304
378
  return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesCoordinatesToFloat64Array(this._origin, this._matrix, x, y, z, result);
305
379
  }
306
- /** Multiply the transposed transform (as 4x4 with 0001 row) by Point4d given as xyzw.. Return as a new point or in the pre-allocated result (if result is given) */
380
+ /**
381
+ * Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row. Now multiply
382
+ * the transposed of this 4x4 matrix by Point4d given as xyzw. Return as a new point4d (`M*p` as first 3 elements
383
+ * and `o*p + w` as last element where `p = (x,y,z)`) or in the pre-allocated result (if result is given).
384
+ */
307
385
  multiplyTransposeXYZW(x, y, z, w, result) {
308
386
  const coffs = this._matrix.coffs;
309
387
  const origin = this._origin;
310
- return Point4d_1.Point4d.create(x * coffs[0] + y * coffs[3] + z * coffs[6], x * coffs[1] + y * coffs[4] + z * coffs[7], x * coffs[2] + y * coffs[5] + z * coffs[8], x * origin.x + y * origin.y + z * origin.z + w, result);
388
+ return Point4d_1.Point4d.create((x * coffs[0]) + (y * coffs[3]) + (z * coffs[6]), (x * coffs[1]) + (y * coffs[4]) + (z * coffs[7]), (x * coffs[2]) + (y * coffs[5]) + (z * coffs[8]), (x * origin.x) + (y * origin.y) + (z * origin.z) + w, result);
311
389
  }
312
- /** for each point: replace point by Transform*point */
390
+ /** For each point in the array, replace point by the transformed point (by `Tp = M*p + o`) */
313
391
  multiplyPoint3dArrayInPlace(points) {
314
392
  let point;
315
393
  for (point of points)
316
394
  Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, point, point);
317
395
  }
318
- /** for each point: replace point by Transform*point */
396
+ /** For each point in the 2d array, replace point by the transformed point (by `Tp = M*p + o`) */
319
397
  multiplyPoint3dArrayArrayInPlace(chains) {
320
398
  for (const chain of chains)
321
399
  this.multiplyPoint3dArrayInPlace(chain);
322
400
  }
323
- /** Return product of the transform's inverse times a point. */
401
+ /**
402
+ * If for a point `p` we have `Tp = M*p + o = point` (where `point` is the transformed point), then
403
+ * `p = MInverse * (point - o)`. This function returns the original point `p` if `point` is the
404
+ * transformed point (`Tp = point`).
405
+ * * Return as a new point or in the optional `result`.
406
+ * * Returns `undefined` if the `matrix` part if this Transform is singular.
407
+ */
324
408
  multiplyInversePoint3d(point, result) {
325
409
  return this._matrix.multiplyInverseXYZAsPoint3d(point.x - this._origin.x, point.y - this._origin.y, point.z - this._origin.z, result);
326
410
  }
327
- /** Inverse transform the input homogeneous point.
328
- * * Return as a new point or in the optional result.
329
- * * returns undefined if the matrix part if this Transform is singular.
411
+ /**
412
+ * If for a point `p` we have `Tp = M*p + w*o = weightedPoint` (where `weightedPoint` is the transformed point), then
413
+ * `p = MInverse * (weightedPoint - w*o)`. This function returns a Point4d where first 3 elements are the original
414
+ * point `p` if `weightedPoint` is the transformed point (`Tp = weightedPoint`) and the last element is `w`.
415
+ * * Return as a new point or in the optional `result`.
416
+ * * Returns `undefined` if the `matrix` part if this Transform is singular.
330
417
  */
331
418
  multiplyInversePoint4d(weightedPoint, result) {
332
419
  const w = weightedPoint.w;
333
420
  return this._matrix.multiplyInverseXYZW(weightedPoint.x - w * this.origin.x, weightedPoint.y - w * this.origin.y, weightedPoint.z - w * this.origin.z, w, result);
334
421
  }
335
- /** Return product of the transform's inverse times a point (point given as x,y,z) */
422
+ /**
423
+ * If for a point `p = (x,y,z)` we have `Tp = M*p + o = point` (where `point` is the transformed point), then
424
+ * `p = MInverse * (point - o)`. This function returns the original point `p` if `point` is the transformed
425
+ * point (`Tp = point`).
426
+ * * Return as a new point or in the optional `result`.
427
+ * * Returns `undefined` if the `matrix` part if this Transform is singular.
428
+ */
336
429
  multiplyInverseXYZ(x, y, z, result) {
337
430
  return this._matrix.multiplyInverseXYZAsPoint3d(x - this._origin.x, y - this._origin.y, z - this._origin.z, result);
338
431
  }
@@ -358,8 +451,8 @@ class Transform {
358
451
  return result;
359
452
  }
360
453
  /**
361
- * * for each point in source: multiply transformInverse * point in place in the point.
362
- * * return false if not invertible.
454
+ * * For each point in source: multiply transformInverse * point in place in the point.
455
+ * * Return false if not invertible.
363
456
  */
364
457
  multiplyInversePoint3dArrayInPlace(source) {
365
458
  if (!this._matrix.computeCachedInverse(true))
@@ -403,9 +496,9 @@ class Transform {
403
496
  return numSource;
404
497
  }
405
498
  /**
406
- * * for each point: multiply transform * point
407
- * * if result is given, resize to match source and replace each corresponding pi
408
- * * if result is not given, return a new array.
499
+ * * For each point: multiply transform * point
500
+ * * If result is given, resize to match source and replace each corresponding pi
501
+ * * If result is not given, return a new array.
409
502
  */
410
503
  multiplyPoint2dArray(source, result) {
411
504
  if (result) {
@@ -420,9 +513,9 @@ class Transform {
420
513
  return result;
421
514
  }
422
515
  /**
423
- * * for each point: multiply transform * point
424
- * * if result is given, resize to match source and replace each corresponding pi
425
- * * if result is not given, return a new array.
516
+ * * For each point: multiply transform * point
517
+ * * If result is given, resize to match source and replace each corresponding pi
518
+ * * If result is not given, return a new array.
426
519
  */
427
520
  multiplyPoint3dArray(source, result) {
428
521
  if (result) {
@@ -436,30 +529,30 @@ class Transform {
436
529
  result.push(Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, p));
437
530
  return result;
438
531
  }
439
- /** Multiply the vector by the Matrix3d part of the transform.
440
- *
441
- * * The transform's origin is not used.
442
- * * Return as new or result by usual optional result convention
532
+ /**
533
+ * Multiply the vector by the Matrix3d part of the transform.
534
+ * * The transform's origin is not used.
535
+ * * Return as new or result by usual optional result convention
443
536
  */
444
537
  multiplyVector(vector, result) {
445
538
  return this._matrix.multiplyVector(vector, result);
446
539
  }
447
- /** Multiply the vector in place by the Matrix3d part of the transform.
448
- *
449
- * * The transform's origin is not used.
450
- */
540
+ /**
541
+ * Multiply the vector in place by the Matrix3d part of the transform.
542
+ * * The transform's origin is not used.
543
+ */
451
544
  multiplyVectorInPlace(vector) {
452
545
  this._matrix.multiplyVectorInPlace(vector);
453
546
  }
454
- /** Multiply the vector (x,y,z) by the Matrix3d part of the transform.
455
- *
456
- * * The transform's origin is not used.
457
- * * Return as new or result by usual optional result convention
547
+ /**
548
+ * Multiply the vector (x,y,z) by the Matrix3d part of the transform.
549
+ * * The transform's origin is not used.
550
+ * * Return as new or result by usual optional result convention
458
551
  */
459
552
  multiplyVectorXYZ(x, y, z, result) {
460
553
  return this._matrix.multiplyXYZ(x, y, z, result);
461
554
  }
462
- /** multiply this Transform times other Transform.
555
+ /** Multiply this Transform times other Transform.
463
556
  * ```
464
557
  * equation
465
558
  * \begin{matrix}
@@ -478,7 +571,7 @@ class Transform {
478
571
  return result;
479
572
  }
480
573
  /**
481
- * multiply transformA * transformB, store to calling instance.
574
+ * Multiply transformA * transformB, store to calling instance.
482
575
  * @param transformA left operand
483
576
  * @param transformB right operand
484
577
  */
@@ -491,7 +584,8 @@ class Transform {
491
584
  }
492
585
  // [Q A][R 0] = [QR A]
493
586
  // [0 1][0 1] [0 1]
494
- /** multiply this Transform times other Matrix3d, with other considered to be a Transform with 0 translation.
587
+ /**
588
+ * Multiply this Transform times other Matrix3d, with other considered to be a Transform with 0 translation.
495
589
  * ```
496
590
  * equation
497
591
  * \begin{matrix}
@@ -514,7 +608,7 @@ class Transform {
514
608
  * Return the range of the transformed corners.
515
609
  * * The 8 corners are transformed individually.
516
610
  * * Note that if there is anything other than translation and principal axis scaling in the transform, the volume of the range rotation will increase.
517
- * * Hence to get a "tight" range on rotated geometry, a range computation must be made on the rotated geometry itself.
611
+ * * Hence to get a "tight" range on rotated geometry, a range computation must be made on the rotated geometry itself.
518
612
  */
519
613
  multiplyRange(range, result) {
520
614
  if (range.isNull)
@@ -539,15 +633,22 @@ class Transform {
539
633
  }
540
634
  /**
541
635
  * * Return a Transform which is the inverse of this transform.
542
- * * Return undefined if this Transform's matrix is singular.
636
+ * @param result optional pre-allocated result
637
+ * @return the inverse Transform, or undefined if the matrix is singular
543
638
  */
544
- inverse() {
545
- const matrixInverse = this._matrix.inverse();
639
+ inverse(result) {
640
+ const matrixInverse = this._matrix.inverse(result ? result._matrix : undefined);
546
641
  if (!matrixInverse)
547
642
  return undefined;
643
+ if (result) {
644
+ // result._matrix is already defined
645
+ matrixInverse.multiplyXYZ(-this._origin.x, -this._origin.y, -this._origin.z, result._origin);
646
+ return result;
647
+ }
548
648
  return Transform.createRefs(matrixInverse.multiplyXYZ(-this._origin.x, -this._origin.y, -this._origin.z), matrixInverse);
549
649
  }
550
- /** Initialize transforms that map each direction of a box (axis aligned) to `[0,1]`.
650
+ /**
651
+ * Initialize transforms that map each direction of a box (axis aligned) to `[0,1]`.
551
652
  * * The corner coordinates do _not_ need to be in order in any of the x,y,z directions.
552
653
  * * The npcToGlobalTransform (if supplied) maps 000 to the point named point000.
553
654
  * * The npcToGlobalTransform (if supplied) maps 11 to the point named point000.