11 #ifndef MI_MATH_MATRIX_H
12 #define MI_MATH_MATRIX_H
88 template <
typename T, Size ROW, Size COL>
278 template <
typename T,
class Matrix,
bool specialized>
279 struct Matrix_struct_get_base_pointer
282 static inline const T* get_base_ptr(
const Matrix& m) {
return m.elements; }
287 template <
typename T,
class Matrix>
288 struct Matrix_struct_get_base_pointer<T,Matrix,true>
290 static inline T* get_base_ptr( Matrix& m) {
return &m.xx; }
291 static inline const T* get_base_ptr(
const Matrix& m) {
return &m.xx; }
296 template <
typename T, Size ROW, Size COL>
299 return Matrix_struct_get_base_pointer<T,Matrix_struct<T,ROW,COL>,
300 (ROW<=4 && COL<=4)>::get_base_ptr( mat);
304 template <
typename T, Size ROW, Size COL>
307 return Matrix_struct_get_base_pointer<T,Matrix_struct<T,ROW,COL>,
308 (ROW<=4 && COL<=4)>::get_base_ptr( mat);
364 template <
typename T, Size ROW, Size COL>
439 for(
Size i(0u); i < ROW * COL; ++i)
450 const Size MIN_DIM = (ROW < COL) ? ROW : COL;
451 for(
Size k(0u); k < MIN_DIM; ++k)
452 begin()[k * COL + k] = diag;
468 template <
typename Iterator>
471 for(
Size i(0u); i <
SIZE; ++i, ++p)
487 template <
typename T2>
491 begin()[i] = array[i];
496 template <
typename T2>
508 for(
Size i(0u); i < ROW; ++i)
509 for(
Size j(0u); j < COL; ++j)
510 begin()[i * COL + j] = other.
begin()[j * ROW + i];
516 template <
typename T2>
521 for(
Size i(0u); i < ROW; ++i)
522 for(
Size j(0u); j < COL; ++j)
523 begin()[i * COL + j] = T(other.
begin()[j * ROW + i]);
612 inline Matrix( T m0, T m1, T m2, T m3, T m4, T m5)
622 inline Matrix( T m0, T m1, T m2, T m3, T m4, T m5, T m6, T m7)
632 inline Matrix( T m0, T m1, T m2, T m3, T m4, T m5, T m6, T m7, T m8)
644 T m0, T m1, T m2, T m3,
645 T m4, T m5, T m6, T m7,
646 T m8, T m9, T m10, T m11)
658 T m0, T m1, T m2, T m3,
659 T m4, T m5, T m6, T m7,
660 T m8, T m9, T m10, T m11,
661 T m12, T m13, T m14, T m15)
684 return begin()[row * COL + col];
694 return begin()[row * COL + col];
713 return begin()[row * COL + col];
734 begin()[row * COL + col] = value;
743 return this->xx * this->yy * this->zz
744 + this->xy * this->yz * this->zx
745 + this->xz * this->yx * this->zy
746 - this->xx * this->zy * this->yz
747 - this->xy * this->zz * this->yx
748 - this->xz * this->zx * this->yy;
764 for(
Size i=0; i < ROW-1; ++i) {
765 for(
Size j=i+1; j < COL; ++j) {
788 this->wx += T( vector.x);
789 this->wy += T( vector.y);
790 this->wz += T( vector.z);
798 this->wx += T( vector.x);
799 this->wy += T( vector.y);
800 this->wz += T( vector.z);
818 this->wx = T( vector.x);
819 this->wy = T( vector.y);
820 this->wz = T( vector.z);
828 this->wx = T( vector.x);
829 this->wy = T( vector.y);
830 this->wz = T( vector.z);
837 inline void rotate( T xangle, T yangle, T zangle)
851 tmp.
set_rotation( T( angles.x), T( angles.y), T( angles.z));
862 tmp.
set_rotation( T( angles.x), T( angles.y), T( angles.z));
871 inline void set_rotation( T x_angle, T y_angle, T z_angle);
880 set_rotation( T( angles.x), T( angles.y), T( angles.z));
890 set_rotation( T( angles.x), T( angles.y), T( angles.z));
933 template <
typename T, Size ROW, Size COL>
942 template <
typename T, Size ROW, Size COL>
953 template <
typename T, Size ROW, Size COL>
964 template <
typename T, Size ROW, Size COL>
975 template <
typename T, Size ROW, Size COL>
986 template <
typename T, Size ROW, Size COL>
997 template <
typename T, Size ROW, Size COL>
998 Matrix<T,ROW,COL>&
operator+=( Matrix<T,ROW,COL>& lhs,
const Matrix<T,ROW,COL>& rhs);
1001 template <
typename T, Size ROW, Size COL>
1002 Matrix<T,ROW,COL>&
operator-=( Matrix<T,ROW,COL>& lhs,
const Matrix<T,ROW,COL>& rhs);
1005 template <
typename T, Size ROW, Size COL>
1016 template <
typename T, Size ROW, Size COL>
1027 template <
typename T, Size ROW, Size COL>
1032 for(
Size i(0u); i < (ROW*COL); ++i)
1043 template <
typename T, Size ROW, Size COL>
1051 for(
Size rrow = 0; rrow < ROW; ++rrow) {
1052 for(
Size rcol = 0; rcol < COL; ++rcol) {
1053 lhs( rrow, rcol) = T(0);
1054 for(
Size k = 0; k < COL; ++k)
1055 lhs( rrow, rcol) += old( rrow, k) * rhs( k, rcol);
1066 template <
typename T, Size ROW1, Size COL1, Size ROW2, Size COL2>
1075 for(
Size rrow = 0; rrow < ROW1; ++rrow) {
1076 for(
Size rcol = 0; rcol < COL2; ++rcol) {
1077 result( rrow, rcol) = T(0);
1078 for(
Size k = 0; k < COL1; ++k)
1079 result( rrow, rcol) += lhs( rrow, k) * rhs( k, rcol);
1092 template <
typename T, Size ROW, Size COL, Size DIM>
1099 for(
Size row = 0; row < ROW; ++row) {
1101 for(
Size col = 0; col < COL; ++col)
1102 result[row] += mat( row, col) * vec[col];
1113 template <Size DIM,
typename T, Size ROW, Size COL>
1120 for(
Size col = 0; col < COL; ++col) {
1122 for(
Size row = 0; row < ROW; ++row)
1123 result[col] += mat( row, col) * vec[row];
1130 template <
typename T, Size ROW, Size COL>
1133 for(
Size i=0; i < (ROW*COL); ++i)
1134 mat.
begin()[i] *= factor;
1139 template <
typename T, Size ROW, Size COL>
1148 template <
typename T, Size ROW, Size COL>
1162 template <Size NEW_ROW, Size NEW_COL,
typename T, Size ROW, Size COL>
1169 for(
Size i=0; i < NEW_ROW; ++i)
1170 for(
Size j=0; j < NEW_COL; ++j)
1171 result( i, j) = mat( i, j);
1178 template <
typename T, Size ROW, Size COL>
1183 for(
Size i=0; i < ROW; ++i)
1184 for(
Size j=0; j < COL; ++j)
1185 result( j, i) = mat( i, j);
1194 template <
typename T,
typename U>
1199 const T w = T(mat.xw * point + mat.ww);
1200 if( w == T(0) || w == T(1))
1201 return U(mat.xx * point + mat.wx);
1203 return U((mat.xx * point + mat.wx) / w);
1211 template <
typename T,
typename U>
1216 T w = T(mat.xw * point.x + mat.yw * point.y + mat.ww);
1217 if( w == T(0) || w == T(1))
1219 U(mat.xx * point.x + mat.yx * point.y + mat.wx),
1220 U(mat.xy * point.x + mat.yy * point.y + mat.wy));
1224 U((mat.xx * point.x + mat.yx * point.y + mat.wx) * w),
1225 U((mat.xy * point.x + mat.yy * point.y + mat.wy) * w));
1234 template <
typename T,
typename U>
1239 T w = T(mat.xw * point.x + mat.yw * point.y + mat.zw * point.z + mat.ww);
1240 if( w == T(0) || w == T(1))
1242 U(mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx),
1243 U(mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy),
1244 U(mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz));
1248 U((mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx) * w),
1249 U((mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy) * w),
1250 U((mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz) * w));
1259 template <
typename T,
typename U>
1265 U(mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx * point.w),
1266 U(mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy * point.w),
1267 U(mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz * point.w),
1268 U(mat.xw * point.x + mat.yw * point.y + mat.zw * point.z + mat.ww * point.w));
1276 template <
typename T,
typename U>
1281 return U(mat.xx * vector);
1289 template <
typename T,
typename U>
1295 U(mat.xx * vector.x + mat.yx * vector.y),
1296 U(mat.xy * vector.x + mat.yy * vector.y));
1304 template <
typename T,
typename U>
1310 U(mat.xx * vector.x + mat.yx * vector.y + mat.zx * vector.z),
1311 U(mat.xy * vector.x + mat.yy * vector.y + mat.zy * vector.z),
1312 U(mat.xz * vector.x + mat.yz * vector.y + mat.zz * vector.z));
1326 template <
typename T,
typename U>
1332 U(inv_mat.xx * normal.x + inv_mat.xy * normal.y + inv_mat.xz * normal.z),
1333 U(inv_mat.yx * normal.x + inv_mat.yy * normal.y + inv_mat.yz * normal.z),
1334 U(inv_mat.zx * normal.x + inv_mat.zy * normal.y + inv_mat.zz * normal.z));
1350 template <
typename T,
typename U>
1356 mat.yx, mat.yy, mat.yz,
1357 mat.zx, mat.zy, mat.zz);
1358 bool inverted = sub_mat.
invert();
1362 U(sub_mat.xx * normal.x + sub_mat.xy * normal.y + sub_mat.xz * normal.z),
1363 U(sub_mat.yx * normal.x + sub_mat.yy * normal.y + sub_mat.yz * normal.z),
1364 U(sub_mat.zx * normal.x + sub_mat.zy * normal.y + sub_mat.zz * normal.z));
1370 template <
typename T, Size ROW, Size COL>
1375 for(
Size i=0; i < ROW*COL; ++i)
1380 template <
typename T, Size ROW, Size COL>
1385 for(
Size i=0; i < ROW*COL; ++i)
1390 #ifndef MI_FOR_DOXYGEN_ONLY
1392 template <
typename T, Size ROW, Size COL>
1399 const T min_angle = T(0.00024f);
1401 if(
abs( xangle) > min_angle) {
1408 if(
abs( yangle) > min_angle) {
1415 if(
abs(zangle) > min_angle) {
1422 this->xx = tcy * tcz;
1423 this->xy = tcy * tsz;
1427 this->yx = tmp * tcz - tcx * tsz;
1428 this->yy = tmp * tsz + tcx * tcz;
1429 this->yz = tsx * tcy;
1432 this->zx = tmp * tcz + tsx * tsz;
1433 this->zy = tmp * tsz - tsx * tcz;
1434 this->zz = tcx * tcy;
1437 template <
typename T, Size ROW, Size COL>
1441 Vector<T,3> axis( axis_v);
1442 const T min_angle = T(0.00024f);
1444 if(
abs( T(angle)) < min_angle) {
1445 T xa = axis.x * T(angle);
1446 T ya = axis.y * T(angle);
1447 T za = axis.z * T(angle);
1464 T s =
sin( T(angle));
1465 T c =
cos( T(angle));
1469 tmp = t * T(axis.x);
1470 this->xx = tmp * T(axis.x) + c;
1471 this->xy = tmp * T(axis.y) + s * T(axis.z);
1472 this->xz = tmp * T(axis.z) - s * T(axis.y);
1475 tmp = t * T(axis.y);
1476 this->yx = tmp * T(axis.x) - s * T(axis.z);
1477 this->yy = tmp * T(axis.y) + c;
1478 this->yz = tmp * T(axis.z) + s * T(axis.x);
1481 tmp = t * T(axis.z);
1482 this->zx = tmp * T(axis.x) + s * T(axis.y);
1483 this->zy = tmp * T(axis.y) - s * T(axis.x);
1484 this->zz = tmp * T(axis.z) + c;
1487 this->wx = this->wy = this->wz = T(0);
1491 template <
typename T, Size ROW, Size COL>
1495 Vector<T,3> axis( axis_v);
1496 const T min_angle = T(0.00024f);
1498 if(
abs(T(angle)) < min_angle) {
1499 T xa = axis.x * T(angle);
1500 T ya = axis.y * T(angle);
1501 T za = axis.z * T(angle);
1518 T s =
sin( T(angle));
1519 T c =
cos( T(angle));
1523 tmp = t * T(axis.x);
1524 this->xx = tmp * T(axis.x) + c;
1525 this->xy = tmp * T(axis.y) + s * T(axis.z);
1526 this->xz = tmp * T(axis.z) - s * T(axis.y);
1529 tmp = t * T(axis.y);
1530 this->yx = tmp * T(axis.x) - s * T(axis.z);
1531 this->yy = tmp * T(axis.y) + c;
1532 this->yz = tmp * T(axis.z) + s * T(axis.x);
1535 tmp = t * T(axis.z);
1536 this->zx = tmp * T(axis.x) + s * T(axis.y);
1537 this->zy = tmp * T(axis.y) - s * T(axis.x);
1538 this->zz = tmp * T(axis.z) + c;
1541 this->wx = this->wy = this->wz = T(0);
1545 template <
typename T, Size ROW, Size COL>
1547 const Vector<Float32,3>& position,
1548 const Vector<Float32,3>& target,
1549 const Vector<Float32,3>& up)
1552 Vector<Float32,3> xaxis, yaxis, zaxis;
1555 zaxis = position - target;
1559 xaxis =
cross( up, zaxis);
1563 yaxis =
cross( zaxis, xaxis);
1568 T(xaxis.x), T(yaxis.x), T(zaxis.x), T(0),
1569 T(xaxis.y), T(yaxis.y), T(zaxis.y), T(0),
1570 T(xaxis.z), T(yaxis.z), T(zaxis.z), T(0),
1571 T(0), T(0), T(0), T(1));
1574 Matrix<T,4,4> trans(
1575 T(1), T(0), T(0), T(0),
1576 T(0), T(1), T(0), T(0),
1577 T(0), T(0), T(1), T(0),
1578 T(-position.x), T(-position.y), T(-position.z), T(1));
1580 *
this = trans * rot;
1583 template <
typename T, Size ROW, Size COL>
1585 const Vector<Float64,3>& position,
1586 const Vector<Float64,3>& target,
1587 const Vector<Float64,3>& up)
1590 Vector<Float64,3> xaxis, yaxis, zaxis;
1593 zaxis = position - target;
1597 xaxis =
cross( up, zaxis);
1601 yaxis =
cross( zaxis, xaxis);
1606 T(xaxis.x), T(yaxis.x), T(zaxis.x), T(0),
1607 T(xaxis.y), T(yaxis.y), T(zaxis.y), T(0),
1608 T(xaxis.z), T(yaxis.z), T(zaxis.z), T(0),
1609 T(0), T(0), T(0), T(1));
1612 Matrix<T,4,4> trans(
1613 T(1), T(0), T(0), T(0),
1614 T(0), T(1), T(0), T(0),
1615 T(0), T(0), T(1), T(0),
1616 T(-position.x), T(-position.y), T(-position.z), T(1));
1618 *
this = trans * rot;
1625 template <
class T, Size ROW, Size COL>
1626 class Matrix_inverter
1629 typedef math::Matrix<T,ROW,COL> Matrix;
1634 static inline bool invert( Matrix& ) {
return false; }
1638 template <
class T, Size DIM>
1639 class Matrix_inverter<T,DIM,DIM>
1642 typedef math::Matrix<T,DIM,DIM> Matrix;
1643 typedef math::Vector<T,DIM> Vector;
1644 typedef math::Vector<Size,DIM> Index_vector;
1650 static bool lu_decomposition(
1652 Index_vector& indx);
1656 static void lu_backsubstitution(
1658 const Index_vector& indx,
1661 static bool invert( Matrix& mat);
1664 template <
class T, Size DIM>
1665 bool Matrix_inverter<T,DIM,DIM>::lu_decomposition(
1671 for(
Size i = 0; i < DIM; i++) {
1673 for(
Size j = 0; j < DIM; j++) {
1674 T temp =
abs(lu.get(i,j));
1686 for(
Size j = 0; j < DIM; j++) {
1687 for(
Size i = 0; i < j; i++) {
1688 T sum = lu.get(i,j);
1689 for(
Size k = 0; k < i; k++)
1690 sum -= lu.get(i,k) * lu.get(k,j);
1694 for(
Size i = j; i < DIM; i++) {
1695 T sum = lu.get(i,j);
1696 for(
Size k = 0; k < j; k++)
1697 sum -= lu.get(i,k) * lu.get(k,j);
1699 T dum = vv[i] *
abs(sum);
1706 for(
Size k = 0; k < DIM; k++) {
1707 T dum = lu.get(imax,k);
1708 lu.set(imax, k, lu.get(j,k));
1714 if( lu.get(j,j) == 0)
1717 T dum = T(1) / lu.get(j,j);
1718 for(
Size i = j + 1; i < DIM; i++)
1719 lu.set(i, j, lu.get(i,j) * dum);
1725 template <
class T, Size DIM>
1726 void Matrix_inverter<T,DIM,DIM>::lu_backsubstitution(
1728 const Index_vector& indx,
1733 for(
Size i = 0; i < DIM; i++) {
1738 for(
Size j = ii; j < i; j++) {
1739 sum -= lu.get(i,j) * b[j];
1748 for(
Size i2 = DIM; i2 > 0;) {
1751 for(
Size j = i2+1; j < DIM; j++)
1752 sum -= lu.get(i2,j) * b[j];
1753 b[i2] = sum / lu.get(i2,i2);
1757 template <
class T, Size DIM>
1758 bool Matrix_inverter<T,DIM,DIM>::invert( Matrix& mat)
1764 if( !lu_decomposition(lu, indx))
1768 for(
Size j = 0; j < DIM; ++j) {
1771 lu_backsubstitution( lu, indx, col);
1772 for(
Size i = 0; i < DIM; ++i) {
1773 mat.set( i, j, col[i]);
1781 class Matrix_inverter<T,1,1>
1784 typedef math::Matrix<T,1,1> Matrix;
1786 static inline bool invert( Matrix& mat)
1788 T s = mat.get( 0, 0);
1791 mat.set( 0, 0, T(1) / s);
1798 class Matrix_inverter<T,2,2>
1801 typedef math::Matrix<T,2,2> Matrix;
1803 static inline bool invert( Matrix& mat)
1805 T a = mat.get( 0, 0);
1806 T b = mat.get( 0, 1);
1807 T c = mat.get( 1, 0);
1808 T d = mat.get( 1, 1);
1812 T rdet = T(1) / det;
1813 mat.set( 0, 0, d * rdet);
1814 mat.set( 0, 1,-b * rdet);
1815 mat.set( 1, 0,-c * rdet);
1816 mat.set( 1, 1, a * rdet);
1821 template <
typename T, Size ROW, Size COL>
1824 return Matrix_inverter<T,ROW,COL>::invert( *
this);
1832 template <
typename T>
1835 const Matrix<T,4,4>& rhs)
1837 Matrix<T,4,4> old( lhs);
1839 lhs.xx = old.xx * rhs.xx + old.xy * rhs.yx + old.xz * rhs.zx + old.xw * rhs.wx;
1840 lhs.xy = old.xx * rhs.xy + old.xy * rhs.yy + old.xz * rhs.zy + old.xw * rhs.wy;
1841 lhs.xz = old.xx * rhs.xz + old.xy * rhs.yz + old.xz * rhs.zz + old.xw * rhs.wz;
1842 lhs.xw = old.xx * rhs.xw + old.xy * rhs.yw + old.xz * rhs.zw + old.xw * rhs.ww;
1844 lhs.yx = old.yx * rhs.xx + old.yy * rhs.yx + old.yz * rhs.zx + old.yw * rhs.wx;
1845 lhs.yy = old.yx * rhs.xy + old.yy * rhs.yy + old.yz * rhs.zy + old.yw * rhs.wy;
1846 lhs.yz = old.yx * rhs.xz + old.yy * rhs.yz + old.yz * rhs.zz + old.yw * rhs.wz;
1847 lhs.yw = old.yx * rhs.xw + old.yy * rhs.yw + old.yz * rhs.zw + old.yw * rhs.ww;
1849 lhs.zx = old.zx * rhs.xx + old.zy * rhs.yx + old.zz * rhs.zx + old.zw * rhs.wx;
1850 lhs.zy = old.zx * rhs.xy + old.zy * rhs.yy + old.zz * rhs.zy + old.zw * rhs.wy;
1851 lhs.zz = old.zx * rhs.xz + old.zy * rhs.yz + old.zz * rhs.zz + old.zw * rhs.wz;
1852 lhs.zw = old.zx * rhs.xw + old.zy * rhs.yw + old.zz * rhs.zw + old.zw * rhs.ww;
1854 lhs.wx = old.wx * rhs.xx + old.wy * rhs.yx + old.wz * rhs.zx + old.ww * rhs.wx;
1855 lhs.wy = old.wx * rhs.xy + old.wy * rhs.yy + old.wz * rhs.zy + old.ww * rhs.wy;
1856 lhs.wz = old.wx * rhs.xz + old.wy * rhs.yz + old.wz * rhs.zz + old.ww * rhs.wz;
1857 lhs.ww = old.wx * rhs.xw + old.wy * rhs.yw + old.wz * rhs.zw + old.ww * rhs.ww;
1863 template <
typename T>
1865 const Matrix<T,4,4>& lhs,
1866 const Matrix<T,4,4>& rhs)
1868 Matrix<T,4,4> temp( lhs);
1873 #endif // MI_FOR_DOXYGEN_ONLY
1881 #endif // MI_MATH_MATRIX_H