AGX Dynamics 2.42.3.0
Loading...
Searching...
No Matches
SPDMatrix3x3.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#pragma once
18
19#include <agx/agxCore_export.h>
20
21#include <agx/Vec3.h>
22#include <agx/AffineMatrix4x4.h>
23#include <agx/Matrix3x3.h>
24
25namespace agx
26{
27 template<typename T>
28 class AffineMatrix4x4T;
29
48 {
49 public:
50 typedef Real Type;
52 SPDMatrix3x3( const SPDMatrix3x3& mat );
53
54 SPDMatrix3x3( Real a00, Real a01, Real a02,
55 Real a10, Real a11, Real a12,
56 Real a20, Real a21, Real a22);
57
58 explicit SPDMatrix3x3( const Vec3& v );
59 explicit SPDMatrix3x3( const Matrix3x3& m );
61
62 bool operator == ( const SPDMatrix3x3& m ) const;
63 bool operator != ( const SPDMatrix3x3& m ) const;
64
65 Real& operator()( size_t row, size_t col );
66 Real operator()( size_t row, size_t col ) const;
67
68#ifndef SWIG
69 Real& at( size_t row, size_t col );
70#endif
71 Real at( size_t row, size_t col ) const;
72
73 bool isValid() const;
74 bool isNaN() const;
75
76 bool isIdentity() const;
77 void makeIdentity();
78
79 SPDMatrix3x3& operator = ( const SPDMatrix3x3& rhs );
80 void set( Real a00, Real a01, Real a02,
81 Real a10, Real a11, Real a12,
82 Real a20, Real a21, Real a22);
83 void set(const Matrix3x3& m);
85 void set(const Vec3& v);
86
93 void set(Real v, size_t row, size_t col);
94
95 Vec3 getDiagonal() const;
96 Real determinant() const;
98
99 void mult( const SPDMatrix3x3& m, const Real& r);
100 void add( const SPDMatrix3x3& a, const SPDMatrix3x3& b);
101 void sub( const SPDMatrix3x3& a, const SPDMatrix3x3& b);
102
103 void operator *= ( const Real& r );
104 void operator /= ( const Real& d);
105 void operator += ( const SPDMatrix3x3& m );
106 void operator -= ( const SPDMatrix3x3& m );
107 SPDMatrix3x3 operator * ( const Real& r ) const;
108 SPDMatrix3x3 operator / ( const Real& r ) const;
109 SPDMatrix3x3 operator + ( const SPDMatrix3x3& m ) const;
110 SPDMatrix3x3 operator - ( const SPDMatrix3x3& m ) const;
111
112 Vec3 preMult( const Vec3& v ) const;
113 Vec3 postMult( const Vec3& v ) const;
114 Vec3 operator * ( const Vec3& v ) const;
115
116
117 Real* ptr();
118 const Real* ptr() const;
119
120 protected:
121 template <typename T>
122 friend class Matrix3x3T;
123
124
125 protected:
126 Type m_data[6];
127 };
128
129 /* Implementation */
130
132 {
133 this->makeIdentity();
134 }
135
137 {
138 *this = mat;
139 }
140
142 Real a00, Real a01, Real a02,
143 Real a10, Real a11, Real a12,
144 Real a20, Real a21, Real a22)
145 {
146 this->set(
147 a00, a01, a02,
148 a10, a11, a12,
149 a20, a21, a22);
150 }
151
152
154 {
155 this->set(v);
156 }
157
159 {
160 return m_data[0] == m.m_data[0] &&
161 m_data[1] == m.m_data[1] &&
162 m_data[2] == m.m_data[2] &&
163 m_data[3] == m.m_data[3] &&
164 m_data[4] == m.m_data[4] &&
165 m_data[5] == m.m_data[5];
166 }
167
169 {
170 return !(*this == m);
171 }
172
173
174 AGX_FORCE_INLINE Real& SPDMatrix3x3::at( size_t row, size_t col )
175 {
176 agxAssert(row < 3);
177 agxAssert(col < 3);
178 return this->operator()(row, col);
179 }
180
181
182 AGX_FORCE_INLINE Real SPDMatrix3x3::at( size_t row, size_t col ) const
183 {
184 agxAssert(row < 3);
185 agxAssert(col < 3);
186 return this->operator()(row, col);
187 }
188
189
191 {
192 size_t index = row + col;
193 if (index == 2 && row == 1)
194 index = 5;
195 return m_data[index];
196 }
197
198 AGX_FORCE_INLINE Real SPDMatrix3x3::operator()( size_t row, size_t col ) const
199 {
200 size_t index = row + col;
201 if (index == 2 && row == 1)
202 index = 5;
203 return m_data[index];
204 }
205
206
208 {
209 // Matrix can not be NaN
210 if (this->isNaN())
211 return false;
212 // Check that it is positive definite
213 // by checking that all 3 principal minors are positive;
214 // i.e. top left matrix 1x1, 2x2 and 3x3 determinants must be positive
215 // 1x1
216 if (m_data[0] <= 0)
217 return false;
218 // 2x2
219 if ((m_data[0] * m_data[5]) - (m_data[1] * m_data[1]) <= 0)
220 return false;
221 // 3x3
222 if (determinant() <= 0)
223 return false;
224 return true;
225 }
226
227
229 {
230 return std::isnan( m_data[0] ) || std::isnan( m_data[1] ) || std::isnan( m_data[2] ) ||
231 std::isnan( m_data[3] ) || std::isnan( m_data[4] ) || std::isnan( m_data[5] );
232 }
233
235 {
236 return *this == SPDMatrix3x3();
237 }
238
240 {
241 m_data[0] = 1.0;
242 m_data[1] = 0;
243 m_data[2] = 0;
244 m_data[3] = 0;
245 m_data[4] = 1.0;
246 m_data[5] = 1.0;
247 }
248
249
251 {
252 m_data[0] = rhs.m_data[0];
253 m_data[1] = rhs.m_data[1];
254 m_data[2] = rhs.m_data[2];
255 m_data[3] = rhs.m_data[3];
256 m_data[4] = rhs.m_data[4];
257 m_data[5] = rhs.m_data[5];
258
259 return *this;
260 }
261
262// #define AGX_SPDMATRIX3X3_VERIFY_VALIDITY in order to get validity asserts.
263#if (defined AGX_DEBUG && defined AGX_SPDMATRIX3X3_VERIFY_VALIDITY)
265 Real a00, Real a01, Real a02,
266 Real a10, Real a11, Real a12,
267 Real a20, Real a21, Real a22)
268 {
269 agxAssert(
270 relativelyEquivalent(a01, a10) &&
271 relativelyEquivalent(a02, a20) &&
272 relativelyEquivalent(a12, a21));
273
274 m_data[0] = a00;
275 m_data[1] = a01;
276 m_data[2] = a02;
277 m_data[3] = a12;
278 m_data[4] = a22;
279 m_data[5] = a11;
280
281 agxAssert(this->isValid());
282 }
283#else
285 Real a00, Real a01, Real a02,
286 Real /*a10*/, Real a11, Real a12,
287 Real /*a20*/, Real /*a21*/, Real a22)
288 {
289 m_data[0] = a00;
290 m_data[1] = a01;
291 m_data[2] = a02;
292 m_data[3] = a12;
293 m_data[4] = a22;
294 m_data[5] = a11;
295 }
296#endif
297
299 {
300 m_data[0] = v[0];
301 m_data[1] = 0;
302 m_data[2] = 0;
303 m_data[3] = 0;
304 m_data[4] = v[2];
305 m_data[5] = v[1];
306 }
307
308
309
310 AGX_FORCE_INLINE void SPDMatrix3x3::set(Real v, size_t row, size_t col)
311 {
312 size_t index = row + col;
313
314 // Per definition, (row, col) = (1, 1) corresponds to index 5 (see top of file)
315 if (index == 2 && row == 1)
316 index = 5;
317
318 m_data[index] = v;
319 }
320
321
322
324 {
325 return Vec3( m_data[0], m_data[5], m_data[4] );
326 }
327
329 {
330 return m_data[0]*m_data[5]*m_data[4] - m_data[0]*m_data[3]*m_data[3] -
331 m_data[1]*m_data[1]*m_data[4] + m_data[1]*m_data[3]*m_data[2] +
332 m_data[2]*m_data[1]*m_data[3] - m_data[2]*m_data[5]*m_data[2];
333 }
334
336 {
337 return Vec3( ( m_data[0]*v.x() + m_data[1]*v.y() + m_data[2]*v.z() ),
338 ( m_data[1]*v.x() + m_data[5]*v.y() + m_data[3]*v.z() ),
339 ( m_data[2]*v.x() + m_data[3]*v.y() + m_data[4]*v.z() ) ) ;
340 }
341
343 {
344 return Vec3( ( m_data[0]*v.x() + m_data[1]*v.y() + m_data[2]*v.z() ),
345 ( m_data[1]*v.x() + m_data[5]*v.y() + m_data[3]*v.z() ),
346 ( m_data[2]*v.x() + m_data[3]*v.y() + m_data[4]*v.z() ) ) ;
347 }
348
350 {
351 m_data[0] = m.m_data[0] * r;
352 m_data[1] = m.m_data[1] * r;
353 m_data[2] = m.m_data[2] * r;
354 m_data[3] = m.m_data[3] * r;
355 m_data[4] = m.m_data[4] * r;
356 m_data[5] = m.m_data[5] * r;
357 }
358
360 {
361 m_data[0] = a.m_data[0] + b.m_data[0];
362 m_data[1] = a.m_data[1] + b.m_data[1];
363 m_data[2] = a.m_data[2] + b.m_data[2];
364 m_data[3] = a.m_data[3] + b.m_data[3];
365 m_data[4] = a.m_data[4] + b.m_data[4];
366 m_data[5] = a.m_data[5] + b.m_data[5];
367 }
368
370 {
371 m_data[0] = a.m_data[0] - b.m_data[0];
372 m_data[1] = a.m_data[1] - b.m_data[1];
373 m_data[2] = a.m_data[2] - b.m_data[2];
374 m_data[3] = a.m_data[3] - b.m_data[3];
375 m_data[4] = a.m_data[4] - b.m_data[4];
376 m_data[5] = a.m_data[5] - b.m_data[5];
377 }
378
380 {
381 this->mult(*this, r);
382 }
383
385 {
386 this->mult(*this, agx::Real(1.0)/d);
387 }
388
390 {
391 this->add(*this, m);
392 }
393
395 {
396 this->sub(*this, m);
397 }
398
400 {
401 SPDMatrix3x3 t;
402 t.mult( *this, r );
403 return t;
404 }
405
407 {
408 SPDMatrix3x3 t;
409 t.mult( *this, agx::Real(1.0)/r );
410 return t;
411 }
412
414 {
415 SPDMatrix3x3 t;
416 t.add( *this, m );
417 return t;
418 }
419
421 {
422 SPDMatrix3x3 t;
423 t.sub( *this, m );
424 return t;
425 }
426
428 {
429 return m.preMult( v );
430 }
431
433 {
434 return postMult( v );
435 }
436
437
439 {
440 SPDMatrix3x3 t;
441 t.mult(m, r);
442 return t;
443 }
444
445
447 {
448 return (equivalent(m1(0, 0), m2(0, 0), epsilon) &&
449 equivalent(m1(0, 1), m2(0, 1), epsilon) &&
450 equivalent(m1(0, 2), m2(0, 2), epsilon) &&
451 equivalent(m1(1, 1), m2(1, 1), epsilon) &&
452 equivalent(m1(1, 2), m2(1, 2), epsilon) &&
453 equivalent(m1(2, 2), m2(2, 2), epsilon));
454 }
455
456
458 {
459 return m_data;
460 }
461
463 {
464 return m_data;
465 }
466
467 inline std::ostream& operator<< ( std::ostream& os, const SPDMatrix3x3& m )
468 {
469 os << "{" << std::endl;
470 for ( size_t row = 0; row < 3; ++row ) {
471 os << "\t";
472 for ( size_t col = 0; col < 3; ++col )
473 os << m( row, col ) << " ";
474 os << std::endl;
475 }
476 os << "}" << std::endl;
477 return os;
478 }
479
480
481
482} // namespace agx
483
484AGX_TYPE_BINDING(agx::SPDMatrix3x3, "SPDMatrix3x3")
485
AGXCORE_EXPORT agx::String operator+(const std::string &str, const agx::Name &name)
#define AGX_TYPE_BINDING(_Type, _Name)
Definition: Type.h:179
#define AGXCORE_EXPORT
Matrix class for rigid transformations (translation, rotation).
Specialized type of matrices for holding symmetric positive definite matrices.
Definition: SPDMatrix3x3.h:48
SPDMatrix3x3 & operator=(const SPDMatrix3x3 &rhs)
Definition: SPDMatrix3x3.h:250
bool isIdentity() const
Definition: SPDMatrix3x3.h:234
void operator*=(const Real &r)
Definition: SPDMatrix3x3.h:379
Vec3 getDiagonal() const
Definition: SPDMatrix3x3.h:323
Real & at(size_t row, size_t col)
Definition: SPDMatrix3x3.h:174
SPDMatrix3x3 operator/(const Real &r) const
Definition: SPDMatrix3x3.h:406
Real & operator()(size_t row, size_t col)
Definition: SPDMatrix3x3.h:190
void mult(const SPDMatrix3x3 &m, const Real &r)
Definition: SPDMatrix3x3.h:349
void set(const Matrix3x3 &m)
Vec3 postMult(const Vec3 &v) const
Definition: SPDMatrix3x3.h:335
SPDMatrix3x3 operator+(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:413
Real determinant() const
Definition: SPDMatrix3x3.h:328
SPDMatrix3x3 operator-(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:420
Vec3 preMult(const Vec3 &v) const
Definition: SPDMatrix3x3.h:342
SPDMatrix3x3(const AffineMatrix4x4T< Real > &m)
void operator-=(const SPDMatrix3x3 &m)
Definition: SPDMatrix3x3.h:394
void sub(const SPDMatrix3x3 &a, const SPDMatrix3x3 &b)
Definition: SPDMatrix3x3.h:369
SPDMatrix3x3 operator*(const Real &r) const
Definition: SPDMatrix3x3.h:399
bool operator!=(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:168
void operator/=(const Real &d)
Definition: SPDMatrix3x3.h:384
SPDMatrix3x3(const Matrix3x3 &m)
void add(const SPDMatrix3x3 &a, const SPDMatrix3x3 &b)
Definition: SPDMatrix3x3.h:359
bool isNaN() const
Definition: SPDMatrix3x3.h:228
bool isValid() const
Definition: SPDMatrix3x3.h:207
void operator+=(const SPDMatrix3x3 &m)
Definition: SPDMatrix3x3.h:389
void set(const AffineMatrix4x4T< Real > &m)
void set(Real a00, Real a01, Real a02, Real a10, Real a11, Real a12, Real a20, Real a21, Real a22)
Definition: SPDMatrix3x3.h:284
SPDMatrix3x3 inverse() const
bool operator==(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:158
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
Vec3T< Real > Vec3
The object holding 3 dimensional vectors and providing basic arithmetic.
Definition: agx/Vec3.h:36
Vec3T< T > operator*(const Vec3T< T > &v, const AffineMatrix4x4T< T > &m)
bool isNaN(T v)
Definition: Math.h:303
std::ostream & operator<<(std::ostream &os, const agx::AddedMassInteraction::Matrix6x6 &m)
bool relativelyEquivalent(float lhs, float rhs, float epsilon=(float) AGX_EQUIVALENT_EPSILON)
Compare two values for relative equality.
Definition: Math.h:165
Real mult(const Jacobian6DOFElementT< T > &G1, const Jacobian6DOFElementT< T > &G2)
Definition: agx/Jacobian.h:386
double Real
Definition: Real.h:41
static constexpr Real AGX_EQUIVALENT_EPSILON
Definition: Math.h:57
AGXPHYSICS_EXPORT agx::Bool equivalent(const agx::AddedMassInteraction::Matrix6x6 &lhs, const agx::AddedMassInteraction::Matrix6x6 &rhs, agx::Real eps=agx::RealEpsilon)