AGX Dynamics 2.41.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#include <agxData/Type.h>
25
26namespace agx
27{
28 template<typename T>
29 class AffineMatrix4x4T;
30
49 {
50 public:
51 typedef Real Type;
53 SPDMatrix3x3( const SPDMatrix3x3& mat );
54
55 SPDMatrix3x3( Real a00, Real a01, Real a02,
56 Real a10, Real a11, Real a12,
57 Real a20, Real a21, Real a22);
58
59 explicit SPDMatrix3x3( const Vec3& v );
60 explicit SPDMatrix3x3( const Matrix3x3& m );
62
63 bool operator == ( const SPDMatrix3x3& m ) const;
64 bool operator != ( const SPDMatrix3x3& m ) const;
65
66 Real& operator()( size_t row, size_t col );
67 Real operator()( size_t row, size_t col ) const;
68
69#ifndef SWIG
70 Real& at( size_t row, size_t col );
71#endif
72 Real at( size_t row, size_t col ) const;
73
74 bool isValid() const;
75 bool isNaN() const;
76
77 bool isIdentity() const;
78 void makeIdentity();
79
80 SPDMatrix3x3& operator = ( const SPDMatrix3x3& rhs );
81 void set( Real a00, Real a01, Real a02,
82 Real a10, Real a11, Real a12,
83 Real a20, Real a21, Real a22);
84 void set(const Matrix3x3& m);
86 void set(const Vec3& v);
87
94 void set(Real v, size_t row, size_t col);
95
96 Vec3 getDiagonal() const;
97 Real determinant() const;
99
100 void mult( const SPDMatrix3x3& m, const Real& r);
101 void add( const SPDMatrix3x3& a, const SPDMatrix3x3& b);
102 void sub( const SPDMatrix3x3& a, const SPDMatrix3x3& b);
103
104 void operator *= ( const Real& r );
105 void operator /= ( const Real& d);
106 void operator += ( const SPDMatrix3x3& m );
107 void operator -= ( const SPDMatrix3x3& m );
108 SPDMatrix3x3 operator * ( const Real& r ) const;
109 SPDMatrix3x3 operator / ( const Real& r ) const;
110 SPDMatrix3x3 operator + ( const SPDMatrix3x3& m ) const;
111 SPDMatrix3x3 operator - ( const SPDMatrix3x3& m ) const;
112
113 Vec3 preMult( const Vec3& v ) const;
114 Vec3 postMult( const Vec3& v ) const;
115 Vec3 operator * ( const Vec3& v ) const;
116
117
118 Real* ptr();
119 const Real* ptr() const;
120
121 protected:
122 template <typename T>
123 friend class Matrix3x3T;
124
125
126 protected:
127 Type m_data[6];
128 };
129
130 /* Implementation */
131
133 {
134 this->makeIdentity();
135 }
136
138 {
139 *this = mat;
140 }
141
143 Real a00, Real a01, Real a02,
144 Real a10, Real a11, Real a12,
145 Real a20, Real a21, Real a22)
146 {
147 this->set(
148 a00, a01, a02,
149 a10, a11, a12,
150 a20, a21, a22);
151 }
152
153
155 {
156 this->set(v);
157 }
158
160 {
161 return m_data[0] == m.m_data[0] &&
162 m_data[1] == m.m_data[1] &&
163 m_data[2] == m.m_data[2] &&
164 m_data[3] == m.m_data[3] &&
165 m_data[4] == m.m_data[4] &&
166 m_data[5] == m.m_data[5];
167 }
168
170 {
171 return !(*this == m);
172 }
173
174
175 AGX_FORCE_INLINE Real& SPDMatrix3x3::at( size_t row, size_t col )
176 {
177 agxAssert(row < 3);
178 agxAssert(col < 3);
179 return this->operator()(row, col);
180 }
181
182
183 AGX_FORCE_INLINE Real SPDMatrix3x3::at( size_t row, size_t col ) const
184 {
185 agxAssert(row < 3);
186 agxAssert(col < 3);
187 return this->operator()(row, col);
188 }
189
190
192 {
193 size_t index = row + col;
194 if (index == 2 && row == 1)
195 index = 5;
196 return m_data[index];
197 }
198
199 AGX_FORCE_INLINE Real SPDMatrix3x3::operator()( size_t row, size_t col ) const
200 {
201 size_t index = row + col;
202 if (index == 2 && row == 1)
203 index = 5;
204 return m_data[index];
205 }
206
207
209 {
210 // Matrix can not be NaN
211 if (this->isNaN())
212 return false;
213 // Check that it is positive definite
214 // by checking that all 3 principal minors are positive;
215 // i.e. top left matrix 1x1, 2x2 and 3x3 determinants must be positive
216 // 1x1
217 if (m_data[0] <= 0)
218 return false;
219 // 2x2
220 if ((m_data[0] * m_data[5]) - (m_data[1] * m_data[1]) <= 0)
221 return false;
222 // 3x3
223 if (determinant() <= 0)
224 return false;
225 return true;
226 }
227
228
230 {
231 return std::isnan( m_data[0] ) || std::isnan( m_data[1] ) || std::isnan( m_data[2] ) ||
232 std::isnan( m_data[3] ) || std::isnan( m_data[4] ) || std::isnan( m_data[5] );
233 }
234
236 {
237 return *this == SPDMatrix3x3();
238 }
239
241 {
242 m_data[0] = 1.0;
243 m_data[1] = 0;
244 m_data[2] = 0;
245 m_data[3] = 0;
246 m_data[4] = 1.0;
247 m_data[5] = 1.0;
248 }
249
250
252 {
253 m_data[0] = rhs.m_data[0];
254 m_data[1] = rhs.m_data[1];
255 m_data[2] = rhs.m_data[2];
256 m_data[3] = rhs.m_data[3];
257 m_data[4] = rhs.m_data[4];
258 m_data[5] = rhs.m_data[5];
259
260 return *this;
261 }
262
263// #define AGX_SPDMATRIX3X3_VERIFY_VALIDITY in order to get validity asserts.
264#if (defined AGX_DEBUG && defined AGX_SPDMATRIX3X3_VERIFY_VALIDITY)
266 Real a00, Real a01, Real a02,
267 Real a10, Real a11, Real a12,
268 Real a20, Real a21, Real a22)
269 {
270 agxAssert(
271 relativelyEquivalent(a01, a10) &&
272 relativelyEquivalent(a02, a20) &&
273 relativelyEquivalent(a12, a21));
274
275 m_data[0] = a00;
276 m_data[1] = a01;
277 m_data[2] = a02;
278 m_data[3] = a12;
279 m_data[4] = a22;
280 m_data[5] = a11;
281
282 agxAssert(this->isValid());
283 }
284#else
286 Real a00, Real a01, Real a02,
287 Real /*a10*/, Real a11, Real a12,
288 Real /*a20*/, Real /*a21*/, Real a22)
289 {
290 m_data[0] = a00;
291 m_data[1] = a01;
292 m_data[2] = a02;
293 m_data[3] = a12;
294 m_data[4] = a22;
295 m_data[5] = a11;
296 }
297#endif
298
300 {
301 m_data[0] = v[0];
302 m_data[1] = 0;
303 m_data[2] = 0;
304 m_data[3] = 0;
305 m_data[4] = v[2];
306 m_data[5] = v[1];
307 }
308
309
310
311 AGX_FORCE_INLINE void SPDMatrix3x3::set(Real v, size_t row, size_t col)
312 {
313 size_t index = row + col;
314
315 // Per definition, (row, col) = (1, 1) corresponds to index 5 (see top of file)
316 if (index == 2 && row == 1)
317 index = 5;
318
319 m_data[index] = v;
320 }
321
322
323
325 {
326 return Vec3( m_data[0], m_data[5], m_data[4] );
327 }
328
330 {
331 return m_data[0]*m_data[5]*m_data[4] - m_data[0]*m_data[3]*m_data[3] -
332 m_data[1]*m_data[1]*m_data[4] + m_data[1]*m_data[3]*m_data[2] +
333 m_data[2]*m_data[1]*m_data[3] - m_data[2]*m_data[5]*m_data[2];
334 }
335
337 {
338 return Vec3( ( m_data[0]*v.x() + m_data[1]*v.y() + m_data[2]*v.z() ),
339 ( m_data[1]*v.x() + m_data[5]*v.y() + m_data[3]*v.z() ),
340 ( m_data[2]*v.x() + m_data[3]*v.y() + m_data[4]*v.z() ) ) ;
341 }
342
344 {
345 return Vec3( ( m_data[0]*v.x() + m_data[1]*v.y() + m_data[2]*v.z() ),
346 ( m_data[1]*v.x() + m_data[5]*v.y() + m_data[3]*v.z() ),
347 ( m_data[2]*v.x() + m_data[3]*v.y() + m_data[4]*v.z() ) ) ;
348 }
349
351 {
352 m_data[0] = m.m_data[0] * r;
353 m_data[1] = m.m_data[1] * r;
354 m_data[2] = m.m_data[2] * r;
355 m_data[3] = m.m_data[3] * r;
356 m_data[4] = m.m_data[4] * r;
357 m_data[5] = m.m_data[5] * r;
358 }
359
361 {
362 m_data[0] = a.m_data[0] + b.m_data[0];
363 m_data[1] = a.m_data[1] + b.m_data[1];
364 m_data[2] = a.m_data[2] + b.m_data[2];
365 m_data[3] = a.m_data[3] + b.m_data[3];
366 m_data[4] = a.m_data[4] + b.m_data[4];
367 m_data[5] = a.m_data[5] + b.m_data[5];
368 }
369
371 {
372 m_data[0] = a.m_data[0] - b.m_data[0];
373 m_data[1] = a.m_data[1] - b.m_data[1];
374 m_data[2] = a.m_data[2] - b.m_data[2];
375 m_data[3] = a.m_data[3] - b.m_data[3];
376 m_data[4] = a.m_data[4] - b.m_data[4];
377 m_data[5] = a.m_data[5] - b.m_data[5];
378 }
379
381 {
382 this->mult(*this, r);
383 }
384
386 {
387 this->mult(*this, agx::Real(1.0)/d);
388 }
389
391 {
392 this->add(*this, m);
393 }
394
396 {
397 this->sub(*this, m);
398 }
399
401 {
402 SPDMatrix3x3 t;
403 t.mult( *this, r );
404 return t;
405 }
406
408 {
409 SPDMatrix3x3 t;
410 t.mult( *this, agx::Real(1.0)/r );
411 return t;
412 }
413
415 {
416 SPDMatrix3x3 t;
417 t.add( *this, m );
418 return t;
419 }
420
422 {
423 SPDMatrix3x3 t;
424 t.sub( *this, m );
425 return t;
426 }
427
429 {
430 return m.preMult( v );
431 }
432
434 {
435 return postMult( v );
436 }
437
438
440 {
441 SPDMatrix3x3 t;
442 t.mult(m, r);
443 return t;
444 }
445
446
448 {
449 return (equivalent(m1(0, 0), m2(0, 0), epsilon) &&
450 equivalent(m1(0, 1), m2(0, 1), epsilon) &&
451 equivalent(m1(0, 2), m2(0, 2), epsilon) &&
452 equivalent(m1(1, 1), m2(1, 1), epsilon) &&
453 equivalent(m1(1, 2), m2(1, 2), epsilon) &&
454 equivalent(m1(2, 2), m2(2, 2), epsilon));
455 }
456
457
459 {
460 return m_data;
461 }
462
464 {
465 return m_data;
466 }
467
468 inline std::ostream& operator<< ( std::ostream& os, const SPDMatrix3x3& m )
469 {
470 os << "{" << std::endl;
471 for ( size_t row = 0; row < 3; ++row ) {
472 os << "\t";
473 for ( size_t col = 0; col < 3; ++col )
474 os << m( row, col ) << " ";
475 os << std::endl;
476 }
477 os << "}" << std::endl;
478 return os;
479 }
480
481
482
483} // namespace agx
484
485AGX_TYPE_BINDING(agx::SPDMatrix3x3, "SPDMatrix3x3")
486
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:49
SPDMatrix3x3 & operator=(const SPDMatrix3x3 &rhs)
Definition: SPDMatrix3x3.h:251
bool isIdentity() const
Definition: SPDMatrix3x3.h:235
void operator*=(const Real &r)
Definition: SPDMatrix3x3.h:380
Vec3 getDiagonal() const
Definition: SPDMatrix3x3.h:324
Real & at(size_t row, size_t col)
Definition: SPDMatrix3x3.h:175
SPDMatrix3x3 operator/(const Real &r) const
Definition: SPDMatrix3x3.h:407
Real & operator()(size_t row, size_t col)
Definition: SPDMatrix3x3.h:191
void mult(const SPDMatrix3x3 &m, const Real &r)
Definition: SPDMatrix3x3.h:350
void set(const Matrix3x3 &m)
Vec3 postMult(const Vec3 &v) const
Definition: SPDMatrix3x3.h:336
SPDMatrix3x3 operator+(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:414
Real determinant() const
Definition: SPDMatrix3x3.h:329
SPDMatrix3x3 operator-(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:421
Vec3 preMult(const Vec3 &v) const
Definition: SPDMatrix3x3.h:343
SPDMatrix3x3(const AffineMatrix4x4T< Real > &m)
void operator-=(const SPDMatrix3x3 &m)
Definition: SPDMatrix3x3.h:395
void sub(const SPDMatrix3x3 &a, const SPDMatrix3x3 &b)
Definition: SPDMatrix3x3.h:370
SPDMatrix3x3 operator*(const Real &r) const
Definition: SPDMatrix3x3.h:400
bool operator!=(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:169
void operator/=(const Real &d)
Definition: SPDMatrix3x3.h:385
SPDMatrix3x3(const Matrix3x3 &m)
void add(const SPDMatrix3x3 &a, const SPDMatrix3x3 &b)
Definition: SPDMatrix3x3.h:360
bool isNaN() const
Definition: SPDMatrix3x3.h:229
bool isValid() const
Definition: SPDMatrix3x3.h:208
void operator+=(const SPDMatrix3x3 &m)
Definition: SPDMatrix3x3.h:390
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:285
SPDMatrix3x3 inverse() const
bool operator==(const SPDMatrix3x3 &m) const
Definition: SPDMatrix3x3.h:159
#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:42
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)