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));
928 #ifdef MI_NEURAYLIB_DEPRECATED_5_0
934 inline void rotateaxis(
const Vector<Float64,3>& axis,
Float64 angle)
939 inline void multiply(
const Matrix<Float32,4,4>& matrix);
941 inline void multiply(
const Matrix<Float64,4,4>& matrix);
943 inline Vector<Float32,3>
transform(
const Vector<Float32,3> vector)
const;
945 inline Vector<Float64,3>
transform(
const Vector<Float64,3> vector)
const;
947 inline Vector<Float32,3> transform33(
const Vector<Float32,3> vector)
const;
949 inline Vector<Float64,3> transform33(
const Vector<Float64,3> vector)
const;
951 inline Vector<Float32,3> transform33t(
const Vector<Float32,3> vector)
const;
953 inline Vector<Float64,3> transform33t(
const Vector<Float64,3> vector)
const;
954 #endif // MI_NEURAYLIB_DEPRECATED_5_0
961 template <
typename T, Size ROW, Size COL>
970 template <
typename T, Size ROW, Size COL>
981 template <
typename T, Size ROW, Size COL>
992 template <
typename T, Size ROW, Size COL>
1003 template <
typename T, Size ROW, Size COL>
1014 template <
typename T, Size ROW, Size COL>
1025 template <
typename T, Size ROW, Size COL>
1026 Matrix<T,ROW,COL>&
operator+=( Matrix<T,ROW,COL>& lhs,
const Matrix<T,ROW,COL>& rhs);
1029 template <
typename T, Size ROW, Size COL>
1030 Matrix<T,ROW,COL>&
operator-=( Matrix<T,ROW,COL>& lhs,
const Matrix<T,ROW,COL>& rhs);
1033 template <
typename T, Size ROW, Size COL>
1044 template <
typename T, Size ROW, Size COL>
1055 template <
typename T, Size ROW, Size COL>
1060 for(
Size i(0u); i < (ROW*COL); ++i)
1071 template <
typename T, Size ROW, Size COL>
1079 for(
Size rrow = 0; rrow < ROW; ++rrow) {
1080 for(
Size rcol = 0; rcol < COL; ++rcol) {
1081 lhs( rrow, rcol) = T(0);
1082 for(
Size k = 0; k < COL; ++k)
1083 lhs( rrow, rcol) += old( rrow, k) * rhs( k, rcol);
1094 template <
typename T, Size ROW1, Size COL1, Size ROW2, Size COL2>
1103 for(
Size rrow = 0; rrow < ROW1; ++rrow) {
1104 for(
Size rcol = 0; rcol < COL2; ++rcol) {
1105 result( rrow, rcol) = T(0);
1106 for(
Size k = 0; k < COL1; ++k)
1107 result( rrow, rcol) += lhs( rrow, k) * rhs( k, rcol);
1120 template <
typename T, Size ROW, Size COL, Size DIM>
1127 for(
Size row = 0; row < ROW; ++row) {
1129 for(
Size col = 0; col < COL; ++col)
1130 result[row] += mat( row, col) * vec[col];
1141 template <Size DIM,
typename T, Size ROW, Size COL>
1148 for(
Size col = 0; col < COL; ++col) {
1150 for(
Size row = 0; row < ROW; ++row)
1151 result[col] += mat( row, col) * vec[row];
1158 template <
typename T, Size ROW, Size COL>
1161 for(
Size i=0; i < (ROW*COL); ++i)
1162 mat.
begin()[i] *= factor;
1167 template <
typename T, Size ROW, Size COL>
1176 template <
typename T, Size ROW, Size COL>
1190 template <Size NEW_ROW, Size NEW_COL,
typename T, Size ROW, Size COL>
1197 for(
Size i=0; i < NEW_ROW; ++i)
1198 for(
Size j=0; j < NEW_COL; ++j)
1199 result( i, j) = mat( i, j);
1206 template <
typename T, Size ROW, Size COL>
1211 for(
Size i=0; i < ROW; ++i)
1212 for(
Size j=0; j < COL; ++j)
1213 result( j, i) = mat( i, j);
1222 template <
typename T,
typename U>
1227 const T w = T(mat.xw * point + mat.ww);
1228 if( w == T(0) || w == T(1))
1229 return U(mat.xx * point + mat.wx);
1231 return U((mat.xx * point + mat.wx) / w);
1239 template <
typename T,
typename U>
1244 T w = T(mat.xw * point.x + mat.yw * point.y + mat.ww);
1245 if( w == T(0) || w == T(1))
1247 U(mat.xx * point.x + mat.yx * point.y + mat.wx),
1248 U(mat.xy * point.x + mat.yy * point.y + mat.wy));
1252 U((mat.xx * point.x + mat.yx * point.y + mat.wx) * w),
1253 U((mat.xy * point.x + mat.yy * point.y + mat.wy) * w));
1262 template <
typename T,
typename U>
1267 T w = T(mat.xw * point.x + mat.yw * point.y + mat.zw * point.z + mat.ww);
1268 if( w == T(0) || w == T(1))
1270 U(mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx),
1271 U(mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy),
1272 U(mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz));
1276 U((mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx) * w),
1277 U((mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy) * w),
1278 U((mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz) * w));
1287 template <
typename T,
typename U>
1293 U(mat.xx * point.x + mat.yx * point.y + mat.zx * point.z + mat.wx * point.w),
1294 U(mat.xy * point.x + mat.yy * point.y + mat.zy * point.z + mat.wy * point.w),
1295 U(mat.xz * point.x + mat.yz * point.y + mat.zz * point.z + mat.wz * point.w),
1296 U(mat.xw * point.x + mat.yw * point.y + mat.zw * point.z + mat.ww * point.w));
1304 template <
typename T,
typename U>
1309 return U(mat.xx * vector);
1317 template <
typename T,
typename U>
1323 U(mat.xx * vector.x + mat.yx * vector.y),
1324 U(mat.xy * vector.x + mat.yy * vector.y));
1332 template <
typename T,
typename U>
1338 U(mat.xx * vector.x + mat.yx * vector.y + mat.zx * vector.z),
1339 U(mat.xy * vector.x + mat.yy * vector.y + mat.zy * vector.z),
1340 U(mat.xz * vector.x + mat.yz * vector.y + mat.zz * vector.z));
1354 template <
typename T,
typename U>
1360 U(inv_mat.xx * normal.x + inv_mat.xy * normal.y + inv_mat.xz * normal.z),
1361 U(inv_mat.yx * normal.x + inv_mat.yy * normal.y + inv_mat.yz * normal.z),
1362 U(inv_mat.zx * normal.x + inv_mat.zy * normal.y + inv_mat.zz * normal.z));
1378 template <
typename T,
typename U>
1384 mat.yx, mat.yy, mat.yz,
1385 mat.zx, mat.zy, mat.zz);
1386 bool inverted = sub_mat.
invert();
1390 U(sub_mat.xx * normal.x + sub_mat.xy * normal.y + sub_mat.xz * normal.z),
1391 U(sub_mat.yx * normal.x + sub_mat.yy * normal.y + sub_mat.yz * normal.z),
1392 U(sub_mat.zx * normal.x + sub_mat.zy * normal.y + sub_mat.zz * normal.z));
1398 template <
typename T, Size ROW, Size COL>
1403 for(
Size i=0; i < ROW*COL; ++i)
1408 template <
typename T, Size ROW, Size COL>
1413 for(
Size i=0; i < ROW*COL; ++i)
1418 #ifndef MI_FOR_DOXYGEN_ONLY
1420 template <
typename T, Size ROW, Size COL>
1427 const T min_angle = T(0.00024f);
1429 if(
abs( xangle) > min_angle) {
1436 if(
abs( yangle) > min_angle) {
1443 if(
abs(zangle) > min_angle) {
1450 this->xx = tcy * tcz;
1451 this->xy = tcy * tsz;
1455 this->yx = tmp * tcz - tcx * tsz;
1456 this->yy = tmp * tsz + tcx * tcz;
1457 this->yz = tsx * tcy;
1460 this->zx = tmp * tcz + tsx * tsz;
1461 this->zy = tmp * tsz - tsx * tcz;
1462 this->zz = tcx * tcy;
1465 template <
typename T, Size ROW, Size COL>
1469 Vector<T,3> axis( axis_v);
1470 const T min_angle = T(0.00024f);
1472 if(
abs( T(angle)) < min_angle) {
1473 T xa = axis.x * T(angle);
1474 T ya = axis.y * T(angle);
1475 T za = axis.z * T(angle);
1492 T s =
sin( T(angle));
1493 T c =
cos( T(angle));
1497 tmp = t * T(axis.x);
1498 this->xx = tmp * T(axis.x) + c;
1499 this->xy = tmp * T(axis.y) + s * T(axis.z);
1500 this->xz = tmp * T(axis.z) - s * T(axis.y);
1503 tmp = t * T(axis.y);
1504 this->yx = tmp * T(axis.x) - s * T(axis.z);
1505 this->yy = tmp * T(axis.y) + c;
1506 this->yz = tmp * T(axis.z) + s * T(axis.x);
1509 tmp = t * T(axis.z);
1510 this->zx = tmp * T(axis.x) + s * T(axis.y);
1511 this->zy = tmp * T(axis.y) - s * T(axis.x);
1512 this->zz = tmp * T(axis.z) + c;
1515 this->wx = this->wy = this->wz = T(0);
1519 template <
typename T, Size ROW, Size COL>
1523 Vector<T,3> axis( axis_v);
1524 const T min_angle = T(0.00024f);
1526 if(
abs(T(angle)) < min_angle) {
1527 T xa = axis.x * T(angle);
1528 T ya = axis.y * T(angle);
1529 T za = axis.z * T(angle);
1546 T s =
sin( T(angle));
1547 T c =
cos( T(angle));
1551 tmp = t * T(axis.x);
1552 this->xx = tmp * T(axis.x) + c;
1553 this->xy = tmp * T(axis.y) + s * T(axis.z);
1554 this->xz = tmp * T(axis.z) - s * T(axis.y);
1557 tmp = t * T(axis.y);
1558 this->yx = tmp * T(axis.x) - s * T(axis.z);
1559 this->yy = tmp * T(axis.y) + c;
1560 this->yz = tmp * T(axis.z) + s * T(axis.x);
1563 tmp = t * T(axis.z);
1564 this->zx = tmp * T(axis.x) + s * T(axis.y);
1565 this->zy = tmp * T(axis.y) - s * T(axis.x);
1566 this->zz = tmp * T(axis.z) + c;
1569 this->wx = this->wy = this->wz = T(0);
1573 template <
typename T, Size ROW, Size COL>
1575 const Vector<Float32,3>& position,
1576 const Vector<Float32,3>& target,
1577 const Vector<Float32,3>& up)
1580 Vector<Float32,3> xaxis, yaxis, zaxis;
1583 zaxis = position - target;
1587 xaxis =
cross( up, zaxis);
1591 yaxis =
cross( zaxis, xaxis);
1596 T(xaxis.x), T(yaxis.x), T(zaxis.x), T(0),
1597 T(xaxis.y), T(yaxis.y), T(zaxis.y), T(0),
1598 T(xaxis.z), T(yaxis.z), T(zaxis.z), T(0),
1599 T(0), T(0), T(0), T(1));
1602 Matrix<T,4,4> trans(
1603 T(1), T(0), T(0), T(0),
1604 T(0), T(1), T(0), T(0),
1605 T(0), T(0), T(1), T(0),
1606 T(-position.x), T(-position.y), T(-position.z), T(1));
1608 *
this = trans * rot;
1611 template <
typename T, Size ROW, Size COL>
1613 const Vector<Float64,3>& position,
1614 const Vector<Float64,3>& target,
1615 const Vector<Float64,3>& up)
1618 Vector<Float64,3> xaxis, yaxis, zaxis;
1621 zaxis = position - target;
1625 xaxis =
cross( up, zaxis);
1629 yaxis =
cross( zaxis, xaxis);
1634 T(xaxis.x), T(yaxis.x), T(zaxis.x), T(0),
1635 T(xaxis.y), T(yaxis.y), T(zaxis.y), T(0),
1636 T(xaxis.z), T(yaxis.z), T(zaxis.z), T(0),
1637 T(0), T(0), T(0), T(1));
1640 Matrix<T,4,4> trans(
1641 T(1), T(0), T(0), T(0),
1642 T(0), T(1), T(0), T(0),
1643 T(0), T(0), T(1), T(0),
1644 T(-position.x), T(-position.y), T(-position.z), T(1));
1646 *
this = trans * rot;
1653 template <
class T, Size ROW, Size COL>
1654 class Matrix_inverter
1657 typedef math::Matrix<T,ROW,COL> Matrix;
1662 static inline bool invert( Matrix& ) {
return false; }
1666 template <
class T, Size DIM>
1667 class Matrix_inverter<T,DIM,DIM>
1670 typedef math::Matrix<T,DIM,DIM> Matrix;
1671 typedef math::Vector<T,DIM> Vector;
1672 typedef math::Vector<Size,DIM> Index_vector;
1678 static bool lu_decomposition(
1680 Index_vector& indx);
1684 static void lu_backsubstitution(
1686 const Index_vector& indx,
1689 static bool invert( Matrix& mat);
1692 template <
class T, Size DIM>
1693 bool Matrix_inverter<T,DIM,DIM>::lu_decomposition(
1699 for(
Size i = 0; i < DIM; i++) {
1701 for(
Size j = 0; j < DIM; j++) {
1702 T temp =
abs(lu.get(i,j));
1714 for(
Size j = 0; j < DIM; j++) {
1715 for(
Size i = 0; i < j; i++) {
1716 T sum = lu.get(i,j);
1717 for(
Size k = 0; k < i; k++)
1718 sum -= lu.get(i,k) * lu.get(k,j);
1722 for(
Size i = j; i < DIM; i++) {
1723 T sum = lu.get(i,j);
1724 for(
Size k = 0; k < j; k++)
1725 sum -= lu.get(i,k) * lu.get(k,j);
1727 T dum = vv[i] *
abs(sum);
1734 for(
Size k = 0; k < DIM; k++) {
1735 T dum = lu.get(imax,k);
1736 lu.set(imax, k, lu.get(j,k));
1742 if( lu.get(j,j) == 0)
1745 T dum = T(1) / lu.get(j,j);
1746 for(
Size i = j + 1; i < DIM; i++)
1747 lu.set(i, j, lu.get(i,j) * dum);
1753 template <
class T, Size DIM>
1754 void Matrix_inverter<T,DIM,DIM>::lu_backsubstitution(
1756 const Index_vector& indx,
1761 for(
Size i = 0; i < DIM; i++) {
1766 for(
Size j = ii; j < i; j++) {
1767 sum -= lu.get(i,j) * b[j];
1776 for(
Size i2 = DIM; i2 > 0;) {
1779 for(
Size j = i2+1; j < DIM; j++)
1780 sum -= lu.get(i2,j) * b[j];
1781 b[i2] = sum / lu.get(i2,i2);
1785 template <
class T, Size DIM>
1786 bool Matrix_inverter<T,DIM,DIM>::invert( Matrix& mat)
1792 if( !lu_decomposition(lu, indx))
1796 for(
Size j = 0; j < DIM; ++j) {
1799 lu_backsubstitution( lu, indx, col);
1800 for(
Size i = 0; i < DIM; ++i) {
1801 mat.set( i, j, col[i]);
1809 class Matrix_inverter<T,1,1>
1812 typedef math::Matrix<T,1,1> Matrix;
1814 static inline bool invert( Matrix& mat)
1816 T s = mat.get( 0, 0);
1819 mat.set( 0, 0, T(1) / s);
1826 class Matrix_inverter<T,2,2>
1829 typedef math::Matrix<T,2,2> Matrix;
1831 static inline bool invert( Matrix& mat)
1833 T a = mat.get( 0, 0);
1834 T b = mat.get( 0, 1);
1835 T c = mat.get( 1, 0);
1836 T d = mat.get( 1, 1);
1840 T rdet = T(1) / det;
1841 mat.set( 0, 0, d * rdet);
1842 mat.set( 0, 1,-b * rdet);
1843 mat.set( 1, 0,-c * rdet);
1844 mat.set( 1, 1, a * rdet);
1849 template <
typename T, Size ROW, Size COL>
1852 return Matrix_inverter<T,ROW,COL>::invert( *
this);
1860 template <
typename T>
1863 const Matrix<T,4,4>& rhs)
1865 Matrix<T,4,4> old( lhs);
1867 lhs.xx = old.xx * rhs.xx + old.xy * rhs.yx + old.xz * rhs.zx + old.xw * rhs.wx;
1868 lhs.xy = old.xx * rhs.xy + old.xy * rhs.yy + old.xz * rhs.zy + old.xw * rhs.wy;
1869 lhs.xz = old.xx * rhs.xz + old.xy * rhs.yz + old.xz * rhs.zz + old.xw * rhs.wz;
1870 lhs.xw = old.xx * rhs.xw + old.xy * rhs.yw + old.xz * rhs.zw + old.xw * rhs.ww;
1872 lhs.yx = old.yx * rhs.xx + old.yy * rhs.yx + old.yz * rhs.zx + old.yw * rhs.wx;
1873 lhs.yy = old.yx * rhs.xy + old.yy * rhs.yy + old.yz * rhs.zy + old.yw * rhs.wy;
1874 lhs.yz = old.yx * rhs.xz + old.yy * rhs.yz + old.yz * rhs.zz + old.yw * rhs.wz;
1875 lhs.yw = old.yx * rhs.xw + old.yy * rhs.yw + old.yz * rhs.zw + old.yw * rhs.ww;
1877 lhs.zx = old.zx * rhs.xx + old.zy * rhs.yx + old.zz * rhs.zx + old.zw * rhs.wx;
1878 lhs.zy = old.zx * rhs.xy + old.zy * rhs.yy + old.zz * rhs.zy + old.zw * rhs.wy;
1879 lhs.zz = old.zx * rhs.xz + old.zy * rhs.yz + old.zz * rhs.zz + old.zw * rhs.wz;
1880 lhs.zw = old.zx * rhs.xw + old.zy * rhs.yw + old.zz * rhs.zw + old.zw * rhs.ww;
1882 lhs.wx = old.wx * rhs.xx + old.wy * rhs.yx + old.wz * rhs.zx + old.ww * rhs.wx;
1883 lhs.wy = old.wx * rhs.xy + old.wy * rhs.yy + old.wz * rhs.zy + old.ww * rhs.wy;
1884 lhs.wz = old.wx * rhs.xz + old.wy * rhs.yz + old.wz * rhs.zz + old.ww * rhs.wz;
1885 lhs.ww = old.wx * rhs.xw + old.wy * rhs.yw + old.wz * rhs.zw + old.ww * rhs.ww;
1891 template <
typename T>
1893 const Matrix<T,4,4>& lhs,
1894 const Matrix<T,4,4>& rhs)
1896 Matrix<T,4,4> temp( lhs);
1901 #endif // MI_FOR_DOXYGEN_ONLY
1903 #ifdef MI_NEURAYLIB_DEPRECATED_5_0
1905 template <
typename T, Size ROW, Size COL>
1906 inline void Matrix<T,ROW,COL>::multiply(
const Matrix<Float32,4,4>& matrix)
1909 (*this) *= Matrix<T,ROW,COL> (matrix);
1912 template <
typename T, Size ROW, Size COL>
1913 inline void Matrix<T,ROW,COL>::multiply(
const Matrix<Float64,4,4>& matrix)
1916 (*this) *= Matrix<T,ROW,COL>( matrix);
1919 template <
typename T, Size ROW, Size COL>
1926 template <
typename T, Size ROW, Size COL>
1933 template <
typename T, Size ROW, Size COL>
1934 inline Vector<Float32,3> Matrix<T,ROW,COL>::transform33(
const Vector<Float32,3> vector)
const
1940 template <
typename T, Size ROW, Size COL>
1941 inline Vector<Float64,3> Matrix<T,ROW,COL>::transform33(
const Vector<Float64,3> vector)
const
1947 template <
typename T, Size ROW, Size COL>
1948 inline Vector<Float32,3> Matrix<T,ROW,COL>::transform33t(
const Vector<Float32,3> vector)
const
1954 template <
typename T, Size ROW, Size COL>
1955 inline Vector<Float64,3> Matrix<T,ROW,COL>::transform33t(
const Vector<Float64,3> vector)
const
1961 #endif // MI_NEURAYLIB_DEPRECATED_5_0
1969 #endif // MI_MATH_MATRIX_H