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