Momentum Scripting v1
Loading...
Searching...
No Matches
Vec3.h
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 without having a written signed agreement with Algoryx Simulation AB.
9
10Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
11from using this software, unless otherwise stated in written agreements with
12Algoryx Simulation AB.
13*/
14
15#ifndef MOMENTUM_VEC3_H
16#define MOMENTUM_VEC3_H
17
18#include "momentum_namespace.h"
19#include "momentum_export.h"
20
21
22#include <agx/PushDisableWarnings.h> // Disabling warnings. Include agx/PopDisableWarnings.h below!
23#include <iosfwd>
24#include <agx/PopDisableWarnings.h> // End of disabled warnings.
25
26#include <agx/agx.h>
27#include <agx/Vec3.h>
28#include <sstream>
29#include "momentum_math.h"
30
31
32namespace MOMENTUM_NAMESPACE
33{
34
39 class Vec3
40 {
41 public:
42 typedef double Type;
43
44
45#ifndef SWIG
47 operator agx::Vec3() const { return agx::Vec3(x(), y(), z()); }
48 operator agx::Vec3f() const { return agx::Vec3f((agx::Real32)x(), (agx::Real32)y(), (agx::Real32)z()); }
49
50 Vec3(const agx::Vec3& copy)
51 {
52 set(copy.x(), copy.y(), copy.z());
53 }
54
55 Vec3(const agx::Vec3f& copy)
56 {
57 set(copy.x(), copy.y(), copy.z());
58 }
60
61#endif
62
64 Vec3(const Vec3& copy );
65
66 // Copy constructor with a new length
67 Vec3(const Vec3& copy, double length);
68
69 // Copy constructor with one modified element, for x, y and z setters.
70 Vec3(const Vec3& copy, double value, int i);
71
72
78 static Vec3 random(double min = double(0), double max = double(1));
79
85 static Vec3 random(const Vec3& min, const Vec3& max);
86
90 Vec3();
91
93 explicit Vec3( double r );
94
95 // Initialize 3d vector from \p x \p y \z values
96 Vec3( double x, double y, double z );
97
98 explicit Vec3(const double v[3] );
99
103 bool operator == ( const Vec3& v ) const;
104
108 bool operator != ( const Vec3& v ) const;
109
113 static Vec3 componentMin(const Vec3& v1, const Vec3& v2);
114
118 static Vec3 componentMax(const Vec3& v1, const Vec3& v2);
119
123 double minComponent() const;
124
128 double maxComponent() const;
129
133 int minElement() const;
134
138 int maxElement() const;
139
143 void clamp(const Vec3& min, const Vec3& max);
144
148 bool equalsZero() const;
149
151 void set( double x, double y, double z );
152
154 void set( double value );
155
156 void set( const Vec3& rhs );
157
158#ifndef SWIG
160 double& operator [] ( int i );
161
163 const double operator [] (int i) const;
164#endif
165
167 double x() const;
168
170 double y() const;
171
173 double z() const;
174
176 void setX( double value );
177
179 void setY(double value);
180
182 void setZ(double value);
183
185 bool isValid() const;
186
188 bool isNaN() const;
189
191 bool isFinite() const; // Non NAN, not infinite.
192
194 double operator * ( const Vec3& rhs ) const;
195
197 const Vec3 operator ^ ( const Vec3& rhs ) const;
198
200 const Vec3 cross(const Vec3& rhs) const;
201
202
204 static Vec3 mul( const Vec3& lhs, const Vec3& rhs );
205
207 static Vec3 div( const Vec3& lhs, const Vec3& rhs );
208
210 const Vec3 operator * ( double rhs ) const;
211
213 Vec3& operator *= ( double rhs );
214
216 const Vec3 operator / ( double rhs ) const;
217
219 Vec3& operator /= ( double rhs );
220
222 const Vec3 operator + ( const Vec3& rhs ) const;
223
227 Vec3& operator += ( const Vec3& rhs );
228
230 const Vec3 operator - ( const Vec3& rhs ) const;
231
233 Vec3& operator -= ( const Vec3& rhs );
234
236 const Vec3 operator + ( const double rhs ) const;
237
241 Vec3& operator += ( const double rhs );
242
244 const Vec3 operator - ( const double rhs ) const;
245
247 Vec3& operator -= ( const double rhs );
248
251 const Vec3 operator - () const;
252
254 double length() const;
255
257 double length2() const;
258
260 double distance2(const Vec3& v2) const;
261
263 double distance(const Vec3& v2) const;
264
269 double normalize();
270
275 double setLength(double l);
276
278 Vec3 normal() const;
279
281 static Vec3 X_AXIS();
282
284 static Vec3 Y_AXIS();
285
287 static Vec3 Z_AXIS();
288
293 static Vec3 AXIS(int i);
294
296 std::string __str__() const;
298
300 protected:
301 double m_data[4];
303 }; // end of class Vec3_template
304
305
306#ifndef SWIG
307 // Implementation
308
309 inline Vec3::Vec3(const Vec3& copy )
310 {
311 m_data[ 0 ] = copy.m_data[ 0 ];
312 m_data[ 1 ] = copy.m_data[ 1 ];
313 m_data[ 2 ] = copy.m_data[ 2 ];
314 m_data[ 3 ] = double(0);
315 }
316
317
318 inline Vec3::Vec3(const Vec3& copy, double length)
319 {
320 m_data[0] = copy.m_data[0];
321 m_data[1] = copy.m_data[1];
322 m_data[2] = copy.m_data[2];
323 m_data[3] = double(0);
324
326 }
327
328
329 inline Vec3::Vec3(const Vec3& copy, double value, int i)
330 {
331 m_data[0] = copy.m_data[0];
332 m_data[1] = copy.m_data[1];
333 m_data[2] = copy.m_data[2];
334 m_data[3] = double(0);
335
336 m_data[i] = value;
337 }
338
339
340 inline Vec3::Vec3()
341 {
342 m_data[0] = double();
343 m_data[1] = double();
344 m_data[2] = double();
345 m_data[3] = double(0);
346 }
347
348
349 inline Vec3::Vec3( double r )
350 {
351 m_data[0] = m_data[1] = m_data[2] = r;
352 m_data[3] = double(0);
353 }
354
355
356 inline Vec3::Vec3( double x, double y, double z )
357 {
358 m_data[0] = x;
359 m_data[1] = y;
360 m_data[2] = z;
361 m_data[3] = double(0);
362 }
363
364
365 inline Vec3::Vec3(const double v[3] )
366 {
367 m_data[0] = v[0];
368 m_data[1] = v[1];
369 m_data[2] = v[2];
370 m_data[3] = double(0);
371 }
372
373
374
375 inline bool Vec3::operator == ( const Vec3& v ) const
376 {
377 return m_data[0] == v.m_data[0] && m_data[1] == v.m_data[1] && m_data[2] == v.m_data[2];
378 }
379
380
381 inline bool Vec3::operator != ( const Vec3& v ) const
382 {
383 return m_data[0] != v.m_data[0] || m_data[1] != v.m_data[1] || m_data[2] != v.m_data[2];
384 }
385
386
387
388 inline Vec3 Vec3::componentMin(const Vec3& v1, const Vec3& v2)
389 {
390 return Vec3( std::min( v1[0], v2[0] ), std::min( v1[1], v2[1] ), std::min( v1[2], v2[2] ) );
391 }
392
393
394 inline Vec3 Vec3::componentMax(const Vec3& v1, const Vec3& v2)
395 {
396 return Vec3( std::max( v1[0], v2[0] ), std::max( v1[1], v2[1] ), std::max( v1[2], v2[2] ) );
397 }
398
399
400 inline double Vec3::minComponent() const
401 {
402 return std::min(std::min(m_data[0], m_data[1]), m_data[2]);
403 }
404
405
406 inline double Vec3::maxComponent() const
407 {
408 return std::max(std::max(m_data[0], m_data[1]), m_data[2]);
409 }
410
411
412 inline int Vec3::minElement() const
413 {
414 double m = std::numeric_limits<double>::infinity();
415 int idx = 0;
416 for(int i = 0; i < 3; i++) {
417 double a = agx::absolute(m_data[i]);
418 if ( a < m) {
419 idx = i;
420 m = a;
421 }
422 }
423 return idx;
424 }
425
426
427 inline int Vec3::maxElement() const
428 {
429 double m = 0;
430 int idx = 0;
431 for(int i = 0; i < 3; i++) {
432 double a = agx::absolute(m_data[i]);
433 if ( a > m) {
434 idx = i;
435 m = a;
436 }
437 }
438 return idx;
439 }
440
441
442 inline void Vec3::clamp(const Vec3& min, const Vec3& max)
443 {
444 m_data[0] = agx::clamp( m_data[0], min.m_data[0], max.m_data[0] );
445 m_data[1] = agx::clamp( m_data[1], min.m_data[1], max.m_data[1] );
446 m_data[2] = agx::clamp( m_data[2], min.m_data[2], max.m_data[2] );
447 }
448
449
450 inline bool Vec3::equalsZero() const
451 {
452 return (agx::equalsZero(m_data[0]) && agx::equalsZero(m_data[1]) && agx::equalsZero(m_data[2]));
453 }
454
455
456
457 inline void Vec3::set( double x, double y, double z )
458 {
459 m_data[0] = x;
460 m_data[1] = y;
461 m_data[2] = z;
462 }
463
464
465 inline void Vec3::set( double value )
466 {
467 m_data[0] = m_data[1] = m_data[2] = value;
468 }
469
470
471 inline void Vec3::set( const Vec3& rhs )
472 {
473 m_data[0] = rhs.m_data[0];
474 m_data[1] = rhs.m_data[1];
475 m_data[2] = rhs.m_data[2];
476 }
477
478
479 inline double& Vec3::operator [] ( int i )
480 {
481 return m_data[i];
482 }
483
484
485 inline const double Vec3::operator [] ( int i ) const
486 {
487 return m_data[i];
488 }
489
490
491 inline double Vec3::x() const
492 {
493 return m_data[0];
494 }
495
496
497 inline double Vec3::y() const
498 {
499 return m_data[1];
500 }
501
502
503 inline double Vec3::z() const
504 {
505 return m_data[2];
506 }
507
508
509 inline void Vec3::setX(double value)
510 {
511 m_data[0] = value;
512 }
513
514
515 inline void Vec3::setY(double value)
516 {
517 m_data[1] = value;
518 }
519
520
521 inline void Vec3::setZ(double value)
522 {
523 m_data[2] = value;
524 }
525
526
527 inline bool Vec3::isValid() const
528 {
529 return !isNaN();
530 }
531
532
533 inline bool Vec3::isNaN() const
534 {
535 return agx::isNaN( m_data[0] ) || agx::isNaN( m_data[1] ) || agx::isNaN( m_data[2] );
536 }
537
538
539 inline bool Vec3::isFinite() const
540 {
541 return agx::isFinite( m_data[0] ) && agx::isFinite( m_data[1] ) && agx::isFinite( m_data[2] );
542 }
543
544
545 inline double Vec3::operator * ( const Vec3& rhs ) const
546 {
547 return double(m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]);
548 }
549
550
551 inline const Vec3 Vec3::operator ^ ( const Vec3& rhs ) const
552 {
553 return Vec3( m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
554 m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2] ,
555 m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0] );
556 }
557
558
559 inline const Vec3 Vec3::cross(const Vec3& rhs) const
560 {
561 return Vec3(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
562 m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2],
563 m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]);
564 }
565
566
567 inline Vec3 Vec3::mul( const Vec3& lhs, const Vec3& rhs )
568 { return Vec3( lhs[0] * rhs[0],
569 lhs[1] * rhs[1],
570 lhs[2] * rhs[2] );
571 }
572
573
574 inline Vec3 Vec3::div( const Vec3& lhs, const Vec3& rhs )
575 {
576 return Vec3( lhs[0] / rhs[0],
577 lhs[1] / rhs[1],
578 lhs[2] / rhs[2] );
579 }
580
581
582
583 inline const Vec3 Vec3::operator * ( double rhs ) const
584 {
585 return Vec3( double(m_data[0] * rhs), double(m_data[1] * rhs), double(m_data[2] * rhs) );
586 }
587
588
589
590 inline Vec3& Vec3::operator *= ( double rhs )
591 {
592 m_data[0] = double(m_data[0] * rhs);
593 m_data[1] = double(m_data[1] * rhs);
594 m_data[2] = double(m_data[2] * rhs);
595 return *this;
596 }
597
598
599 inline const Vec3 Vec3::operator / ( double rhs ) const
600 {
601 return Vec3( double(m_data[0] / rhs), double(m_data[1] / rhs), double(m_data[2] / rhs) );
602 }
603
604
605 inline Vec3& Vec3::operator /= ( double rhs )
606 {
607 m_data[0] = double(m_data[0] / rhs);
608 m_data[1] = double(m_data[1] / rhs);
609 m_data[2] = double(m_data[2] / rhs);
610 return *this;
611 }
612
613
614
615 inline const Vec3 Vec3::operator + ( const Vec3& rhs ) const
616 {
617 return Vec3( m_data[0] + rhs[0], m_data[1] + rhs[1], m_data[2] + rhs[2] );
618 }
619
620
621 inline Vec3& Vec3::operator += ( const Vec3& rhs )
622 {
623 m_data[0] += rhs.m_data[0];
624 m_data[1] += rhs.m_data[1];
625 m_data[2] += rhs.m_data[2];
626 return *this;
627 }
628
629
630 inline const Vec3 Vec3::operator - ( const Vec3& rhs ) const
631 {
632 return Vec3( m_data[0] - rhs[0], m_data[1] - rhs[1], m_data[2] - rhs[2] );
633 }
634
635
636 inline Vec3& Vec3::operator -= ( const Vec3& rhs )
637 {
638 m_data[0] -= rhs.m_data[0];
639 m_data[1] -= rhs.m_data[1];
640 m_data[2] -= rhs.m_data[2];
641 return *this;
642 }
643
644
645 inline const Vec3 Vec3::operator + ( const double rhs ) const
646 {
647 return Vec3( m_data[0] + rhs, m_data[1] + rhs, m_data[2] + rhs );
648 }
649
650
651 inline Vec3& Vec3::operator += ( const double rhs )
652 {
653 m_data[0] += rhs;
654 m_data[1] += rhs;
655 m_data[2] += rhs;
656 return *this;
657 }
658
659
660 inline const Vec3 Vec3::operator - ( const double rhs ) const
661 {
662 return Vec3( m_data[0] - rhs, m_data[1] - rhs, m_data[2] - rhs );
663 }
664
665
666 inline Vec3& Vec3::operator -= ( const double rhs )
667 {
668 m_data[0] -= rhs;
669 m_data[1] -= rhs;
670 m_data[2] -= rhs;
671 return *this;
672 }
673
674
675 inline const Vec3 Vec3::operator - () const
676 {
677 return Vec3 ( -m_data[0], -m_data[1], -m_data[2] );
678 }
679
680
681 inline double Vec3::length() const
682 {
683 return std::sqrt( (m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2]) );
684 }
685
686
687 inline double Vec3::length2() const
688 {
689 return m_data[0] * m_data[0] + m_data[1] * m_data[1] + m_data[2] * m_data[2];
690 }
691
692
693 inline double Vec3::distance(const Vec3& v2) const
694 {
695 return std::sqrt(distance2(v2));
696 }
697
698
699 inline double Vec3::normalize()
700 {
701 return setLength(1.0);
702 }
703
704 inline double Vec3::setLength(double newLength)
705 {
706 double norm = Vec3::length();
707
708 if (norm > 0.0) {
709 double inv = newLength / norm;
710 m_data[0] = double(m_data[0] * inv);
711 m_data[1] = double(m_data[1] * inv);
712 m_data[2] = double(m_data[2] * inv);
713
714 }
715 return(norm);
716 }
717
718
719 inline Vec3 Vec3::normal() const
720 {
721 Vec3 normal = *this;
723 return normal;
724 }
725
726
727
729 {
730 return Vec3(1, 0, 0);
731 }
732
733
735 {
736 return Vec3(0, 1, 0);
737 }
738
739
741 {
742 return Vec3(0, 0, 1);
743 }
744
745
746 inline Vec3 Vec3::AXIS(int i)
747 {
748 Vec3 tmp;
749 tmp[i] = double(1);
750 return tmp;
751 }
752
753
754 inline Vec3 Vec3::random(double min, double max)
755 {
756 return Vec3(agx::random(min, max), agx::random(min, max), agx::random(min, max));
757 }
758
759
760 inline Vec3 Vec3::random(const Vec3& min, const Vec3& max)
761 {
762 return Vec3(agx::random(min[0], max[0]), agx::random(min[1], max[1]), agx::random(min[2], max[2]));
763 }
764#endif
765
766
767 inline bool equivalent( const Vec3& a, const Vec3& b, double epsilon = double(MOMENTUM_EQUIVALENT_EPSILON) )
768 {
769 return agx::equivalent(a[0], b[0], epsilon) &&
770 agx::equivalent(a[1], b[1], epsilon) &&
771 agx::equivalent(a[2], b[2], epsilon);
772 }
773
774
775 inline Vec3 absolute( const Vec3& a)
776 {
777 return Vec3(std::abs(a[0]),
778 std::abs(a[1]),
779 std::abs(a[2]));
780 }
781
782
783 inline Vec3 asin( const Vec3& a)
784 {
785 return Vec3(std::asin(a[0]),
786 std::asin(a[1]),
787 std::asin(a[2]));
788 }
789
790
791 inline Vec3 sinc( const Vec3& a)
792 {
793 return Vec3(agx::sinc(a[0]),
794 agx::sinc(a[1]),
795 agx::sinc(a[2]));
796 }
797
798 inline Vec3 operator* ( double val, const Vec3& vec )
799 {
800 return vec * val;
801 }
802
803
804 inline Vec3 max( const Vec3& lhs, const Vec3& rhs )
805 {
806 return Vec3::componentMax(lhs, rhs);
807 }
808
809
810 inline Vec3 min( const Vec3& lhs, const Vec3& rhs )
811 {
812 return Vec3::componentMin(lhs, rhs);
813 }
814
815#ifndef SWIG
816
817
818 inline std::ostream& operator << ( std::ostream& output, const Vec3& v )
819 {
820 output << v[0] << " " << v[1] << " " << v[2];
821 return output;
822 }
823
824
825 inline std::string Vec3::__str__() const
826 {
827 std::ostringstream stream;
828 stream << *this;
829 return stream.str();
830 }
831
832
833 inline double Vec3::distance2(const Vec3& v2) const
834 {
835 Vec3 diff(m_data[0] - v2.m_data[0], m_data[1] - v2.m_data[1], m_data[2] - v2.m_data[2]);
836 return diff.length2();
837 }
838#endif // "#ifndef SWIG"
839
840
841 inline Vec3 clamp( const Vec3& vec, const Vec3& minimum, const Vec3& maximum )
842 {
843 Vec3 result = vec;
844 result.clamp(minimum, maximum);
845 return result;
846 }
847
848} // end of namespace Momentum
849
850
851#endif
A 3 dimensional vector which can be used to define a point or a vector and contains basic arithmetic.
Definition: Vec3.h:40
Vec3 & operator+=(const Vec3 &rhs)
Unary vector add.
Definition: Vec3.h:621
double normalize()
Normalize the vector so that it has length unity.
Definition: Vec3.h:699
const Vec3 operator-() const
Negation operator.
Definition: Vec3.h:675
void setY(double value)
set the y element of this vector
Definition: Vec3.h:515
double length2() const
Definition: Vec3.h:687
const Vec3 operator+(const Vec3 &rhs) const
Binary vector add.
Definition: Vec3.h:615
double setLength(double l)
Scale the vector so that is has the specified length.
Definition: Vec3.h:704
double minComponent() const
Definition: Vec3.h:400
bool isNaN() const
Definition: Vec3.h:533
static Vec3 div(const Vec3 &lhs, const Vec3 &rhs)
Element-wise-division.
Definition: Vec3.h:574
double distance2(const Vec3 &v2) const
Definition: Vec3.h:833
bool isFinite() const
Definition: Vec3.h:539
double y() const
Definition: Vec3.h:497
void set(double x, double y, double z)
Set the value of this vector with the specified elements.
Definition: Vec3.h:457
Vec3 normal() const
Definition: Vec3.h:719
static Vec3 componentMin(const Vec3 &v1, const Vec3 &v2)
Creates a new vector where each component is the minimum of this and the other vector.
Definition: Vec3.h:388
Vec3 & operator-=(const Vec3 &rhs)
Unary vector subtract.
Definition: Vec3.h:636
int minElement() const
Definition: Vec3.h:412
double distance(const Vec3 &v2) const
Definition: Vec3.h:693
Vec3()
Default constructor.
Definition: Vec3.h:340
double Type
Definition: Vec3.h:42
const Vec3 operator/(double rhs) const
Divide by scalar.
Definition: Vec3.h:599
void setX(double value)
set the x element of this vector
Definition: Vec3.h:509
bool isValid() const
Definition: Vec3.h:527
double maxComponent() const
Definition: Vec3.h:406
bool equalsZero() const
Definition: Vec3.h:450
Vec3 & operator/=(double rhs)
Unary divide by scalar.
Definition: Vec3.h:605
bool operator==(const Vec3 &v) const
Equality test.
Definition: Vec3.h:375
double length() const
Definition: Vec3.h:681
void clamp(const Vec3 &min, const Vec3 &max)
Clamp a vector between a lower and upper bound (per component).
Definition: Vec3.h:442
const Vec3 operator^(const Vec3 &rhs) const
Definition: Vec3.h:551
int maxElement() const
Definition: Vec3.h:427
double & operator[](int i)
\access the ith element of this vector
Definition: Vec3.h:479
static Vec3 X_AXIS()
Definition: Vec3.h:728
bool operator!=(const Vec3 &v) const
In-equality test.
Definition: Vec3.h:381
Vec3 & operator*=(double rhs)
Unary multiply by scalar.
Definition: Vec3.h:590
void setZ(double value)
set the z element of this vector
Definition: Vec3.h:521
static Vec3 random(double min=double(0), double max=double(1))
Definition: Vec3.h:754
double z() const
Definition: Vec3.h:503
static Vec3 Y_AXIS()
Definition: Vec3.h:734
static Vec3 Z_AXIS()
Definition: Vec3.h:740
static Vec3 mul(const Vec3 &lhs, const Vec3 &rhs)
Element-wise-multiplication.
Definition: Vec3.h:567
static Vec3 componentMax(const Vec3 &v1, const Vec3 &v2)
Creates a new vector where each component is the maximum of this and the other vector.
Definition: Vec3.h:394
static Vec3 AXIS(int i)
Definition: Vec3.h:746
double x() const
Definition: Vec3.h:491
const Vec3 cross(const Vec3 &rhs) const
Definition: Vec3.h:559
double operator*(const Vec3 &rhs) const
Definition: Vec3.h:545
Namespace for Momentum Scripting API.
Definition: AffineMatrix4x4.h:29
const double MOMENTUM_EQUIVALENT_EPSILON
Definition: momentum_math.h:30
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
Vec3 min(const Vec3 &lhs, const Vec3 &rhs)
Definition: Vec3.h:810
Vec3 asin(const Vec3 &a)
Definition: Vec3.h:783
Vec3 absolute(const Vec3 &a)
Definition: Vec3.h:775
Vec3 clamp(const Vec3 &vec, const Vec3 &minimum, const Vec3 &maximum)
Definition: Vec3.h:841
Vec3 sinc(const Vec3 &a)
Definition: Vec3.h:791
bool equivalent(const Matrix3x3 &a, const Matrix3x3 &b, double epsilon=1e-6)
Definition: Matrix3x3.h:905
Definition: Statistic.h:23