@itwin/core-geometry 4.0.0-dev.51 → 4.0.0-dev.52
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/geometry3d/Matrix3d.d.ts +9 -5
- package/lib/cjs/geometry3d/Matrix3d.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Matrix3d.js +9 -6
- package/lib/cjs/geometry3d/Matrix3d.js.map +1 -1
- package/lib/cjs/geometry3d/Transform.d.ts +112 -75
- package/lib/cjs/geometry3d/Transform.d.ts.map +1 -1
- package/lib/cjs/geometry3d/Transform.js +159 -119
- package/lib/cjs/geometry3d/Transform.js.map +1 -1
- package/lib/esm/geometry3d/Matrix3d.d.ts +9 -5
- package/lib/esm/geometry3d/Matrix3d.d.ts.map +1 -1
- package/lib/esm/geometry3d/Matrix3d.js +9 -6
- package/lib/esm/geometry3d/Matrix3d.js.map +1 -1
- package/lib/esm/geometry3d/Transform.d.ts +112 -75
- package/lib/esm/geometry3d/Transform.d.ts.map +1 -1
- package/lib/esm/geometry3d/Transform.js +159 -119
- package/lib/esm/geometry3d/Transform.js.map +1 -1
- package/package.json +3 -3
|
@@ -20,11 +20,15 @@ const Range_1 = require("./Range");
|
|
|
20
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
21
|
* In other words, `T` is a combination of two operations on `p`: the action of matrix multiplication, followed by a
|
|
22
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
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* global axes centered at the global origin, to a new set of axes specified by matrix M columns centered at `o`.
|
|
24
|
+
* * Beware that for common transformations (e.g. scale about point, rotate around an axis) the `fixed point` that
|
|
25
|
+
* is used when describing the transform is NOT the `origin` stored in the transform. Setup methods (e.g
|
|
26
|
+
* createFixedPointAndMatrix, createScaleAboutPoint) take care of determining the appropriate origin coordinates.
|
|
27
|
+
* * If `T` is a translation, no point is fixed by `T`.
|
|
28
|
+
* * If `T` is the identity, all points are fixed by `T`.
|
|
29
|
+
* * If `T` is a scale about a point, one point is fixed by `T`.
|
|
30
|
+
* * If `T` is a rotation about an axis, a line is fixed by `T`.
|
|
31
|
+
* * If `T` is a projection to the plane, a plane is fixed by `T`.
|
|
28
32
|
* @public
|
|
29
33
|
*/
|
|
30
34
|
class Transform {
|
|
@@ -317,22 +321,32 @@ class Transform {
|
|
|
317
321
|
const origin = Matrix3d_1.Matrix3d.xyzMinusMatrixTimesXYZ(fixedPoint, matrix, fixedPoint);
|
|
318
322
|
return Transform.createRefs(origin, matrix, result);
|
|
319
323
|
}
|
|
320
|
-
/**
|
|
324
|
+
/**
|
|
325
|
+
* Transform the input 2d point (using `Tp = M*p + o`).
|
|
326
|
+
* Return as a new point or in the pre-allocated result (if result is given).
|
|
327
|
+
*/
|
|
321
328
|
multiplyPoint2d(point, result) {
|
|
322
|
-
// Tx = Mx + o so we return Mx + o
|
|
323
329
|
return Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix, point, result);
|
|
324
330
|
}
|
|
325
|
-
/**
|
|
331
|
+
/**
|
|
332
|
+
* Transform the input 3d point (using `Tp = M*p + o`).
|
|
333
|
+
* Return as a new point or in the pre-allocated result (if result is given).
|
|
334
|
+
*/
|
|
326
335
|
multiplyPoint3d(point, result) {
|
|
327
336
|
// Tx = Mx + o so we return Mx + o
|
|
328
337
|
return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, point, result);
|
|
329
338
|
}
|
|
330
|
-
/**
|
|
339
|
+
/**
|
|
340
|
+
* Transform the input 3d point in place (using `Tp = M*p + o`).
|
|
341
|
+
* Return as a new point or in the pre-allocated result (if result is given).
|
|
342
|
+
*/
|
|
331
343
|
multiplyXYAndZInPlace(point) {
|
|
332
|
-
// Tx = Mx + o so we override x by Mx + o
|
|
333
344
|
return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZInPlace(this._origin, this._matrix, point);
|
|
334
345
|
}
|
|
335
|
-
/**
|
|
346
|
+
/**
|
|
347
|
+
* Transform the input 3d point (using `Tp = M*p + o`).
|
|
348
|
+
* Return as a new point or in the pre-allocated result (if result is given).
|
|
349
|
+
*/
|
|
336
350
|
multiplyXYZ(x, y, z = 0, result) {
|
|
337
351
|
// Tx = Mx + o so we return Mx + o
|
|
338
352
|
return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesCoordinates(this._origin, this._matrix, x, y, z, result);
|
|
@@ -378,7 +392,7 @@ class Transform {
|
|
|
378
392
|
return Matrix3d_1.Matrix3d.xyzPlusMatrixTimesCoordinatesToFloat64Array(this._origin, this._matrix, x, y, z, result);
|
|
379
393
|
}
|
|
380
394
|
/**
|
|
381
|
-
* Treat the 3x3 matrix and origin as upper 3x4 part of a 4x4 matrix, with 0001 as the final row. Now multiply
|
|
395
|
+
* Treat the 3x3 `matrix` and `origin` as upper 3x4 part of a 4x4 matrix, with 0001 as the final row. Now multiply
|
|
382
396
|
* the transposed of this 4x4 matrix by Point4d given as xyzw. Return as a new point4d (`M*p` as first 3 elements
|
|
383
397
|
* and `o*p + w` as last element where `p = (x,y,z)`) or in the pre-allocated result (if result is given).
|
|
384
398
|
*/
|
|
@@ -387,13 +401,13 @@ class Transform {
|
|
|
387
401
|
const origin = this._origin;
|
|
388
402
|
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);
|
|
389
403
|
}
|
|
390
|
-
/** For each point in the array, replace point by the transformed point (
|
|
404
|
+
/** For each point in the array, replace point by the transformed point (using `Tp = M*p + o`) */
|
|
391
405
|
multiplyPoint3dArrayInPlace(points) {
|
|
392
406
|
let point;
|
|
393
407
|
for (point of points)
|
|
394
408
|
Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, point, point);
|
|
395
409
|
}
|
|
396
|
-
/** For each point in the 2d array, replace point by the transformed point (
|
|
410
|
+
/** For each point in the 2d array, replace point by the transformed point (using `Tp = M*p + o`) */
|
|
397
411
|
multiplyPoint3dArrayArrayInPlace(chains) {
|
|
398
412
|
for (const chain of chains)
|
|
399
413
|
this.multiplyPoint3dArrayInPlace(chain);
|
|
@@ -430,58 +444,23 @@ class Transform {
|
|
|
430
444
|
return this._matrix.multiplyInverseXYZAsPoint3d(x - this._origin.x, y - this._origin.y, z - this._origin.z, result);
|
|
431
445
|
}
|
|
432
446
|
/**
|
|
433
|
-
* *
|
|
434
|
-
*
|
|
435
|
-
* * if result is not given, return a new array.
|
|
436
|
-
*/
|
|
437
|
-
multiplyInversePoint3dArray(source, result) {
|
|
438
|
-
if (!this._matrix.computeCachedInverse(true))
|
|
439
|
-
return undefined;
|
|
440
|
-
const originX = this.origin.x;
|
|
441
|
-
const originY = this.origin.y;
|
|
442
|
-
const originZ = this.origin.z;
|
|
443
|
-
if (result) {
|
|
444
|
-
const n = Transform.matchArrayLengths(source, result, Point3dVector3d_1.Point3d.createZero);
|
|
445
|
-
for (let i = 0; i < n; i++)
|
|
446
|
-
this._matrix.multiplyInverseXYZAsPoint3d(source[i].x - originX, source[i].y - originY, source[i].z - originZ, result[i]);
|
|
447
|
-
}
|
|
448
|
-
result = [];
|
|
449
|
-
for (const p of source)
|
|
450
|
-
result.push(this._matrix.multiplyInverseXYZAsPoint3d(p.x - originX, p.y - originY, p.z - originZ));
|
|
451
|
-
return result;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* * For each point in source: multiply transformInverse * point in place in the point.
|
|
455
|
-
* * Return false if not invertible.
|
|
456
|
-
*/
|
|
457
|
-
multiplyInversePoint3dArrayInPlace(source) {
|
|
458
|
-
if (!this._matrix.computeCachedInverse(true))
|
|
459
|
-
return false;
|
|
460
|
-
const originX = this.origin.x;
|
|
461
|
-
const originY = this.origin.y;
|
|
462
|
-
const originZ = this.origin.z;
|
|
463
|
-
const n = source.length;
|
|
464
|
-
for (let i = 0; i < n; i++)
|
|
465
|
-
this._matrix.multiplyInverseXYZAsPoint3d(source[i].x - originX, source[i].y - originY, source[i].z - originZ, source[i]);
|
|
466
|
-
return true;
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* * Compute (if needed) the inverse of the matrix part, thereby ensuring inverse operations can complete.
|
|
470
|
-
* * Return true if matrix inverse completes.
|
|
447
|
+
* * Compute (if needed) the inverse of the `matrix` part of the Transform, thereby ensuring inverse
|
|
448
|
+
* operations can complete.
|
|
471
449
|
* @param useCached If true, accept prior cached inverse if available.
|
|
450
|
+
* @returns `true` if matrix inverse completes, `false` otherwise.
|
|
472
451
|
*/
|
|
473
452
|
computeCachedInverse(useCached = true) {
|
|
474
453
|
return this._matrix.computeCachedInverse(useCached);
|
|
475
454
|
}
|
|
476
455
|
/**
|
|
477
|
-
*
|
|
478
|
-
* * If destination has
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
* @param
|
|
456
|
+
* Match the length of destination array with the length of source array
|
|
457
|
+
* * If destination has more elements than source, remove the extra elements.
|
|
458
|
+
* * If destination has fewer elements than source, use `constructionFunction` to create new elements.
|
|
459
|
+
* *
|
|
460
|
+
* @param source the source array
|
|
461
|
+
* @param dest the destination array
|
|
462
|
+
* @param constructionFunction function to call to create new elements.
|
|
482
463
|
*/
|
|
483
|
-
// modify destination so it has non-null points for the same length as the source.
|
|
484
|
-
// (ASSUME existing elements of dest are non-null, and that parameters are given as either Point2d or Point3d arrays)
|
|
485
464
|
static matchArrayLengths(source, dest, constructionFunction) {
|
|
486
465
|
const numSource = source.length;
|
|
487
466
|
const numDest = dest.length;
|
|
@@ -496,72 +475,125 @@ class Transform {
|
|
|
496
475
|
return numSource;
|
|
497
476
|
}
|
|
498
477
|
/**
|
|
499
|
-
*
|
|
500
|
-
* *
|
|
501
|
-
*
|
|
478
|
+
* If for each point `p` we have `Tp = M*p + o = point` (where `point` is the transformed point), then
|
|
479
|
+
* `p = MInverse * (point - o)`. This function returns the array of original points `p[]` if `points`
|
|
480
|
+
* is the array of transformed point (`Tp = point` for each `p` and `point`).
|
|
481
|
+
* * If `results` is given, resize it to match the input `points` array and update it with original points `p[]`.
|
|
482
|
+
* * If `results` is not given, return a new array.
|
|
483
|
+
* * Returns `undefined` if the `matrix` part if this Transform is singular.
|
|
502
484
|
*/
|
|
503
|
-
|
|
485
|
+
multiplyInversePoint3dArray(points, results) {
|
|
486
|
+
if (!this._matrix.computeCachedInverse(true))
|
|
487
|
+
return undefined;
|
|
488
|
+
const originX = this.origin.x;
|
|
489
|
+
const originY = this.origin.y;
|
|
490
|
+
const originZ = this.origin.z;
|
|
491
|
+
if (results) {
|
|
492
|
+
const n = Transform.matchArrayLengths(points, results, Point3dVector3d_1.Point3d.createZero);
|
|
493
|
+
for (let i = 0; i < n; i++)
|
|
494
|
+
this._matrix.multiplyInverseXYZAsPoint3d(points[i].x - originX, points[i].y - originY, points[i].z - originZ, results[i]);
|
|
495
|
+
}
|
|
496
|
+
results = [];
|
|
497
|
+
for (const point of points)
|
|
498
|
+
results.push(this._matrix.multiplyInverseXYZAsPoint3d(point.x - originX, point.y - originY, point.z - originZ));
|
|
499
|
+
return results;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* If for each point `p` we have `Tp = M*p + o = point` (where `point` is the transformed point), then
|
|
503
|
+
* `p = MInverse * (point - o)`. This function calculates the array of original points `p[]` if `points`
|
|
504
|
+
* is the array of transformed point (`Tp = point` for each `p` and `point`) and replaces `points`
|
|
505
|
+
* with the array of original points.
|
|
506
|
+
* * Returns `true` if the `matrix` part if this Transform is invertible and `false if singular.
|
|
507
|
+
*/
|
|
508
|
+
multiplyInversePoint3dArrayInPlace(points) {
|
|
509
|
+
if (!this._matrix.computeCachedInverse(true))
|
|
510
|
+
return false;
|
|
511
|
+
for (const point of points)
|
|
512
|
+
this._matrix.multiplyInverseXYZAsPoint3d(point.x - this.origin.x, point.y - this.origin.y, point.z - this.origin.z, point);
|
|
513
|
+
return true;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Transform the input 2d point array (using `Tp = M*p + o`).
|
|
517
|
+
* * If `result` is given, resize it to match the input `points` array and update it with transformed points.
|
|
518
|
+
* * If `result` is not given, return a new array.
|
|
519
|
+
*/
|
|
520
|
+
multiplyPoint2dArray(points, result) {
|
|
504
521
|
if (result) {
|
|
505
|
-
const n = Transform.matchArrayLengths(
|
|
522
|
+
const n = Transform.matchArrayLengths(points, result, Point2dVector2d_1.Point2d.createZero);
|
|
506
523
|
for (let i = 0; i < n; i++)
|
|
507
|
-
Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix,
|
|
524
|
+
Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix, points[i], result[i]);
|
|
508
525
|
return result;
|
|
509
526
|
}
|
|
510
527
|
result = [];
|
|
511
|
-
for (const p of
|
|
528
|
+
for (const p of points)
|
|
512
529
|
result.push(Matrix3d_1.Matrix3d.xyPlusMatrixTimesXY(this._origin, this._matrix, p));
|
|
513
530
|
return result;
|
|
514
531
|
}
|
|
515
532
|
/**
|
|
516
|
-
*
|
|
517
|
-
* * If result is given, resize to match
|
|
518
|
-
* * If result is not given, return a new array.
|
|
533
|
+
* Transform the input 3d point array (using `Tp = M*p + o`).
|
|
534
|
+
* * If `result` is given, resize it to match the input `points` array and update it with transformed points.
|
|
535
|
+
* * If `result` is not given, return a new array.
|
|
519
536
|
*/
|
|
520
|
-
multiplyPoint3dArray(
|
|
537
|
+
multiplyPoint3dArray(points, result) {
|
|
521
538
|
if (result) {
|
|
522
|
-
const n = Transform.matchArrayLengths(
|
|
539
|
+
const n = Transform.matchArrayLengths(points, result, Point3dVector3d_1.Point3d.createZero);
|
|
523
540
|
for (let i = 0; i < n; i++)
|
|
524
|
-
Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix,
|
|
541
|
+
Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, points[i], result[i]);
|
|
525
542
|
return result;
|
|
526
543
|
}
|
|
527
544
|
result = [];
|
|
528
|
-
for (const p of
|
|
545
|
+
for (const p of points)
|
|
529
546
|
result.push(Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(this._origin, this._matrix, p));
|
|
530
547
|
return result;
|
|
531
548
|
}
|
|
532
549
|
/**
|
|
533
|
-
* Multiply the vector by the
|
|
534
|
-
* * The
|
|
535
|
-
* *
|
|
550
|
+
* Multiply the vector by the `matrix` part of the Transform.
|
|
551
|
+
* * The `origin` part of Transform is not used.
|
|
552
|
+
* * If `result` is given, update it with the multiplication. Otherwise, create a new Vector3d.
|
|
536
553
|
*/
|
|
537
554
|
multiplyVector(vector, result) {
|
|
538
555
|
return this._matrix.multiplyVector(vector, result);
|
|
539
556
|
}
|
|
540
557
|
/**
|
|
541
|
-
* Multiply the vector
|
|
542
|
-
* * The
|
|
558
|
+
* Multiply the vector by the `matrix` part of the Transform in place.
|
|
559
|
+
* * The `origin` part of Transform is not used.
|
|
543
560
|
*/
|
|
544
561
|
multiplyVectorInPlace(vector) {
|
|
545
562
|
this._matrix.multiplyVectorInPlace(vector);
|
|
546
563
|
}
|
|
547
564
|
/**
|
|
548
|
-
* Multiply the vector (x,y,z) by the
|
|
549
|
-
* * The
|
|
550
|
-
* *
|
|
565
|
+
* Multiply the vector (x,y,z) by the `matrix` part of the Transform.
|
|
566
|
+
* * The `origin` part of Transform is not used.
|
|
567
|
+
* * If `result` is given, update it with the multiplication. Otherwise, create a new Vector3d.
|
|
551
568
|
*/
|
|
552
569
|
multiplyVectorXYZ(x, y, z, result) {
|
|
553
570
|
return this._matrix.multiplyXYZ(x, y, z, result);
|
|
554
571
|
}
|
|
555
|
-
/**
|
|
572
|
+
/**
|
|
573
|
+
* Calculate `transformA * transformB` and store it into the calling instance (`this`).
|
|
574
|
+
* * **Note:** If `transformA = [A a]` and `transformB = [B b]` then `transformA * transformB` is defined as
|
|
575
|
+
* `[A*B Ab+a]`. See `multiplyTransformTransform` doc for math details.
|
|
576
|
+
* @param transformA first operand
|
|
577
|
+
* @param transformB second operand
|
|
578
|
+
*/
|
|
579
|
+
setMultiplyTransformTransform(transformA, transformB) {
|
|
580
|
+
Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(transformA._origin, transformA._matrix, transformB._origin, this._origin);
|
|
581
|
+
transformA._matrix.multiplyMatrixMatrix(transformB._matrix, this._matrix);
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Multiply `this` Transform times `other` Transform.
|
|
585
|
+
* **Note:** If `this = [A a]` and `other = [B b]` then `this * other` is defined as [A*B Ab+a].
|
|
586
|
+
* That's because we create a 4x4 matrix for each Transform with the 3x3 `matrix` and `origin`
|
|
587
|
+
* as upper 3x4 part of a 4x4 matrix and 0001 as the final row. Then we multiply those two 4x4 matrixes:
|
|
556
588
|
* ```
|
|
557
589
|
* equation
|
|
558
590
|
* \begin{matrix}
|
|
559
|
-
* \text{`this`
|
|
560
|
-
* \text{`other`
|
|
591
|
+
* \text{`this` Transform with `matrix` part }\bold{A}\text{ and `origin` part }\bold{a} & \blockTransform{A}{a}\\
|
|
592
|
+
* \text{`other` Transform with `matrix` part }\bold{B}\text{ and `origin` part }\bold{b} & \blockTransform{B}{b} \\
|
|
561
593
|
* \text{product}& \blockTransform{A}{a}\blockTransform{B}{b}=\blockTransform{AB}{Ab + a}
|
|
562
594
|
* \end{matrix}
|
|
563
595
|
* ```
|
|
564
|
-
* @param other
|
|
596
|
+
* @param other the 'other` Transform to be multiplied to `this` Transform.
|
|
565
597
|
* @param result optional preallocated result to reuse.
|
|
566
598
|
*/
|
|
567
599
|
multiplyTransformTransform(other, result) {
|
|
@@ -571,30 +603,20 @@ class Transform {
|
|
|
571
603
|
return result;
|
|
572
604
|
}
|
|
573
605
|
/**
|
|
574
|
-
* Multiply
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (Transform._scratchPoint === undefined)
|
|
580
|
-
Transform._scratchPoint = Point3dVector3d_1.Point3d.create();
|
|
581
|
-
Matrix3d_1.Matrix3d.xyzPlusMatrixTimesXYZ(transformA._origin, transformA._matrix, transformB._origin, Transform._scratchPoint);
|
|
582
|
-
this._origin.setFrom(Transform._scratchPoint);
|
|
583
|
-
transformA._matrix.multiplyMatrixMatrix(transformB._matrix, this._matrix);
|
|
584
|
-
}
|
|
585
|
-
// [Q A][R 0] = [QR A]
|
|
586
|
-
// [0 1][0 1] [0 1]
|
|
587
|
-
/**
|
|
588
|
-
* Multiply this Transform times other Matrix3d, with other considered to be a Transform with 0 translation.
|
|
606
|
+
* Multiply `this` Transform times `other` Matrix3d (considered to be a Transform with 0 `origin`).
|
|
607
|
+
* **Note:** If `this = [A a]`, then we promote `other` matrix to be a Transform [B 0].
|
|
608
|
+
* Then `this * other` is defined as [A*B a]. That's because we create a 4x4 matrix for each Transform
|
|
609
|
+
* with the 3x3 `matrix` and `origin` as upper 3x4 part of a 4x4 matrix and 0001 as the final row. Then we
|
|
610
|
+
* multiply those two 4x4 matrixes:
|
|
589
611
|
* ```
|
|
590
612
|
* equation
|
|
591
613
|
* \begin{matrix}
|
|
592
|
-
* \text{`this`
|
|
593
|
-
* \text{`other` matrix }\bold{B}\text{ promoted to block
|
|
614
|
+
* \text{`this` Transform with `matrix` part }\bold{A}\text{ and `origin` part }\bold{a} & \blockTransform{A}{a}\\
|
|
615
|
+
* \text{`other` matrix }\bold{B}\text{ promoted to block Transform} & \blockTransform{B}{0} \\
|
|
594
616
|
* \text{product}& \blockTransform{A}{a}\blockTransform{B}{0}=\blockTransform{AB}{a}
|
|
595
617
|
* \end{matrix}
|
|
596
618
|
* ```
|
|
597
|
-
* @param other
|
|
619
|
+
* @param other the `other` Matrix3d to be multiplied to `this` Transform.
|
|
598
620
|
* @param result optional preallocated result to reuse.
|
|
599
621
|
*/
|
|
600
622
|
multiplyTransformMatrix3d(other, result) {
|
|
@@ -605,15 +627,17 @@ class Transform {
|
|
|
605
627
|
return result;
|
|
606
628
|
}
|
|
607
629
|
/**
|
|
608
|
-
* Return the
|
|
630
|
+
* Return the Range of the transformed corners.
|
|
609
631
|
* * The 8 corners are transformed individually.
|
|
610
|
-
* * Note
|
|
611
|
-
*
|
|
632
|
+
* * **Note:** Suppose you have a geometry, a range box around that geometry, and your Transform is a rotation.
|
|
633
|
+
* If you rotate the range box and recompute a new range box around the rotated range box, then the new range
|
|
634
|
+
* box will have a larger volume than the original range box. However, if you rotate the geometry itself and
|
|
635
|
+
* then recompute the range box, it will be a tighter range box around the rotated geometry. `multiplyRange`
|
|
636
|
+
* function creates the larger range box because it only has access to the range box and the geometry itself.
|
|
612
637
|
*/
|
|
613
638
|
multiplyRange(range, result) {
|
|
614
639
|
if (range.isNull)
|
|
615
640
|
return range.clone(result);
|
|
616
|
-
// snag current values to allow aliasing.
|
|
617
641
|
const lowX = range.low.x;
|
|
618
642
|
const lowY = range.low.y;
|
|
619
643
|
const lowZ = range.low.z;
|
|
@@ -632,9 +656,9 @@ class Transform {
|
|
|
632
656
|
return result;
|
|
633
657
|
}
|
|
634
658
|
/**
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
659
|
+
* Return a Transform which is the inverse of `this` Transform.
|
|
660
|
+
* * If `transform = [M o]` then `transformInverse = [MInverse MInverse*-o]`
|
|
661
|
+
* * Return `undefined` if this Transform's matrix is singular.
|
|
638
662
|
*/
|
|
639
663
|
inverse(result) {
|
|
640
664
|
const matrixInverse = this._matrix.inverse(result ? result._matrix : undefined);
|
|
@@ -648,15 +672,15 @@ class Transform {
|
|
|
648
672
|
return Transform.createRefs(matrixInverse.multiplyXYZ(-this._origin.x, -this._origin.y, -this._origin.z), matrixInverse);
|
|
649
673
|
}
|
|
650
674
|
/**
|
|
651
|
-
* Initialize
|
|
652
|
-
*
|
|
653
|
-
*
|
|
654
|
-
*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
* @param
|
|
658
|
-
*
|
|
659
|
-
*
|
|
675
|
+
* Initialize 2 Transforms: First Transform maps a box (axis aligned) specified by `min` and `max` to
|
|
676
|
+
* the unit box specified by 000 and 111 and inverse of it. Second Transform is the reverse of first.
|
|
677
|
+
* @param min the min corner of the box
|
|
678
|
+
* @param max the max corner of the box
|
|
679
|
+
* @param npcToGlobal maps global (the unit box specified by 000 and 111) to NPC (a box specified by `min`
|
|
680
|
+
* and `max`). Object created by caller, re-initialized here.
|
|
681
|
+
* @param globalToNpc maps NPC (a box specified by `min` and `max`) to global (the unit box specified by
|
|
682
|
+
* 000 and 111). Object created by caller, re-initialized here.
|
|
683
|
+
* * NPC stands for `Normalized Projection Coordinate`
|
|
660
684
|
*/
|
|
661
685
|
static initFromRange(min, max, npcToGlobal, globalToNpc) {
|
|
662
686
|
const diag = max.minus(min);
|
|
@@ -667,10 +691,26 @@ class Transform {
|
|
|
667
691
|
if (diag.z === 0.0)
|
|
668
692
|
diag.z = 1.0;
|
|
669
693
|
const rMatrix = new Matrix3d_1.Matrix3d();
|
|
694
|
+
/**
|
|
695
|
+
* [diag.x 0 0 min.x]
|
|
696
|
+
* npcToGlobal = [ 0 diag.y 0 min.y]
|
|
697
|
+
* [ 0 0 diag.y min.z]
|
|
698
|
+
*
|
|
699
|
+
* npcToGlobal * 0 = min
|
|
700
|
+
* npcToGlobal * 1 = diag + min = max
|
|
701
|
+
*/
|
|
670
702
|
if (npcToGlobal) {
|
|
671
703
|
Matrix3d_1.Matrix3d.createScale(diag.x, diag.y, diag.z, rMatrix);
|
|
672
704
|
Transform.createOriginAndMatrix(min, rMatrix, npcToGlobal);
|
|
673
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* [1/diag.x 0 0 -min.x/diag.x]
|
|
708
|
+
* globalToNpc = [ 0 1/diag.y 0 -min.y/diag.y]
|
|
709
|
+
* [ 0 0 1/diag.y -min.z/diag.z]
|
|
710
|
+
*
|
|
711
|
+
* globalToNpc * min = min/diag - min/diag = 0
|
|
712
|
+
* globalToNpc * max = max/diag - min/diag = diag/diag = 1
|
|
713
|
+
*/
|
|
674
714
|
if (globalToNpc) {
|
|
675
715
|
const origin = new Point3dVector3d_1.Point3d(-min.x / diag.x, -min.y / diag.y, -min.z / diag.z);
|
|
676
716
|
Matrix3d_1.Matrix3d.createScale(1.0 / diag.x, 1.0 / diag.y, 1.0 / diag.z, rMatrix);
|