24
#include "PreCompiled.h"
38
: dMtrx4D {{1., 0., 0., 0.},
44
Matrix4D::Matrix4D(float a11, float a12, float a13, float a14,
45
float a21, float a22, float a23, float a24,
46
float a31, float a32, float a33, float a34,
47
float a41, float a42, float a43, float a44)
48
: dMtrx4D {{a11, a12, a13, a14},
54
Matrix4D::Matrix4D(double a11, double a12, double a13, double a14,
55
double a21, double a22, double a23, double a24,
56
double a31, double a32, double a33, double a34,
57
double a41, double a42, double a43, double a44)
58
: dMtrx4D {{a11, a12, a13, a14},
65
Matrix4D::Matrix4D(const Matrix4D& mat)
71
Matrix4D::Matrix4D(const Vector3f& rclBase, const Vector3f& rclDir, float fAngle)
74
this->rotLine(rclBase, rclDir, fAngle);
77
Matrix4D::Matrix4D(const Vector3d& rclBase, const Vector3d& rclDir, double fAngle)
80
this->rotLine(rclBase, rclDir, fAngle);
83
void Matrix4D::setToUnity()
103
bool Matrix4D::isUnity() const
108
bool Matrix4D::isUnity(double tol) const
110
for (int i = 0; i < 4; i++) {
111
for (int j = 0; j < 4; j++) {
113
if (fabs(dMtrx4D[i][j] - 1.0) > tol) {
118
if (fabs(dMtrx4D[i][j]) > tol) {
128
void Matrix4D::nullify()
148
bool Matrix4D::isNull() const
151
for (int i = 0; i < 4; i++) {
152
for (int j = 0; j < 4; j++) {
153
if (dMtrx4D[i][j] != 0.0) {
163
double Matrix4D::determinant() const
165
double fA0 = dMtrx4D[0][0] * dMtrx4D[1][1] - dMtrx4D[0][1] * dMtrx4D[1][0];
166
double fA1 = dMtrx4D[0][0] * dMtrx4D[1][2] - dMtrx4D[0][2] * dMtrx4D[1][0];
167
double fA2 = dMtrx4D[0][0] * dMtrx4D[1][3] - dMtrx4D[0][3] * dMtrx4D[1][0];
168
double fA3 = dMtrx4D[0][1] * dMtrx4D[1][2] - dMtrx4D[0][2] * dMtrx4D[1][1];
169
double fA4 = dMtrx4D[0][1] * dMtrx4D[1][3] - dMtrx4D[0][3] * dMtrx4D[1][1];
170
double fA5 = dMtrx4D[0][2] * dMtrx4D[1][3] - dMtrx4D[0][3] * dMtrx4D[1][2];
171
double fB0 = dMtrx4D[2][0] * dMtrx4D[3][1] - dMtrx4D[2][1] * dMtrx4D[3][0];
172
double fB1 = dMtrx4D[2][0] * dMtrx4D[3][2] - dMtrx4D[2][2] * dMtrx4D[3][0];
173
double fB2 = dMtrx4D[2][0] * dMtrx4D[3][3] - dMtrx4D[2][3] * dMtrx4D[3][0];
174
double fB3 = dMtrx4D[2][1] * dMtrx4D[3][2] - dMtrx4D[2][2] * dMtrx4D[3][1];
175
double fB4 = dMtrx4D[2][1] * dMtrx4D[3][3] - dMtrx4D[2][3] * dMtrx4D[3][1];
176
double fB5 = dMtrx4D[2][2] * dMtrx4D[3][3] - dMtrx4D[2][3] * dMtrx4D[3][2];
177
double fDet = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0;
181
double Matrix4D::determinant3() const
183
double va = dMtrx4D[0][0] * dMtrx4D[1][1] * dMtrx4D[2][2];
184
double vb = dMtrx4D[0][1] * dMtrx4D[1][2] * dMtrx4D[2][0];
185
double vc = dMtrx4D[1][0] * dMtrx4D[2][1] * dMtrx4D[0][2];
186
double vd = dMtrx4D[0][2] * dMtrx4D[1][1] * dMtrx4D[2][0];
187
double ve = dMtrx4D[1][0] * dMtrx4D[0][1] * dMtrx4D[2][2];
188
double vf = dMtrx4D[0][0] * dMtrx4D[2][1] * dMtrx4D[1][2];
189
double det = (va + vb + vc) - (vd + ve + vf);
193
void Matrix4D::move(const Vector3f& vec)
195
move(convertTo<Vector3d>(vec));
198
void Matrix4D::move(const Vector3d& vec)
200
dMtrx4D[0][3] += vec.x;
201
dMtrx4D[1][3] += vec.y;
202
dMtrx4D[2][3] += vec.z;
205
void Matrix4D::scale(const Vector3f& vec)
207
scale(convertTo<Vector3d>(vec));
210
void Matrix4D::scale(const Vector3d& vec)
214
clMat.dMtrx4D[0][0] = vec.x;
215
clMat.dMtrx4D[1][1] = vec.y;
216
clMat.dMtrx4D[2][2] = vec.z;
217
(*this) = clMat * (*this);
220
void Matrix4D::rotX(double fAngle)
228
clMat.dMtrx4D[1][1] = fcos;
229
clMat.dMtrx4D[2][2] = fcos;
230
clMat.dMtrx4D[1][2] = -fsin;
231
clMat.dMtrx4D[2][1] = fsin;
233
(*this) = clMat * (*this);
236
void Matrix4D::rotY(double fAngle)
244
clMat.dMtrx4D[0][0] = fcos;
245
clMat.dMtrx4D[2][2] = fcos;
246
clMat.dMtrx4D[2][0] = -fsin;
247
clMat.dMtrx4D[0][2] = fsin;
249
(*this) = clMat * (*this);
252
void Matrix4D::rotZ(double fAngle)
260
clMat.dMtrx4D[0][0] = fcos;
261
clMat.dMtrx4D[1][1] = fcos;
262
clMat.dMtrx4D[0][1] = -fsin;
263
clMat.dMtrx4D[1][0] = fsin;
265
(*this) = clMat * (*this);
268
void Matrix4D::rotLine(const Vector3d& vec, double fAngle)
275
Vector3d clRotAxis(vec);
280
for (short iz = 0; iz < 4; iz++) {
281
for (short is = 0; is < 4; is++) {
282
clMA.dMtrx4D[iz][is] = 0;
283
clMB.dMtrx4D[iz][is] = 0;
284
clMC.dMtrx4D[iz][is] = 0;
289
clRotAxis.Normalize();
295
clMA.dMtrx4D[0][0] = (1 - fcos) * clRotAxis.x * clRotAxis.x;
296
clMA.dMtrx4D[0][1] = (1 - fcos) * clRotAxis.x * clRotAxis.y;
297
clMA.dMtrx4D[0][2] = (1 - fcos) * clRotAxis.x * clRotAxis.z;
298
clMA.dMtrx4D[1][0] = (1 - fcos) * clRotAxis.x * clRotAxis.y;
299
clMA.dMtrx4D[1][1] = (1 - fcos) * clRotAxis.y * clRotAxis.y;
300
clMA.dMtrx4D[1][2] = (1 - fcos) * clRotAxis.y * clRotAxis.z;
301
clMA.dMtrx4D[2][0] = (1 - fcos) * clRotAxis.x * clRotAxis.z;
302
clMA.dMtrx4D[2][1] = (1 - fcos) * clRotAxis.y * clRotAxis.z;
303
clMA.dMtrx4D[2][2] = (1 - fcos) * clRotAxis.z * clRotAxis.z;
305
clMB.dMtrx4D[0][0] = fcos;
306
clMB.dMtrx4D[1][1] = fcos;
307
clMB.dMtrx4D[2][2] = fcos;
309
clMC.dMtrx4D[0][1] = -fsin * clRotAxis.z;
310
clMC.dMtrx4D[0][2] = fsin * clRotAxis.y;
311
clMC.dMtrx4D[1][0] = fsin * clRotAxis.z;
312
clMC.dMtrx4D[1][2] = -fsin * clRotAxis.x;
313
clMC.dMtrx4D[2][0] = -fsin * clRotAxis.y;
314
clMC.dMtrx4D[2][1] = fsin * clRotAxis.x;
316
for (short iz = 0; iz < 3; iz++) {
317
for (short is = 0; is < 3; is++) {
318
clMRot.dMtrx4D[iz][is] =
319
clMA.dMtrx4D[iz][is] + clMB.dMtrx4D[iz][is] + clMC.dMtrx4D[iz][is];
323
(*this) = clMRot * (*this);
326
void Matrix4D::rotLine(const Vector3f& vec, float fAngle)
328
Vector3d tmp = convertTo<Vector3d>(vec);
329
rotLine(tmp, static_cast<double>(fAngle));
332
void Matrix4D::rotLine(const Vector3d& rclBase, const Vector3d& rclDir, double fAngle)
335
clMRot.rotLine(rclDir, fAngle);
336
transform(rclBase, clMRot);
339
void Matrix4D::rotLine(const Vector3f& rclBase, const Vector3f& rclDir, float fAngle)
341
Vector3d pnt = convertTo<Vector3d>(rclBase);
342
Vector3d dir = convertTo<Vector3d>(rclDir);
343
rotLine(pnt, dir, static_cast<double>(fAngle));
358
bool Matrix4D::toAxisAngle(Vector3f& rclBase,
361
float& fTranslation) const
363
Vector3d pnt = convertTo<Vector3d>(rclBase);
364
Vector3d dir = convertTo<Vector3d>(rclDir);
365
double dAngle = static_cast<double>(rfAngle);
366
double dTranslation = static_cast<double>(fTranslation);
368
bool ok = toAxisAngle(pnt, dir, dAngle, dTranslation);
370
rclBase = convertTo<Vector3f>(pnt);
371
rclDir = convertTo<Vector3f>(dir);
372
rfAngle = static_cast<float>(dAngle);
373
fTranslation = static_cast<float>(dTranslation);
379
bool Matrix4D::toAxisAngle(Vector3d& rclBase,
382
double& fTranslation) const
385
for (int i = 0; i < 3; i++) {
387
if (fabs(dMtrx4D[0][i] * dMtrx4D[0][i] + dMtrx4D[1][i] * dMtrx4D[1][i]
388
+ dMtrx4D[2][i] * dMtrx4D[2][i] - 1.0)
393
if (fabs(dMtrx4D[0][i] * dMtrx4D[0][(i + 1) % 3] + dMtrx4D[1][i] * dMtrx4D[1][(i + 1) % 3]
394
+ dMtrx4D[2][i] * dMtrx4D[2][(i + 1) % 3])
427
double fTrace = dMtrx4D[0][0] + dMtrx4D[1][1] + dMtrx4D[2][2];
428
double fCos = 0.5 * (fTrace - 1.0);
429
rfAngle = acos(fCos);
432
if (rfAngle < D_PI) {
433
rclDir.x = (dMtrx4D[2][1] - dMtrx4D[1][2]);
434
rclDir.y = (dMtrx4D[0][2] - dMtrx4D[2][0]);
435
rclDir.z = (dMtrx4D[1][0] - dMtrx4D[0][1]);
440
double fHalfInverse {};
441
if (dMtrx4D[0][0] >= dMtrx4D[1][1]) {
443
if (dMtrx4D[0][0] >= dMtrx4D[2][2]) {
445
rclDir.x = (0.5 * sqrt(dMtrx4D[0][0] - dMtrx4D[1][1] - dMtrx4D[2][2] + 1.0));
446
fHalfInverse = 0.5 / rclDir.x;
447
rclDir.y = (fHalfInverse * dMtrx4D[0][1]);
448
rclDir.z = (fHalfInverse * dMtrx4D[0][2]);
452
rclDir.z = (0.5 * sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
453
fHalfInverse = 0.5 / rclDir.z;
454
rclDir.x = (fHalfInverse * dMtrx4D[0][2]);
455
rclDir.y = (fHalfInverse * dMtrx4D[1][2]);
460
if (dMtrx4D[1][1] >= dMtrx4D[2][2]) {
462
rclDir.y = (0.5 * sqrt(dMtrx4D[1][1] - dMtrx4D[0][0] - dMtrx4D[2][2] + 1.0));
463
fHalfInverse = 0.5 / rclDir.y;
464
rclDir.x = (fHalfInverse * dMtrx4D[0][1]);
465
rclDir.z = (fHalfInverse * dMtrx4D[1][2]);
469
rclDir.z = (0.5 * sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
470
fHalfInverse = 0.5 / rclDir.z;
471
rclDir.x = (fHalfInverse * dMtrx4D[0][2]);
472
rclDir.y = (fHalfInverse * dMtrx4D[1][2]);
489
fTranslation = (dMtrx4D[0][3] * rclDir.x + dMtrx4D[1][3] * rclDir.y + dMtrx4D[2][3] * rclDir.z);
490
Vector3d cPnt(dMtrx4D[0][3], dMtrx4D[1][3], dMtrx4D[2][3]);
491
cPnt = cPnt - fTranslation * rclDir;
495
double factor = 0.5 * (1.0 + fTrace) / sin(rfAngle);
496
rclBase.x = (0.5 * (cPnt.x + factor * (rclDir.y * cPnt.z - rclDir.z * cPnt.y)));
497
rclBase.y = (0.5 * (cPnt.y + factor * (rclDir.z * cPnt.x - rclDir.x * cPnt.z)));
498
rclBase.z = (0.5 * (cPnt.z + factor * (rclDir.x * cPnt.y - rclDir.y * cPnt.x)));
504
void Matrix4D::transform(const Vector3f& vec, const Matrix4D& mat)
507
(*this) = mat * (*this);
511
void Matrix4D::transform(const Vector3d& vec, const Matrix4D& mat)
514
(*this) = mat * (*this);
518
void Matrix4D::inverse()
520
Matrix4D clInvTrlMat;
521
Matrix4D clInvRotMat;
525
for (short iz = 0; iz < 3; iz++) {
526
clInvTrlMat.dMtrx4D[iz][3] = -dMtrx4D[iz][3];
531
for (short iz = 0; iz < 3; iz++) {
532
for (short is = 0; is < 3; is++) {
533
clInvRotMat.dMtrx4D[iz][is] = dMtrx4D[is][iz];
538
(*this) = clInvRotMat * clInvTrlMat;
541
using Matrix = double*;
544
void Matrix_gauss(Matrix a, Matrix b)
546
int ipiv[4], indxr[4], indxc[4];
547
int i {}, j {}, k {}, l {}, ll {};
548
int irow = 0, icol = 0;
549
double big {}, pivinv {};
551
for (j = 0; j < 4; j++) {
554
for (i = 0; i < 4; i++) {
556
for (j = 0; j < 4; j++) {
558
for (k = 0; k < 4; k++) {
560
if (fabs(a[4 * j + k]) >= big) {
561
big = fabs(a[4 * j + k]);
566
else if (ipiv[k] > 1) {
572
ipiv[icol] = ipiv[icol] + 1;
574
for (l = 0; l < 4; l++) {
575
dum = a[4 * irow + l];
576
a[4 * irow + l] = a[4 * icol + l];
577
a[4 * icol + l] = dum;
579
for (l = 0; l < 4; l++) {
580
dum = b[4 * irow + l];
581
b[4 * irow + l] = b[4 * icol + l];
582
b[4 * icol + l] = dum;
587
if (a[4 * icol + icol] == 0.0) {
590
pivinv = 1.0 / a[4 * icol + icol];
591
a[4 * icol + icol] = 1.0;
592
for (l = 0; l < 4; l++) {
593
a[4 * icol + l] = a[4 * icol + l] * pivinv;
595
for (l = 0; l < 4; l++) {
596
b[4 * icol + l] = b[4 * icol + l] * pivinv;
598
for (ll = 0; ll < 4; ll++) {
600
dum = a[4 * ll + icol];
601
a[4 * ll + icol] = 0;
602
for (l = 0; l < 4; l++) {
603
a[4 * ll + l] = a[4 * ll + l] - a[4 * icol + l] * dum;
605
for (l = 0; l < 4; l++) {
606
b[4 * ll + l] = b[4 * ll + l] - b[4 * icol + l] * dum;
611
for (l = 3; l >= 0; l--) {
612
if (indxr[l] != indxc[l]) {
613
for (k = 0; k < 4; k++) {
614
dum = a[4 * k + indxr[l]];
615
a[4 * k + indxr[l]] = a[4 * k + indxc[l]];
616
a[4 * k + indxc[l]] = dum;
623
void Matrix4D::inverseOrthogonal()
625
Base::Vector3d vec(dMtrx4D[0][3], dMtrx4D[1][3], dMtrx4D[2][3]);
627
vec = this->operator*(vec);
628
dMtrx4D[0][3] = -vec.x;
630
dMtrx4D[1][3] = -vec.y;
632
dMtrx4D[2][3] = -vec.z;
636
void Matrix4D::inverseGauss()
640
double inversematrix[16] = {1, 0, 0, 0,
647
Matrix_gauss(matrix, inversematrix);
649
setGLMatrix(inversematrix);
652
void Matrix4D::getMatrix(double dMtrx[16]) const
654
for (short iz = 0; iz < 4; iz++) {
655
for (short is = 0; is < 4; is++) {
656
dMtrx[4 * iz + is] = dMtrx4D[iz][is];
661
void Matrix4D::setMatrix(const double dMtrx[16])
663
for (short iz = 0; iz < 4; iz++) {
664
for (short is = 0; is < 4; is++) {
665
dMtrx4D[iz][is] = dMtrx[4 * iz + is];
670
void Matrix4D::getGLMatrix(double dMtrx[16]) const
672
for (short iz = 0; iz < 4; iz++) {
673
for (short is = 0; is < 4; is++) {
674
dMtrx[iz + 4 * is] = dMtrx4D[iz][is];
679
void Matrix4D::setGLMatrix(const double dMtrx[16])
681
for (short iz = 0; iz < 4; iz++) {
682
for (short is = 0; is < 4; is++) {
683
dMtrx4D[iz][is] = dMtrx[iz + 4 * is];
688
unsigned long Matrix4D::getMemSpace()
690
return sizeof(Matrix4D);
693
void Matrix4D::Print() const
696
for (short i = 0; i < 4; i++) {
697
printf("%9.3f %9.3f %9.3f %9.3f\n",
706
void Matrix4D::transpose()
710
for (int i = 0; i < 4; i++) {
711
for (int j = 0; j < 4; j++) {
712
dNew[j][i] = dMtrx4D[i][j];
716
memcpy(dMtrx4D, dNew, sizeof(dMtrx4D));
721
std::string Matrix4D::toString() const
723
std::stringstream str;
725
for (int i = 0; i < 4; i++) {
726
for (int j = 0; j < 4; j++) {
727
str << dMtrx4D[i][j] << " ";
736
void Matrix4D::fromString(const std::string& str)
738
std::stringstream input;
742
for (int i = 0; i < 4; i++) {
743
for (int j = 0; j < 4; j++) {
744
input >> dMtrx4D[i][j];
751
std::string Matrix4D::analyse() const
753
const double eps = 1.0e-06;
754
bool hastranslation = (dMtrx4D[0][3] != 0.0 || dMtrx4D[1][3] != 0.0 || dMtrx4D[2][3] != 0.0);
755
const Base::Matrix4D unityMatrix = Base::Matrix4D();
757
if (*this == unityMatrix) {
758
text = "Unity Matrix";
761
if (dMtrx4D[3][0] != 0.0 || dMtrx4D[3][1] != 0.0 || dMtrx4D[3][2] != 0.0
762
|| dMtrx4D[3][3] != 1.0) {
767
if (dMtrx4D[0][1] == 0.0 && dMtrx4D[0][2] == 0.0 && dMtrx4D[1][0] == 0.0
768
&& dMtrx4D[1][2] == 0.0 && dMtrx4D[2][0] == 0.0 && dMtrx4D[2][1] == 0.0)
770
std::ostringstream stringStream;
771
stringStream << "Scale [" << dMtrx4D[0][0] << ", " << dMtrx4D[1][1] << ", "
772
<< dMtrx4D[2][2] << "]";
773
text = stringStream.str();
777
sub[0][0] = dMtrx4D[0][0];
778
sub[0][1] = dMtrx4D[0][1];
779
sub[0][2] = dMtrx4D[0][2];
780
sub[1][0] = dMtrx4D[1][0];
781
sub[1][1] = dMtrx4D[1][1];
782
sub[1][2] = dMtrx4D[1][2];
783
sub[2][0] = dMtrx4D[2][0];
784
sub[2][1] = dMtrx4D[2][1];
785
sub[2][2] = dMtrx4D[2][2];
787
Base::Matrix4D trp = sub;
791
for (unsigned short i = 0; i < 4 && ortho; i++) {
792
for (unsigned short j = 0; j < 4 && ortho; j++) {
794
if (fabs(trp[i][j]) > eps) {
802
double determinant = sub.determinant();
804
if (fabs(determinant - 1.0) < eps)
806
text = "Rotation Matrix";
809
if (fabs(determinant + 1.0) < eps)
811
text = "Rotinversion Matrix";
815
std::ostringstream stringStream;
816
stringStream << "Scale and Rotate ";
817
if (determinant < 0.0) {
818
stringStream << "and Invert ";
820
stringStream << "[ " << sqrt(trp[0][0]) << ", " << sqrt(trp[1][1])
821
<< ", " << sqrt(trp[2][2]) << "]";
822
text = stringStream.str();
827
std::ostringstream stringStream;
828
stringStream << "Affine with det= " << determinant;
829
text = stringStream.str();
833
if (hastranslation) {
834
text += " with Translation";
840
Matrix4D& Matrix4D::Outer(const Vector3f& rV1, const Vector3f& rV2)
844
Outer(convertTo<Vector3d>(rV1), convertTo<Vector3d>(rV2));
849
Matrix4D& Matrix4D::Outer(const Vector3d& rV1, const Vector3d& rV2)
853
dMtrx4D[0][0] = rV1.x * rV2.x;
854
dMtrx4D[0][1] = rV1.x * rV2.y;
855
dMtrx4D[0][2] = rV1.x * rV2.z;
857
dMtrx4D[1][0] = rV1.y * rV2.x;
858
dMtrx4D[1][1] = rV1.y * rV2.y;
859
dMtrx4D[1][2] = rV1.y * rV2.z;
861
dMtrx4D[2][0] = rV1.z * rV2.x;
862
dMtrx4D[2][1] = rV1.z * rV2.y;
863
dMtrx4D[2][2] = rV1.z * rV2.z;
868
Matrix4D& Matrix4D::Hat(const Vector3f& rV)
872
Hat(convertTo<Vector3d>(rV));
877
Matrix4D& Matrix4D::Hat(const Vector3d& rV)
882
dMtrx4D[0][1] = -rV.z;
883
dMtrx4D[0][2] = rV.y;
885
dMtrx4D[1][0] = rV.z;
887
dMtrx4D[1][2] = -rV.x;
889
dMtrx4D[2][0] = -rV.y;
890
dMtrx4D[2][1] = rV.x;
896
ScaleType Matrix4D::hasScale(double tol) const
898
const double defaultTolerance = 1e-9;
905
tol = defaultTolerance;
909
auto closeAbs = [&](double val_a, double val_b) {
910
double abs_a = fabs(val_a);
911
double abs_b = fabs(val_b);
913
return (abs_b - abs_a) / abs_b <= tol;
916
return (abs_a - abs_b) / abs_a <= tol;
922
double dx = getCol(0).Sqr();
923
double dy = getCol(1).Sqr();
924
double dz = getCol(2).Sqr();
925
double dxyz = sqrt(dx * dy * dz);
928
double du = getRow(0).Sqr();
929
double dv = getRow(1).Sqr();
930
double dw = getRow(2).Sqr();
931
double duvw = sqrt(du * dv * dw);
933
double d3 = determinant3();
936
if (!closeAbs(dxyz, d3) && !closeAbs(duvw, d3)) {
937
return ScaleType::Other;
940
if (closeAbs(duvw, d3) && (!closeAbs(du, dv) || !closeAbs(dv, dw))) {
941
return ScaleType::NonUniformLeft;
944
if (closeAbs(dxyz, d3) && (!closeAbs(dx, dy) || !closeAbs(dy, dz))) {
945
return ScaleType::NonUniformRight;
948
if (fabs(d3 - 1.0) > tol) {
949
return ScaleType::Uniform;
952
return ScaleType::NoScaling;
955
std::array<Matrix4D, 4> Matrix4D::decompose() const
961
Matrix4D rotationMatrix;
962
Matrix4D scaleMatrix;
963
Matrix4D residualMatrix(*this);
965
moveMatrix.move(residualMatrix.getCol(3));
966
residualMatrix.setCol(3, Vector3d());
969
std::array<Vector3d, 3> dirs = {Vector3d(1., 0., 0.),
970
Vector3d(0., 1., 0.),
971
Vector3d(0., 0., 1.)};
972
for (int i = 0; i < 3; i++) {
973
if (residualMatrix.getCol(i).IsNull()) {
977
dirs[i] = residualMatrix.getCol(i);
983
Vector3d cross = dirs[prim_dir].Cross(residualMatrix.getCol(i));
984
if (cross.IsNull()) {
988
int last_dir = 3 - i - prim_dir;
989
if (i - prim_dir == 1) {
990
dirs[last_dir] = cross;
991
dirs[i] = cross.Cross(dirs[prim_dir]);
994
dirs[last_dir] = -cross;
995
dirs[i] = dirs[prim_dir].Cross(-cross);
1000
if (prim_dir >= 0) {
1002
Vector3d cross = dirs[prim_dir].Cross(Vector3d(0., 0., 1.));
1003
if (cross.IsNull()) {
1004
cross = dirs[prim_dir].Cross(Vector3d(0., 1., 0.));
1006
dirs[(prim_dir + 1) % 3] = cross;
1007
dirs[(prim_dir + 2) % 3] = dirs[prim_dir].Cross(cross);
1009
rotationMatrix.setCol(0, dirs[0]);
1010
rotationMatrix.setCol(1, dirs[1]);
1011
rotationMatrix.setCol(2, dirs[2]);
1012
rotationMatrix.inverseGauss();
1013
residualMatrix = rotationMatrix * residualMatrix;
1015
if (residualMatrix.determinant() < 0) {
1016
rotationMatrix.rotZ(D_PI);
1017
residualMatrix.rotZ(D_PI);
1019
rotationMatrix.inverseGauss();
1021
double xScale = residualMatrix.dMtrx4D[0][0];
1022
double yScale = residualMatrix.dMtrx4D[1][1];
1023
double zScale = residualMatrix.dMtrx4D[2][2];
1024
scaleMatrix.dMtrx4D[0][0] = xScale;
1025
scaleMatrix.dMtrx4D[1][1] = yScale;
1026
scaleMatrix.dMtrx4D[2][2] = zScale;
1028
residualMatrix.scale(xScale != 0 ? 1.0 / xScale : 1.0,
1029
yScale != 0 ? 1.0 / yScale : 1.0,
1030
zScale != 0 ? 1.0 / zScale : 1.0);
1032
residualMatrix.setDiagonal(Vector3d(1.0, 1.0, 1.0));
1034
for (int i = 0; i < 3; i++) {
1035
if (std::abs(scaleMatrix.dMtrx4D[i][i]) < 1e-15) {
1036
scaleMatrix.dMtrx4D[i][i] = 0.0;
1038
for (int j = 0; j < 3; j++) {
1039
if (std::abs(residualMatrix.dMtrx4D[i][j]) < 1e-15) {
1040
residualMatrix.dMtrx4D[i][j] = 0.0;
1042
if (std::abs(rotationMatrix.dMtrx4D[i][j]) < 1e-15) {
1043
rotationMatrix.dMtrx4D[i][j] = 0.0;
1047
return std::array<Matrix4D, 4> {residualMatrix, scaleMatrix, rotationMatrix, moveMatrix};