14#ifndef MOMENTUM_MATRIX3X3_H
15#define MOMENTUM_MATRIX3X3_H
17#include "momentum_export.h"
18#include <momentum_namespace.h>
26#include <agx/Prefetch.h>
30#include <agx/Matrix3x3.h>
36#define MOMENTUM_MATRIX3X3_SET_ROW(row, v1, v2, v3) \
37 m_data[(row)][0] = (v1); \
38 m_data[(row)][1] = (v2); \
39 m_data[(row)][2] = (v3);
41#define MOMENTUM_MATRIX3X3_INNER_PRODUCT(a,b,r,c) \
42 ((a).m_data[r][0] * (b).m_data[0][c]) \
43 +((a).m_data[r][1] * (b).m_data[1][c]) \
44 +((a).m_data[r][2] * (b).m_data[2][c])
46#define MOMENTUM_MATRIX3X3_DET2(a, b, c, d) ((a)*(d) - (b)*(c))
61 operator agx::Matrix3x3()
const
65 this->m_data[0][0], this->m_data[0][1], this->m_data[0][2],
66 this->m_data[1][0], this->m_data[1][1], this->m_data[1][2],
67 this->m_data[2][0], this->m_data[2][1], this->m_data[2][2]
74 for (
auto i = 0; i < 3; i++)
75 for (
auto j = 0; j < 3; j++)
76 this->m_data[i][j] = mat(i, j);
96 Matrix3x3(
double a00,
double a01,
double a02,
97 double a10,
double a11,
double a12,
98 double a20,
double a21,
double a22);
121 bool isFinite()
const;
126 bool isIdentity()
const;
131 bool isRigidTransformation()
const;
155 Matrix3x3 set(
double const *
const ptr );
156 Matrix3x3 set(
double a00,
double a01,
double a02,
157 double a10,
double a11,
double a12,
158 double a20,
double a21,
double a22);
167 m_data[row][0] = vec[0];
168 m_data[row][1] = vec[1];
169 m_data[row][2] = vec[2];
173 m_data[0][col] = vec[0];
174 m_data[1][col] = vec[1];
175 m_data[2][col] = vec[2];
196 double at(
size_t row,
size_t col)
const
198 return m_data[row][col];
205 Matrix3x3 setRotate(
double angle,
double x,
double y,
double z );
207 double angle2,
const Vec3& axis2,
208 double angle3,
const Vec3& axis3 );
216 Quat getRotate()
const;
226 const double *ptr()
const;
237 static Matrix3x3 rotate(
double angle,
double x,
double y,
double z );
240 double angle2,
const Vec3& axis2,
241 double angle3,
const Vec3& axis3 );
246 Vec3 operator* (
const Vec3& v )
const;
248 void operator*= (
const Matrix3x3& other );
250 bool operator== (
const Matrix3x3& m )
const;
251 bool operator!= (
const Matrix3x3& m )
const;
253 double& operator()(
size_t row,
size_t col);
256 double operator()(
size_t row,
size_t col)
const;
268 std::string __str__()
const;
275 bool isDiagonal()
const;
276 double determinant()
const;
305 m_data[0][0] = mat(0, 0);
306 m_data[0][1] = mat(0, 1);
307 m_data[0][2] = mat(0, 2);
309 m_data[1][0] = mat(1, 0);
310 m_data[1][1] = mat(1, 1);
311 m_data[1][2] = mat(1, 2);
313 m_data[2][0] = mat(2, 0);
314 m_data[2][1] = mat(2, 1);
315 m_data[2][2] = mat(2, 2);
319 double a10,
double a11,
double a12,
320 double a20,
double a21,
double a22)
365 return std::isnan( m_data[0][0] ) || std::isnan( m_data[0][1] )
366 || std::isnan( m_data[0][2] )
367 || std::isnan( m_data[1][0] ) || std::isnan( m_data[1][1] )
368 || std::isnan( m_data[1][2] )
369 || std::isnan( m_data[2][0] ) || std::isnan( m_data[2][1] )
370 || std::isnan( m_data[2][2] );
377 return std::isfinite( m_data[0][0] ) && std::isfinite( m_data[0][1] )
378 && std::isfinite( m_data[0][2] )
379 && std::isfinite( m_data[1][0] ) && std::isfinite( m_data[1][1] )
380 && std::isfinite( m_data[1][2] )
381 && std::isfinite( m_data[2][0] ) && std::isfinite( m_data[2][1] )
382 && std::isfinite( m_data[2][2] );
396 isRigid &=
equivalent(m_data[0][0]*m_data[0][0] + m_data[0][1]*m_data[0][1] + m_data[0][2]*m_data[0][2],
double(1),
double(1.0e-3));
397 isRigid &=
equivalent(m_data[1][0]*m_data[1][0] + m_data[1][1]*m_data[1][1] + m_data[1][2]*m_data[1][2],
double(1),
double(1.0e-3));
398 isRigid &=
equivalent(m_data[2][0]*m_data[2][0] + m_data[2][1]*m_data[2][1] + m_data[2][2]*m_data[2][2],
double(1),
double(1.0e-3));
400 isRigid &=
equivalent(m_data[0][0]*m_data[0][0] + m_data[1][0]*m_data[1][0] + m_data[2][0]*m_data[2][0],
double(1),
double(1.0e-3));
401 isRigid &=
equivalent(m_data[0][1]*m_data[0][1] + m_data[1][1]*m_data[1][1] + m_data[2][1]*m_data[2][1],
double(1),
double(1.0e-3));
402 isRigid &=
equivalent(m_data[0][2]*m_data[0][2] + m_data[1][2]*m_data[1][2] + m_data[2][2]*m_data[2][2],
double(1),
double(1.0e-3));
404 isRigid &=
equivalent(m_data[0][0]*m_data[1][1]*m_data[2][2] + m_data[0][1]*m_data[1][2]*m_data[2][0] + m_data[0][2]*m_data[1][0]*m_data[2][1]
405 - m_data[2][0]*m_data[1][1]*m_data[0][2] - m_data[1][0]*m_data[0][1]*m_data[2][2] - m_data[0][0]*m_data[2][1]*m_data[1][2],
406 double(1),
double(1.0e-1));
418 memcpy(m_data,
ptr,
sizeof(
double)*9);
425 double a10,
double a11,
double a12,
426 double a20,
double a21,
double a22)
472 double angle2,
const Vec3& axis2,
473 double angle3,
const Vec3& axis3 )
488 if (length2 != 1.0 && length2 != 0.0)
491 q /= agx::Quat::Type(std::sqrt(length2));
498 double wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
522 m_data[0][0] = (1.0 - (yy + zz));
523 m_data[1][0] = (xy - wz);
524 m_data[2][0] = (xz + wy);
527 m_data[0][1] = (xy + wz);
528 m_data[1][1] = (1.0 - (xx + zz));
529 m_data[2][1] = (yz - wx);
532 m_data[0][2] = (xz - wy);
533 m_data[1][2] = (yz + wx);
534 m_data[2][2] = (1.0 - (xx + yy));
542 this->
set(1,0,0, 0,1,0, 0,0,1);
559 return (
double* )m_data;
565 return (
const double * )m_data;
609 double angle2,
const Vec3& axis2,
610 double angle3,
const Vec3& axis3 )
613 m.
setRotate(angle1, axis1, angle2, axis2, angle3, axis3);
625 agx::prefetch<agx::L1>( lhs.m_data );
626 agx::prefetch<agx::L1>( rhs.m_data );
639 m_data[0][0] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 0, 0);
640 m_data[0][1] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 0, 1);
641 m_data[0][2] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 0, 2);
643 m_data[1][0] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 1, 0);
644 m_data[1][1] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 1, 1);
645 m_data[1][2] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 1, 2);
647 m_data[2][0] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 2, 0);
648 m_data[2][1] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 2, 1);
649 m_data[2][2] = MOMENTUM_MATRIX3X3_INNER_PRODUCT(lhs, rhs, 2, 2);
659 for(
size_t col=0; col<3; ++col) {
660 t[0] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( other, *
this, 0, col );
661 t[1] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( other, *
this, 1, col );
662 t[2] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( other, *
this, 2, col );
663 m_data[0][col] = t[0];
664 m_data[1][col] = t[1];
665 m_data[2][col] = t[2];
675 for(
size_t row=0; row<3; ++row)
677 t[0] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( *
this, other, row, 0 );
678 t[1] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( *
this, other, row, 1 );
679 t[2] = MOMENTUM_MATRIX3X3_INNER_PRODUCT( *
this, other, row, 2 );
681 MOMENTUM_MATRIX3X3_SET_ROW(row, t[0], t[1], t[2])
687 const int bitCompare = memcmp(m_data, m.m_data,
sizeof(m_data));
688 return (bitCompare == 0);
694 const int bitCompare = memcmp(m_data, m.m_data,
sizeof(m_data));
695 return (bitCompare != 0);
702 return m_data[row][col];
709 return m_data[row][col];
724 if (
this == &other )
759 return Vec3( ( m_data[0][0]*v.
x() + m_data[0][1]*v.
y() + m_data[0][2]*v.
z() ) ,
760 ( m_data[1][0]*v.
x() + m_data[1][1]*v.
y() + m_data[1][2]*v.
z() ) ,
761 ( m_data[2][0]*v.
x() + m_data[2][1]*v.
y() + m_data[2][2]*v.
z() ) ) ;
768 return Matrix3x3( m_data[0][0], m_data[1][0], m_data[2][0],
769 m_data[0][1], m_data[1][1], m_data[2][1],
770 m_data[0][2], m_data[1][2], m_data[2][2]);
773 inline double Matrix3x3::determinant()
const
775 return m_data[0][0] * m_data[1][1] * m_data[2][2] - m_data[0][0] * m_data[1][2] * m_data[2][1] -
776 m_data[0][1] * m_data[1][0] * m_data[2][2] + m_data[0][1] * m_data[1][2] * m_data[2][0] +
777 m_data[0][2] * m_data[1][0] * m_data[2][1] - m_data[0][2] * m_data[1][1] * m_data[2][0];
780 inline bool Matrix3x3::isDiagonal()
const
782 return m_data[0][1] == 0.0 && m_data[0][2] == 0.0 &&
783 m_data[1][0] == 0.0 && m_data[1][2] == 0.0 &&
784 m_data[2][0] == 0.0 && m_data[2][1] == 0.0;
787 inline Matrix3x3 Matrix3x3::fastInverse(
double det)
const
791 double k = 1.0 / det;
793 dest(0, 0) = k * MOMENTUM_MATRIX3X3_DET2(m_data[1][1], m_data[1][2], m_data[2][1], m_data[2][2]);
794 dest(0, 1) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][2], m_data[0][1], m_data[2][2], m_data[2][1]);
795 dest(0, 2) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][1], m_data[0][2], m_data[1][1], m_data[1][2]);
797 dest(1, 0) = k * MOMENTUM_MATRIX3X3_DET2(m_data[1][2], m_data[1][0], m_data[2][2], m_data[2][0]);
798 dest(1, 1) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][0], m_data[0][2], m_data[2][0], m_data[2][2]);
799 dest(1, 2) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][2], m_data[0][0], m_data[1][2], m_data[1][0]);
801 dest(2, 0) = k * MOMENTUM_MATRIX3X3_DET2(m_data[1][0], m_data[1][1], m_data[2][0], m_data[2][1]);
802 dest(2, 1) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][1], m_data[0][0], m_data[2][1], m_data[2][0]);
803 dest(2, 2) = k * MOMENTUM_MATRIX3X3_DET2(m_data[0][0], m_data[0][1], m_data[1][0], m_data[1][1]);
809 inline void momentum_findMaxElement(
const Matrix3x3& mat,
bool skipFlags[3],
int coord[2])
813 coord[0] = (skipFlags[0] ? (skipFlags[1] ? 2 : 1) : 0);
816 for (
int i = 0; i < 3; i++)
821 for (
int j = 0; j < 3; j++)
823 if (std::abs(mat(i, j)) >
max)
827 max = std::abs(mat(i, j));
832 agxAssert(coord[0] >= 0 && coord[1] >= 0);
839 if (this->isDiagonal())
840 return Matrix3x3(1.0 / m_data[0][0], 0, 0, 0, 1.0 / m_data[1][1], 0, 0, 0, 1.0 / m_data[2][2]);
843 double determinant = this->determinant();
845 if (determinant > agx::RealEpsilon)
846 return this->fastInverse(determinant);
849 const int next[3] = { 1, 2, 0 };
853 bool done[3] = {
false,
false,
false };
854 int pivotColumns[3] = { -1, -1, -1 };
856 for (
int i = 0; i < 3; i++)
860 momentum_findMaxElement(tmp, done, coord);
861 pivotColumns[(int)coord[0]] = (
int)coord[1];
864 double *row = &tmp(coord[0], 0);
865 double *resultRow = &result(coord[0], 0);
868 double scale = 1.0 / row[coord[1]];
869 for (
int j = 0; j < 3; j++)
872 resultRow[j] *= scale;
877 for (
int r = next[coord[0]]; r != coord[0]; r = next[r])
879 double *ra = &tmp(r, 0);
880 double *rb = &result(r, 0);
881 double f = ra[coord[1]];
883 for (
int j = 0; j < 3; j++)
886 rb[j] -= f*resultRow[j];
890 done[coord[0]] =
true;
894 for (
int i = 0; i < 3; i++)
896 double *ra = &tmp(pivotColumns[i], 0);
897 double *rb = &result(i, 0);
898 memcpy(ra, rb,
sizeof(
double) * 3);
908 agx::equivalent(a(0, 0), b(0, 0), epsilon) &&
909 agx::equivalent(a(0, 1), b(0, 1), epsilon) &&
910 agx::equivalent(a(0, 2), b(0, 2), epsilon) &&
911 agx::equivalent(a(1, 0), b(1, 0), epsilon) &&
912 agx::equivalent(a(1, 1), b(1, 1), epsilon) &&
913 agx::equivalent(a(1, 2), b(1, 2), epsilon) &&
914 agx::equivalent(a(2, 0), b(2, 0), epsilon) &&
915 agx::equivalent(a(2, 1), b(2, 1), epsilon) &&
916 agx::equivalent(a(2, 2), b(2, 2), epsilon);
Matrix class for inertia.
Definition: Matrix3x3.h:52
Matrix3x3()
Creates a new matrix, initialized to be an identity matrix.
Definition: Matrix3x3.h:298
double & operator()(size_t row, size_t col)
Definition: Matrix3x3.h:700
Matrix3x3 operator=(const Matrix3x3 &rhs)
Definition: Matrix3x3.h:713
void postMult(const Matrix3x3 &)
Definition: Matrix3x3.h:670
Matrix3x3 setIdentity()
Definition: Matrix3x3.h:540
Matrix3x3 set(double const *const ptr)
Definition: Matrix3x3.h:416
Matrix3x3(agx::Matrix3x3 mat)
Definition: Matrix3x3.h:72
Vec3 getRow(size_t row) const
Definition: Matrix3x3.h:178
bool valid() const
Definition: Matrix3x3.h:356
void preMult(const Matrix3x3 &)
Definition: Matrix3x3.h:654
bool isIdentity() const
Definition: Matrix3x3.h:386
Quat getRotate() const
Definition: Matrix3x3.h:550
void setCol(size_t col, const Vec3 &vec)
Definition: Matrix3x3.h:172
bool operator!=(const Matrix3x3 &m) const
Definition: Matrix3x3.h:692
static Matrix3x3 rotate(const Vec3 &from, const Vec3 &to)
Definition: Matrix3x3.h:584
bool isRigidTransformation() const
Definition: Matrix3x3.h:392
Vec3 getCol(size_t col) const
Definition: Matrix3x3.h:187
Matrix3x3 inverse() const
Matrix inverse.
Definition: Matrix3x3.h:836
Vec3 operator*(const Vec3 &v) const
Definition: Matrix3x3.h:741
bool isNaN() const
Definition: Matrix3x3.h:363
void operator*=(const Matrix3x3 &other)
Definition: Matrix3x3.h:722
bool operator==(const Matrix3x3 &m) const
Definition: Matrix3x3.h:685
bool isFinite() const
Definition: Matrix3x3.h:375
~Matrix3x3()
Destructor.
Definition: Matrix3x3.h:348
double at(size_t row, size_t col) const
Definition: Matrix3x3.h:196
Vec3 mult(const Vec3 &v) const
Definition: Matrix3x3.h:757
void setRow(size_t row, const Vec3 &vec)
Set the row of the matrix,.
Definition: Matrix3x3.h:166
static Matrix3x3 crossMatrix(const Vec3 &vec)
Generates a new matrix of a specific type.
Definition: Matrix3x3.h:577
Matrix3x3 transpose() const
Definition: Matrix3x3.h:766
double * ptr()
Definition: Matrix3x3.h:557
Matrix3x3 setRotate(const Quat &q)
Definition: Matrix3x3.h:484
The object holding quaternions and providing operations on these.
Definition: Quat.h:55
void setRotate(double angle, double x, double y, double z)
Set the rotation of the Quaternion as a rotation angle radians around the vector (x,...
double length2() const
Definition: Quat.h:656
A 3 dimensional vector which can be used to define a point or a vector and contains basic arithmetic.
Definition: Vec3.h:40
double y() const
Definition: Vec3.h:497
double z() const
Definition: Vec3.h:503
double x() const
Definition: Vec3.h:491
Namespace for Momentum Scripting API.
Definition: AffineMatrix4x4.h:29
std::ostream & operator<<(std::ostream &os, const EulerAngles &e)
Definition: EulerAngles.h:358
Vec3 max(const Vec3 &lhs, const Vec3 &rhs)
Definition: Vec3.h:804
Vec3 operator*(const Vec3 &v, const Matrix3x3 &m)
Definition: Matrix3x3.h:746
bool equivalent(const Matrix3x3 &a, const Matrix3x3 &b, double epsilon=1e-6)
Definition: Matrix3x3.h:905