@itwin/ecschema-rpcinterface-tests 4.0.0-dev.39 → 4.0.0-dev.40

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.
@@ -1 +1 @@
1
- {"version":3,"file":"_d48c.bundled-tests.js","mappings":";;;;;;;;AAAA","sources":["file:///ignored|D:\\vsts_a\\10\\s\\common\\temp\\node_modules\\.pnpm\\@loaders.gl+worker-utils@3.3.1\\node_modules\\@loaders.gl\\worker-utils\\dist\\esm\\lib\\library-utils|../node/require-utils.node"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"_d48c.bundled-tests.js","mappings":";;;;;;;;AAAA","sources":["file:///ignored|D:\\vsts_b\\57\\s\\common\\temp\\node_modules\\.pnpm\\@loaders.gl+worker-utils@3.3.1\\node_modules\\@loaders.gl\\worker-utils\\dist\\esm\\lib\\library-utils|../node/require-utils.node"],"names":[],"sourceRoot":""}
@@ -172775,8 +172775,8 @@ class Geometry {
172775
172775
  return (Math.abs(a) <= Geometry.smallMetricDistanceSquared) ? undefined : 1.0 / a;
172776
172776
  }
172777
172777
  /**
172778
- * Boolean test for metric coordinate near-equality. If tolerance is not passed, `Geometry.smallMetricDistance`
172779
- * is used as tolerance.
172778
+ * Boolean test for metric coordinate near-equality (i.e., if x and y are almost equal). If tolerance is not passed,
172779
+ * `Geometry.smallMetricDistance` is used as tolerance.
172780
172780
  */
172781
172781
  static isSameCoordinate(x, y, tol) {
172782
172782
  if (tol)
@@ -172974,7 +172974,8 @@ class Geometry {
172974
172974
  q = c;
172975
172975
  return q;
172976
172976
  }
172977
- /** Examine the value (particularly sign) of x.
172977
+ /**
172978
+ * Examine the value (particularly sign) of x.
172978
172979
  * * If x is negative, return outNegative.
172979
172980
  * * If x is true zero, return outZero
172980
172981
  * * If x is positive, return outPositive
@@ -173215,7 +173216,7 @@ class Geometry {
173215
173216
  /** return 0 if the value is undefined, 1 if defined. */
173216
173217
  static defined01(value) { return value === undefined ? 0 : 1; }
173217
173218
  /**
173218
- * Return `numerator` over `denominator` or `undefined`.
173219
+ * Return `numerator` divided by `denominator`, or `undefined`.
173219
173220
  * @param numerator the numerator
173220
173221
  * @param denominator the denominator
173221
173222
  * @returns return `numerator/denominator` but if the ratio would exceed `Geometry.largeFractionResult`,
@@ -173227,7 +173228,7 @@ class Geometry {
173227
173228
  return undefined;
173228
173229
  }
173229
173230
  /**
173230
- * Return `numerator` over `denominator`.
173231
+ * Return `numerator` divided by `denominator`.
173231
173232
  * @param numerator the numerator
173232
173233
  * @param denominator the denominator
173233
173234
  * @returns return `numerator/denominator` but if the ratio would exceed `Geometry.largeFractionResult`,
@@ -173240,7 +173241,7 @@ class Geometry {
173240
173241
  return defaultResult;
173241
173242
  }
173242
173243
  /**
173243
- * Return `numerator` over `denominator` (with a given `largestResult`) or `undefined`.
173244
+ * Return `numerator` divided by `denominator` (with a given `largestResult`), or `undefined`.
173244
173245
  * @param numerator the numerator
173245
173246
  * @param denominator the denominator
173246
173247
  * @param largestResult the ratio threshold.
@@ -208308,7 +208309,7 @@ __webpack_require__.r(__webpack_exports__);
208308
208309
 
208309
208310
 
208310
208311
  /* eslint-disable @itwin/prefer-get */
208311
- // cSpell:words XXYZ YXYZ ZXYZ SaeedTorabi arctan newcommand
208312
+ // cSpell:words XXYZ YXYZ ZXYZ SaeedTorabi arctan newcommand diagonalization
208312
208313
  /**
208313
208314
  * PackedMatrix3dOps contains static methods for matrix operations where the matrix is a Float64Array.
208314
208315
  * * The Float64Array contains the matrix entries in row-major order
@@ -208961,7 +208962,14 @@ class Matrix3d {
208961
208962
  }
208962
208963
  return Matrix3d.createIdentity(result);
208963
208964
  }
208964
- /** Return the matrix for rotation of `angle` around desired `axis` */
208965
+ /**
208966
+ * Return the matrix for rotation of `angle` around desired `axis`
208967
+ * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/CubeRotationAroundAnAxis
208968
+ * @param axis the axis of rotation
208969
+ * @param angle the angle of rotation
208970
+ * @param result caller-allocated matrix (optional)
208971
+ * @returns the `rotation matrix` or `undefined` (if axis magnitude is near zero).
208972
+ */
208965
208973
  static createRotationAroundVector(axis, angle, result) {
208966
208974
  // Rodriguez formula (matrix form), https://mathworld.wolfram.com/RodriguesRotationFormula.html
208967
208975
  const c = angle.cos();
@@ -209177,63 +209185,143 @@ class Matrix3d {
209177
209185
  return result;
209178
209186
  }
209179
209187
  /**
209180
- * Apply (in place) a jacobi update that zeros out this.at(i,j).
209188
+ * Apply (in place) a jacobi eigenvalue algorithm.
209181
209189
  * @param i row index of zeroed member
209182
209190
  * @param j column index of zeroed member
209183
- * @param k other row/column index (different from i and j)
209184
- * @param leftEigenVectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
209185
- * (allocated by caller, computed and filled by this function)
209191
+ * @param leftEigenvectors a matrix that its columns will be filled by the left eigenvectors of `this` Matrix3d
209192
+ * (allocated by caller, computed and filled by this function). Note that columns of leftEigenVectors will be
209193
+ * mutually perpendicular because `this` matrix is symmetric.
209194
+ * @param lambda a matrix that its diagonal entries will be filled by eigenvalues and its non-diagonal elements
209195
+ * converge to 0 (allocated by caller, computed and filled by this function).
209196
+ */
209197
+ applySymmetricJacobi(i, j, leftEigenvectors, lambda) {
209198
+ const sii = lambda.at(i, i);
209199
+ const sjj = lambda.at(j, j);
209200
+ const sij = lambda.at(i, j);
209201
+ if (Math.abs(sij) < 1.0e-15 * (sii + sjj))
209202
+ return 0.0;
209203
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
209204
+ const c = jacobi.c;
209205
+ const s = jacobi.s;
209206
+ /**
209207
+ * The following check does not exist in applyFastSymmetricJacobi because here if we don't return
209208
+ * early, the matrix remains untouched. However, applyFastSymmetricJacobi zeroes-out elements ij
209209
+ * and ji. Therefore, if we return early in applyFastSymmetricJacobi, zeroing-out wont happen.
209210
+ */
209211
+ if (Math.abs(s) < 2.0e-15)
209212
+ return 0.0;
209213
+ /**
209214
+ * If you apply the following 2 lines to a symmetric matrix, you get same lines used in
209215
+ * applyFastSymmetricJacobi. There are 2 differences which make applyFastSymmetricJacobi
209216
+ * more efficient. First, we directly set elements ij and ji equal to zero rather than
209217
+ * calculation them. Second, we copy symmetric elements from upper triangle to lower
209218
+ * instead of calculating them.
209219
+ */
209220
+ lambda.applyGivensRowOp(i, j, c, s);
209221
+ lambda.applyGivensColumnOp(i, j, c, s);
209222
+ leftEigenvectors.applyGivensColumnOp(i, j, c, s);
209223
+ return Math.abs(sij);
209224
+ }
209225
+ /**
209226
+ * Factor `this` matrix as a product `U * lambda * UT` where `U` is an orthogonal matrix and `lambda`
209227
+ * is a diagonal matrix.
209228
+ *
209229
+ * * **Note 1:** You must apply this function to a `symmetric` matrix. Otherwise, the lower triangle is ignored
209230
+ * and the upper triangle is mirrored to the lower triangle to enforce symmetry.
209231
+ * * **Note 2:** This function is replaced by a faster method called `fastSymmetricEigenvalues` so consider
209232
+ * using the fast version instead.
209233
+ * @param leftEigenvectors a matrix that its columns will be filled by the left eigenvectors of `this` Matrix3d
209234
+ * (allocated by caller, computed and filled by this function). Note that columns of leftEigenVectors will be
209235
+ * mutually perpendicular because `this` matrix is symmetric.
209236
+ * @param lambda a vector that its entries will be filled by eigenvalues of `this` Matrix3d (allocated by
209237
+ * caller, computed and filled by this function).
209238
+ */
209239
+ symmetricEigenvalues(leftEigenvectors, lambda) {
209240
+ const matrix = this.clone();
209241
+ leftEigenvectors.setIdentity();
209242
+ matrix.coffs[3] = matrix.coffs[1];
209243
+ matrix.coffs[6] = matrix.coffs[2];
209244
+ matrix.coffs[7] = matrix.coffs[5];
209245
+ const tolerance = 1.0e-12 * this.sumSquares();
209246
+ const numberOfIterations = 7;
209247
+ for (let iteration = 0; iteration < numberOfIterations; iteration++) {
209248
+ const sum = this.applySymmetricJacobi(0, 1, leftEigenvectors, matrix)
209249
+ + this.applySymmetricJacobi(0, 2, leftEigenvectors, matrix)
209250
+ + this.applySymmetricJacobi(1, 2, leftEigenvectors, matrix);
209251
+ if (sum < tolerance) {
209252
+ lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
209253
+ return true;
209254
+ }
209255
+ }
209256
+ return false;
209257
+ }
209258
+ /**
209259
+ * Apply (in place) a jacobi eigenvalue algorithm that diagonalize `this` matrix, i.e., zeros out this.at(i,j).
209260
+ * * During diagonalization, the upper triangle is mirrored to lower triangle to enforce symmetry.
209261
+ * * Math details can be found at docs/learning/geometry/Matrix.md
209262
+ * @param i row index of zeroed member.
209263
+ * @param j column index of zeroed member.
209264
+ * @param k other row/column index (different from i and j).
209265
+ * @param leftEigenVectors a matrix that its columns will be filled by the left eigenvectors of `this` Matrix3d
209266
+ * (allocated by caller, computed and filled by this function). Note that columns of leftEigenVectors will be
209267
+ * mutually perpendicular because `this` matrix is symmetric.
209186
209268
  */
209187
- applyFastSymmetricJacobiUpdate(i, j, k, leftEigenVectors) {
209269
+ applyFastSymmetricJacobi(i, j, k, leftEigenVectors) {
209188
209270
  const indexII = 4 * i;
209189
209271
  const indexJJ = 4 * j;
209190
209272
  const indexIJ = 3 * i + j;
209273
+ const indexJI = 3 * j + i;
209191
209274
  const indexIK = 3 * i + k;
209275
+ const indexKI = 3 * k + i;
209192
209276
  const indexJK = 3 * j + k;
209193
- const dotUU = this.coffs[indexII];
209194
- const dotVV = this.coffs[indexJJ];
209195
- const dotUV = this.coffs[indexIJ];
209196
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(dotUU - dotVV, 2.0 * dotUV);
209197
- if (Math.abs(dotUV) < 1.0e-15 * (dotUU + dotVV))
209277
+ const indexKJ = 3 * k + j;
209278
+ const sii = this.coffs[indexII];
209279
+ const sjj = this.coffs[indexJJ];
209280
+ const sij = this.coffs[indexIJ];
209281
+ if (Math.abs(sij) < 1.0e-15 * (sii + sjj))
209198
209282
  return 0.0;
209283
+ const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(sii - sjj, 2.0 * sij);
209199
209284
  const c = jacobi.c;
209200
209285
  const s = jacobi.s;
209201
209286
  const cc = c * c;
209202
209287
  const ss = s * s;
209203
209288
  const sc2 = 2.0 * c * s;
209204
- this.coffs[indexII] = cc * dotUU + sc2 * dotUV + ss * dotVV;
209205
- this.coffs[indexJJ] = ss * dotUU - sc2 * dotUV + cc * dotVV;
209289
+ this.coffs[indexII] = cc * sii + sc2 * sij + ss * sjj;
209290
+ this.coffs[indexJJ] = ss * sii - sc2 * sij + cc * sjj;
209206
209291
  this.coffs[indexIJ] = 0.0;
209292
+ this.coffs[indexJI] = 0.0;
209207
209293
  const a = this.coffs[indexIK];
209208
209294
  const b = this.coffs[indexJK];
209209
- this.coffs[indexIK] = a * c + b * s;
209295
+ this.coffs[indexIK] = c * a + s * b;
209210
209296
  this.coffs[indexJK] = -s * a + c * b;
209211
- this.coffs[3 * j + i] = 0.0;
209212
- this.coffs[3 * k + i] = this.coffs[indexIK];
209213
- this.coffs[3 * k + j] = this.coffs[indexJK];
209297
+ this.coffs[indexKI] = this.coffs[indexIK];
209298
+ this.coffs[indexKJ] = this.coffs[indexJK];
209214
209299
  leftEigenVectors.applyGivensColumnOp(i, j, c, s);
209215
- return Math.abs(dotUV);
209300
+ return Math.abs(sij);
209216
209301
  }
209217
209302
  /**
209218
- * Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
209219
- * The upper triangle is mirrored to lower triangle to enforce symmetry.
209220
- * @param leftEigenvectors a matrix that its columns will be filled by eigenvectors of this Matrix3d
209221
- * (allocated by caller, computed and filled by this function)
209222
- * @param lambda a vector that its entries will be filled by eigenvalues of this Matrix3d
209223
- * (allocated by caller, computed and filled by this function)
209303
+ * Factor `this` matrix as a product `U * lambda * UT` where `U` is an orthogonal matrix and `lambda`
209304
+ * is a diagonal matrix.
209305
+ *
209306
+ * * **Note:** You must apply this function to a `symmetric` matrix. Otherwise, the lower triangle is ignored
209307
+ * and the upper triangle is mirrored to the lower triangle to enforce symmetry.
209308
+ * * Math details can be found at docs/learning/geometry/Matrix.md
209309
+ * @param leftEigenvectors a matrix that its columns will be filled by the left eigenvectors of `this` Matrix3d
209310
+ * (allocated by caller, computed and filled by this function). Note that columns of leftEigenVectors will be
209311
+ * mutually perpendicular because `this` matrix is symmetric.
209312
+ * @param lambda a vector that its entries will be filled by eigenvalues of `this` Matrix3d (allocated by
209313
+ * caller, computed and filled by this function).
209224
209314
  */
209225
209315
  fastSymmetricEigenvalues(leftEigenvectors, lambda) {
209226
209316
  const matrix = this.clone();
209227
209317
  leftEigenvectors.setIdentity();
209228
209318
  const tolerance = 1.0e-12 * this.sumSquares();
209229
- for (let iteration = 0; iteration < 7; iteration++) {
209230
- const sum = matrix.applyFastSymmetricJacobiUpdate(0, 1, 2, leftEigenvectors)
209231
- + matrix.applyFastSymmetricJacobiUpdate(0, 2, 1, leftEigenvectors)
209232
- + matrix.applyFastSymmetricJacobiUpdate(1, 2, 0, leftEigenvectors);
209233
- // console.log("symmetric sum", sum);
209234
- // console.log ("sum", sum);
209319
+ const numberOfIterations = 7;
209320
+ for (let iteration = 0; iteration < numberOfIterations; iteration++) {
209321
+ const sum = matrix.applyFastSymmetricJacobi(0, 1, 2, leftEigenvectors)
209322
+ + matrix.applyFastSymmetricJacobi(0, 2, 1, leftEigenvectors)
209323
+ + matrix.applyFastSymmetricJacobi(1, 2, 0, leftEigenvectors);
209235
209324
  if (sum < tolerance) {
209236
- // console.log("symmetric iterations", iteration);
209237
209325
  lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
209238
209326
  return true;
209239
209327
  }
@@ -209241,8 +209329,8 @@ class Matrix3d {
209241
209329
  return false;
209242
209330
  }
209243
209331
  /**
209244
- * Compute the (unit vector) axis and angle of rotation.
209245
- * * math details can be found at docs/learning/geometry/Angle.md
209332
+ * Compute the (unit vector) axis and angle for the rotation generated by `this` Matrix3d.
209333
+ * * Math details can be found at docs/learning/geometry/Angle.md
209246
209334
  * @returns Returns axis and angle of rotation with result.ok === true when the conversion succeeded.
209247
209335
  */
209248
209336
  getAxisAndAngleOfRotation() {
@@ -209268,7 +209356,7 @@ class Matrix3d {
209268
209356
  * 2x^2-1 2xy 2xz
209269
209357
  * 2xy 2y^2-1 2yz
209270
209358
  * 2xz 2yz 2z^2-1
209271
- * Note that the matrix is symmetric.
209359
+ * Note that the matrix is "symmetric".
209272
209360
  * If rotation is around one the standard basis then non-diagonal entries become 0 and we
209273
209361
  * have one 1 and two -1s on the diagonal.
209274
209362
  * If rotation is around an axis other than standard basis, then the axis is the eigenvector
@@ -209290,7 +209378,7 @@ class Matrix3d {
209290
209378
  // Look for eigenvector with eigenvalue = 1
209291
209379
  const eigenvectors = Matrix3d.createIdentity();
209292
209380
  const eigenvalues = _Point3dVector3d__WEBPACK_IMPORTED_MODULE_2__.Vector3d.create(0, 0, 0);
209293
- if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) {
209381
+ if (this.fastSymmetricEigenvalues(eigenvectors, eigenvalues)) { // note: this matrix is "symmetric"
209294
209382
  for (let axisIndex = 0; axisIndex < 2; axisIndex++) {
209295
209383
  const lambda = eigenvalues.at(axisIndex);
209296
209384
  if (_Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.isAlmostEqualNumber(1, lambda))
@@ -209311,53 +209399,67 @@ class Matrix3d {
209311
209399
  };
209312
209400
  return result;
209313
209401
  }
209314
- /** Rotate so columns i and j become perpendicular */
209402
+ /**
209403
+ * Rotate columns i and j of `this` matrix to make them perpendicular using the angle that zero-out
209404
+ * `thisTranspose * this`.
209405
+ * @param i row index of zeroed member.
209406
+ * @param j column index of zeroed member.
209407
+ * @param matrixU a matrix that its columns will be filled by the right eigenvectors of `thisTranspose * this`
209408
+ * (allocated by caller, computed and filled by this function). Note that columns of matrixU will be mutually
209409
+ * perpendicular because `thisTranspose * this` matrix is symmetric.
209410
+ */
209315
209411
  applyJacobiColumnRotation(i, j, matrixU) {
209316
- const uDotU = this.coffs[i] * this.coffs[i] + this.coffs[i + 3] * this.coffs[i + 3] + this.coffs[i + 6] * this.coffs[i + 6];
209317
- const vDotV = this.coffs[j] * this.coffs[j] + this.coffs[j + 3] * this.coffs[j + 3] + this.coffs[j + 6] * this.coffs[j + 6];
209318
- const uDotV = this.coffs[i] * this.coffs[j] + this.coffs[i + 3] * this.coffs[j + 3] + this.coffs[i + 6] * this.coffs[j + 6];
209319
- // const c2 = uDotU - vDotV;
209320
- // const s2 = 2.0 * uDotV;
209412
+ const uDotU = this.coffs[i] * this.coffs[i]
209413
+ + this.coffs[i + 3] * this.coffs[i + 3]
209414
+ + this.coffs[i + 6] * this.coffs[i + 6];
209415
+ const vDotV = this.coffs[j] * this.coffs[j]
209416
+ + this.coffs[j + 3] * this.coffs[j + 3]
209417
+ + this.coffs[j + 6] * this.coffs[j + 6];
209418
+ const uDotV = this.coffs[i] * this.coffs[j]
209419
+ + this.coffs[i + 3] * this.coffs[j + 3]
209420
+ + this.coffs[i + 6] * this.coffs[j + 6];
209321
209421
  const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(uDotU - vDotV, 2.0 * uDotV);
209322
- // const h = Math.hypot(c2, s2);
209323
- // console.log(" c2 s2", c2 / h, s2 / h);
209324
- // console.log(" C S ", Math.cos(2 * jacobi.radians), Math.sin(2 * jacobi.radians));
209325
- // console.log("i j uDotV", i, j, uDotV);
209326
- if (Math.abs(jacobi.s) < 2.0e-15)
209422
+ const c = jacobi.c;
209423
+ const s = jacobi.s;
209424
+ if (Math.abs(s) < 2.0e-15)
209327
209425
  return 0.0;
209328
- this.applyGivensColumnOp(i, j, jacobi.c, jacobi.s);
209329
- matrixU.applyGivensRowOp(i, j, jacobi.c, jacobi.s);
209330
- // const BTB = this.multiplyMatrixTransposeMatrix(this);
209331
- // console.log("BTB", BTB.at(0, 0), BTB.at(1, 1), BTB.at(2, 2), " off", BTB.at(0, 1), BTB.at(0, 2), BTB.at(1, 2), " at(i,j)", BTB.at(i, j));
209426
+ this.applyGivensColumnOp(i, j, c, s); // make columns i and j of `this` matrix perpendicular
209427
+ matrixU.applyGivensRowOp(i, j, c, s); // right eigenvalues of `thisTranspose * this`
209332
209428
  return Math.abs(uDotV);
209333
209429
  }
209334
209430
  /**
209335
- * Factor this as a product C * U where C has mutually perpendicular columns and
209336
- * U is orthogonal.
209337
- * @param matrixC (allocate by caller, computed here)
209338
- * @param matrixU (allocate by caller, computed here)
209431
+ * Factor `this` matrix as a product `VD * U` where `VD` has mutually perpendicular columns and `U` is orthogonal.
209432
+ * @param matrixVD a matrix that its columns will be filled by rotating columns of `this` to make them mutually
209433
+ * perpendicular (allocated by caller, computed and filled by this function).
209434
+ * @param matrixU a matrix that its columns will be filled by the right eigenvectors of `thisTranspose * this`
209435
+ * (allocated by caller, computed and filled by this function). Note that columns of matrixU will be mutually
209436
+ * perpendicular because `thisTranspose * this` matrix is symmetric.
209339
209437
  */
209340
- factorPerpendicularColumns(matrixC, matrixU) {
209341
- matrixC.setFrom(this);
209438
+ factorPerpendicularColumns(matrixVD, matrixU) {
209439
+ matrixVD.setFrom(this);
209342
209440
  matrixU.setIdentity();
209343
209441
  const tolerance = 1.0e-12 * this.sumSquares();
209344
- for (let iteration = 0; iteration < 7; iteration++) {
209345
- const sum = matrixC.applyJacobiColumnRotation(0, 1, matrixU)
209346
- + matrixC.applyJacobiColumnRotation(0, 2, matrixU)
209347
- + matrixC.applyJacobiColumnRotation(1, 2, matrixU);
209348
- // console.log (" sum", sum);
209442
+ const numberOfIterations = 7;
209443
+ for (let iteration = 0; iteration < numberOfIterations; iteration++) {
209444
+ const sum = matrixVD.applyJacobiColumnRotation(0, 1, matrixU)
209445
+ + matrixVD.applyJacobiColumnRotation(0, 2, matrixU)
209446
+ + matrixVD.applyJacobiColumnRotation(1, 2, matrixU);
209349
209447
  if (sum < tolerance) {
209350
- // console.log("jacobi iterations", iteration);
209351
209448
  return true;
209352
209449
  }
209353
209450
  }
209354
209451
  return false;
209355
209452
  }
209356
209453
  /**
209357
- * Factor this matrix M as a product M = V * D * U where V and U are orthogonal, and D is diagonal (scale matrix).
209358
- * @param matrixV left orthogonal factor (allocate by caller, computed here)
209359
- * @param scale diagonal entries of D (allocate by caller, computed here)
209360
- * @param matrixU right orthogonal factor (allocate by caller, computed here)
209454
+ * Factor `this` matrix as a product `V * D * U` where `V` and `U` are orthogonal and `D` is diagonal with
209455
+ * positive entries.
209456
+ * * This is formally known as the `Singular Value Decomposition` or `SVD`.
209457
+ * @param matrixV an orthogonal matrix that its columns will be filled by the left eigenvectors of
209458
+ * `thisTranspose * this` (allocated by caller, computed and filled by this function).
209459
+ * @param scale singular values of `this` (allocated by caller, computed and filled by this function).
209460
+ * The singular values in the `scale` are non-negative and decreasing.
209461
+ * @param matrixU an orthogonal matrix that its columns will be filled by the right eigenvectors of
209462
+ * `thisTranspose * this` (allocated by caller, computed and filled by this function).
209361
209463
  */
209362
209464
  factorOrthogonalScaleOrthogonal(matrixV, scale, matrixU) {
209363
209465
  const matrixVD = Matrix3d.createZero();
@@ -209367,7 +209469,7 @@ class Matrix3d {
209367
209469
  column.push(matrixVD.getColumn(0));
209368
209470
  column.push(matrixVD.getColumn(1));
209369
209471
  column.push(matrixVD.getColumn(2));
209370
- scale.set(column[0].magnitude(), column[1].magnitude(), column[2].magnitude());
209472
+ scale.set(column[0].magnitude(), column[1].magnitude(), column[2].magnitude()); // singular values of `this`
209371
209473
  const det = matrixVD.determinant();
209372
209474
  if (det < 0)
209373
209475
  scale.z = -scale.z;
@@ -209375,7 +209477,7 @@ class Matrix3d {
209375
209477
  const scaleXIsZero = Math.abs(scale.x) < almostZero;
209376
209478
  const scaleYIsZero = Math.abs(scale.y) < almostZero;
209377
209479
  const scaleZIsZero = Math.abs(scale.z) < almostZero;
209378
- // ASSUME: any zero-magnitude column(s) of matrixVD are last
209480
+ // NOTE: We assume any zero-magnitude column(s) of matrixVD are last
209379
209481
  if (!scaleXIsZero && !scaleYIsZero && !scaleZIsZero) { // full rank
209380
209482
  matrixV = matrixVD.scaleColumns(1 / scale.x, 1 / scale.y, 1 / scale.z, matrixV);
209381
209483
  }
@@ -209393,59 +209495,6 @@ class Matrix3d {
209393
209495
  }
209394
209496
  return true;
209395
209497
  }
209396
- /** Apply a jacobi step to lambda which evolves towards diagonal. */
209397
- applySymmetricJacobi(i, j, lambda) {
209398
- const uDotU = lambda.at(i, i);
209399
- const vDotV = lambda.at(j, j);
209400
- const uDotV = lambda.at(i, j);
209401
- if (Math.abs(uDotV) < 1.0e-15 * (uDotU + vDotV))
209402
- return 0.0;
209403
- // const c2 = uDotU - vDotV;
209404
- // const s2 = 2.0 * uDotV;
209405
- const jacobi = _Angle__WEBPACK_IMPORTED_MODULE_1__.Angle.trigValuesToHalfAngleTrigValues(uDotU - vDotV, 2.0 * uDotV);
209406
- // const h = Math.hypot(c2, s2);
209407
- // console.log(" c2 s2", c2 / h, s2 / h);
209408
- // console.log(" C S ", Math.cos(2 * jacobi.radians), Math.sin(2 * jacobi.radians));
209409
- // console.log("i j uDotV", i, j, uDotV);
209410
- if (Math.abs(jacobi.s) < 2.0e-15)
209411
- return 0.0;
209412
- // Factored form is this *lambda * thisTranspose
209413
- // Let Q be the rotation matrix. Q*QT is inserted, viz
209414
- // this*Q * QT * lambda * Q*thisTranspose
209415
- this.applyGivensColumnOp(i, j, jacobi.c, jacobi.s);
209416
- lambda.applyGivensRowOp(i, j, jacobi.c, jacobi.s);
209417
- lambda.applyGivensColumnOp(i, j, jacobi.c, jacobi.s);
209418
- // const BTB = this.multiplyMatrixTransposeMatrix(this);
209419
- // console.log("BTB", BTB.at(0, 0), BTB.at(1, 1), BTB.at(2, 2), " off", BTB.at(0, 1), BTB.at(0, 2), BTB.at(1, 2), " at(i,j)", BTB.at(i, j));
209420
- return Math.abs(uDotV);
209421
- }
209422
- /**
209423
- * Factor this (symmetrized) as a product U * lambda * UT where U is orthogonal, lambda is diagonal.
209424
- * The upper triangle is mirrored to lower triangle to enforce symmetry.
209425
- * @param matrixC (allocate by caller, computed here)
209426
- * @param factor (allocate by caller, computed here)
209427
- */
209428
- symmetricEigenvalues(leftEigenvectors, lambda) {
209429
- const matrix = this.clone();
209430
- leftEigenvectors.setIdentity();
209431
- matrix.coffs[3] = matrix.coffs[1];
209432
- matrix.coffs[6] = matrix.coffs[2];
209433
- matrix.coffs[7] = matrix.coffs[5];
209434
- const tolerance = 1.0e-12 * this.sumSquares();
209435
- for (let iteration = 0; iteration < 7; iteration++) {
209436
- const sum = leftEigenvectors.applySymmetricJacobi(0, 1, matrix)
209437
- + leftEigenvectors.applySymmetricJacobi(0, 2, matrix)
209438
- + leftEigenvectors.applySymmetricJacobi(1, 2, matrix);
209439
- // console.log("symmetric sum", sum);
209440
- // console.log (" sum", sum);
209441
- if (sum < tolerance) {
209442
- // console.log("symmetric iterations", iteration);
209443
- lambda.set(matrix.at(0, 0), matrix.at(1, 1), matrix.at(2, 2));
209444
- return true;
209445
- }
209446
- }
209447
- return false;
209448
- }
209449
209498
  /**
209450
209499
  * Return a matrix that rotates a fraction of the angular sweep from vectorA to vectorB.
209451
209500
  * @param vectorA initial vector position
@@ -210543,8 +210592,7 @@ class Matrix3d {
210543
210592
  this.inverseState = InverseMatrixState.unknown;
210544
210593
  }
210545
210594
  /**
210546
- * Create a rigid matrix (columns and rows are unit length and pairwise perpendicular) for
210547
- * the given eye coordinate.
210595
+ * Create a rigid matrix (columns and rows are unit length and pairwise perpendicular) for the given eye coordinate.
210548
210596
  * * column 2 is parallel to (x,y,z).
210549
210597
  * * column 0 is perpendicular to column 2 and is in the xy plane.
210550
210598
  * * column 1 is perpendicular to both. It is the "up" vector on the view plane.
@@ -210577,7 +210625,8 @@ class Matrix3d {
210577
210625
  *
210578
210626
  * This is an orthogonal matrix meaning it rotates the standard XYZ axis to ABC axis system
210579
210627
  * (if matrix is [A B C]). The matrix rotates (0,0,1), i.e., the default Top view or Z axis,
210580
- * to the eye point (x/r,y/r,z/r). The matrix also rotates (1,0,0) to a point on XY plane.
210628
+ * to the eye point (x/r,y/r,z/r) where r = sqrt(x*x + y*y + z*z). The matrix also rotates
210629
+ * (1,0,0) to a point on XY plane.
210581
210630
  */
210582
210631
  const c = x / rxy;
210583
210632
  const s = y / rxy;
@@ -210657,6 +210706,15 @@ class Matrix3d {
210657
210706
  const sumOff = Math.abs(sumAll - sumDiagonal);
210658
210707
  return Math.sqrt(sumOff) <= _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians * (1.0 + Math.sqrt(sumAll));
210659
210708
  }
210709
+ /** Sum of squared differences between symmetric pairs (symmetric pairs have indices (1,3), (2,6), and (5,7).) */
210710
+ sumSkewSquares() {
210711
+ return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1] - this.coffs[3], this.coffs[2] - this.coffs[6], this.coffs[5] - this.coffs[7]);
210712
+ }
210713
+ /** Test if the matrix is (very near to) symmetric */
210714
+ isSymmetric() {
210715
+ const offDiagonal = this.sumSkewSquares();
210716
+ return Math.sqrt(offDiagonal) <= _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians * (1.0 + Math.sqrt(this.sumSquares()));
210717
+ }
210660
210718
  /** Test if the stored inverse is present and marked valid */
210661
210719
  get hasCachedInverse() {
210662
210720
  return this.inverseState === InverseMatrixState.inverseStored && this.inverseCoffs !== undefined;
@@ -210670,7 +210728,7 @@ class Matrix3d {
210670
210728
  /** Test if the above diagonal entries (1,2,5) are all nearly zero */
210671
210729
  get isLowerTriangular() {
210672
210730
  const sumAll = this.sumSquares();
210673
- const sumLow = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[2], this.coffs[75]);
210731
+ const sumLow = _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1], this.coffs[2], this.coffs[5]);
210674
210732
  return Math.sqrt(sumLow) <= _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.smallAngleRadians * (1.0 + Math.sqrt(sumAll));
210675
210733
  }
210676
210734
  /**
@@ -210687,10 +210745,6 @@ class Matrix3d {
210687
210745
  return this.coffs[0];
210688
210746
  return undefined;
210689
210747
  }
210690
- /** Sum of squared differences between symmetric pairs (entry 1 and 3 - 2 and 6 - 5 and 7) */
210691
- sumSkewSquares() {
210692
- return _Geometry__WEBPACK_IMPORTED_MODULE_0__.Geometry.hypotenuseSquaredXYZ(this.coffs[1] - this.coffs[3], this.coffs[2] - this.coffs[6], this.coffs[5] - this.coffs[7]);
210693
- }
210694
210748
  /**
210695
210749
  * Test if all rows and columns are unit length and are perpendicular to each other, i.e., the matrix is either
210696
210750
  * a `pure rotation` (determinant is +1) or is a `mirror` (determinant is -1).
@@ -210994,6 +211048,7 @@ class OrderedRotationAngles {
210994
211048
  * For example XYZ means to rotate around x axis first, then y axis, and finally Z axis.
210995
211049
  * * Note that rotation order is reverse of rotation matrix multiplication so for XYZ the rotation
210996
211050
  * matrix multiplication would be zRot*yRot*xRot
211051
+ * * Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/CubeRotationAroundStandardAxes
210997
211052
  * @param xyzRotationIsClockwise the flags controlling whether direction of x,y,z is clockwise or counterclockwise.
210998
211053
  * rotation direction of x,y,z: true ---> clockwise - false ---> counterclockwise.
210999
211054
  * * if xyzRotationIsClockwise is undefined it's set to [false, false, false].
@@ -287758,7 +287813,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
287758
287813
  /***/ ((module) => {
287759
287814
 
287760
287815
  "use strict";
287761
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.39","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.39","@itwin/core-bentley":"workspace:^4.0.0-dev.39","@itwin/core-common":"workspace:^4.0.0-dev.39","@itwin/core-geometry":"workspace:^4.0.0-dev.39","@itwin/core-orbitgt":"workspace:^4.0.0-dev.39","@itwin/core-quantity":"workspace:^4.0.0-dev.39"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/mocha":"^8.2.2","@types/node":"^18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"^1.5.0","@itwin/cloud-agnostic-core":"^1.5.0","@itwin/object-storage-core":"^1.5.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
287816
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.0.0-dev.40","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs","build:ci":"npm run -s build && npm run -s build:esm","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"../../tools/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core/tree/master/core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.0.0-dev.40","@itwin/core-bentley":"workspace:^4.0.0-dev.40","@itwin/core-common":"workspace:^4.0.0-dev.40","@itwin/core-geometry":"workspace:^4.0.0-dev.40","@itwin/core-orbitgt":"workspace:^4.0.0-dev.40","@itwin/core-quantity":"workspace:^4.0.0-dev.40"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/deep-assign":"^0.1.0","@types/mocha":"^8.2.2","@types/node":"^18.11.5","@types/qs":"^6.5.0","@types/semver":"7.3.10","@types/superagent":"^4.1.14","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^7.11.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~4.4.0","webpack":"^5.64.4"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"^1.5.0","@itwin/cloud-agnostic-core":"^1.5.0","@itwin/object-storage-core":"^1.5.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","deep-assign":"^2.0.0","fuse.js":"^3.3.0","qs":"^6.5.3","semver":"^7.3.5","superagent":"^7.1.5","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
287762
287817
 
287763
287818
  /***/ })
287764
287819