KrisLibrary  1.0.0
math3d/primitives.h
Go to the documentation of this file.
1 #ifndef MATH3D_PRIMITIVES_H
2 #define MATH3D_PRIMITIVES_H
3 
5 #include <KrisLibrary/utils.h>
6 #include <iosfwd>
7 class File;
8 
21 namespace Math3D {
22 
25 
26 using namespace Math;
27 
28 class Vector2;
29 class Vector3;
30 class Vector4;
31 class Matrix2;
32 class Matrix3;
33 class Matrix4;
34 class RigidTransform2D;
35 class RigidTransform;
36 
41 class Vector2
42 {
43  public:
44  Vector2();
45  Vector2(const Vector2&);
46  Vector2(Real x);
47  Vector2(Real x, Real y);
48  explicit Vector2(const Real* data);
49 
50  inline bool operator == (const Vector2&) const;
51  inline bool operator != (const Vector2&) const;
52  inline const Vector2& operator = (const Vector2&);
53  inline void operator += (const Vector2&);
54  inline void operator -= (const Vector2&);
55  inline void operator *= (Real);
56  inline void operator /= (Real);
57  inline Real& operator [] (int);
58  inline const Real& operator [] (int) const;
59  inline operator Real* ();
60  inline operator const Real* () const;
61 
62  inline void add(const Vector2& a, const Vector2& b);
63  inline void sub(const Vector2& a, const Vector2& b);
64  inline void mul(const Vector2& a, Real b);
65  inline void div(const Vector2& a, Real b);
66  inline void madd(const Vector2& a, Real b);
67  inline Real dot(const Vector2& a) const;
68  inline Real cross(const Vector2& a) const;
69  inline Real distance(const Vector2& a) const;
70  inline Real distanceSquared(const Vector2& a) const;
71  inline Real norm() const;
72  inline Real normSquared() const;
73  inline Real length() const;
74  inline Real minElement(int* index=NULL) const;
75  inline Real maxElement(int* index=NULL) const;
76  inline Real minAbsElement(int* index=NULL) const;
77  inline Real maxAbsElement(int* index=NULL) const;
78 
79  inline void set(const Vector2&);
80  inline void set(Real x);
81  inline void set(Real x, Real y);
82  inline void set(const Real* data);
83  inline void setZero();
84  inline void setRotation(Real rads);
85  inline void setPerpendicular(const Vector2&);
86  inline void setOrthogonal(const Vector2& v) { setPerpendicular(v); }
87  inline void setNegative(const Vector2&);
88  inline void setNormalized(const Vector2&);
89  inline void setProjection(const Vector2&, const Vector2&);
90  inline void setMinimum(const Vector2&,const Vector2&);
91  inline void setMinimum(const Vector2&);
92  inline void setMaximum(const Vector2&,const Vector2&);
93  inline void setMaximum(const Vector2&);
94 
95  inline void get(Vector2&) const;
96  inline void get(Real& x, Real& y) const;
97  inline void get(Real data[2]) const;
98  inline void getNegative(Vector2&) const;
99  inline void getNormalized(Vector2&) const;
100  inline void getOrthogonal(Vector2&) const;
101 
102  inline void inplaceNegative();
103  inline void inplaceMul(Real);
104  inline void inplaceDiv(Real);
105  inline void inplaceNormalize();
106 
107  inline bool isZero(Real eps=Zero) const;
108  inline bool isEqual(const Vector2&,Real eps=Zero) const;
109 
110  bool Read(File&);
111  bool Write(File&) const;
112 
113  union {
114  Real data[2];
115  struct { Real x,y; };
116  };
117 };
118 
119 inline Real dot(const Vector2& a, const Vector2& b);
120 inline Real cross(const Vector2& a, const Vector2& b);
121 inline void normalize(Vector2& a);
122 inline Vector2 project(const Vector2& a, const Vector2& b);
123 inline Vector2 operator - (const Vector2& a);
124 inline Vector2 operator + (const Vector2& a, const Vector2& b);
125 inline Vector2 operator - (const Vector2& a, const Vector2& b);
126 inline Vector2 operator * (const Vector2& a, Real b);
127 inline Vector2 operator * (Real a, const Vector2& b);
128 inline Vector2 operator / (const Vector2& a, Real b);
129 
130 
136 class Vector3
137 {
138  public:
139  Vector3();
140  Vector3(const Vector3&);
141  Vector3(Real x);
142  Vector3(Real x, Real y, Real z);
143  explicit Vector3(const Real* data);
144 
145  inline bool operator == (const Vector3&) const;
146  inline bool operator != (const Vector3&) const;
147  inline const Vector3& operator = (const Vector3&);
148  inline void operator += (const Vector3&);
149  inline void operator -= (const Vector3&);
150  inline void operator *= (Real);
151  inline void operator /= (Real);
152  inline Real& operator [] (int);
153  inline const Real& operator [] (int) const;
154  inline operator Real* ();
155  inline operator const Real* () const;
156 
157  inline void add(const Vector3& a, const Vector3& b);
158  inline void sub(const Vector3& a, const Vector3& b);
159  inline void mul(const Vector3& a, Real b);
160  inline void div(const Vector3& a, Real b);
161  inline void madd(const Vector3& a, Real b);
162  inline Real dot(const Vector3& a) const;
163  inline Real distance(const Vector3& a) const;
164  inline Real distanceSquared(const Vector3& a) const;
165  inline Real norm() const;
166  inline Real normSquared() const;
167  inline Real length() const;
168  inline Real minElement(int* index=NULL) const;
169  inline Real maxElement(int* index=NULL) const;
170  inline Real minAbsElement(int* index=NULL) const;
171  inline Real maxAbsElement(int* index=NULL) const;
172 
173  inline void set(const Vector3&);
174  inline void set(Real x);
175  inline void set(Real x, Real y, Real z);
176  inline void set(const Real* data);
177  inline void setZero();
178  inline void setNegative(const Vector3&);
179  inline void setCross(const Vector3&, const Vector3&);
180  inline void setNormalized(const Vector3&);
181  inline void setProjection(const Vector3&, const Vector3&);
182  inline void setMinimum(const Vector3&,const Vector3&);
183  inline void setMinimum(const Vector3&);
184  inline void setMaximum(const Vector3&,const Vector3&);
185  inline void setMaximum(const Vector3&);
186 
187  inline void get(Vector3&) const;
188  inline void get(Real& x, Real& y, Real& z) const;
189  inline void get(Real data[3]) const;
190  inline void getNegative(Vector3&) const;
191  inline void getNormalized(Vector3&) const;
192  inline void getOrthogonalBasis(Vector3& yb,Vector3& zb) const;
193 
194  inline void inplaceNegative();
195  inline void inplaceMul(Real);
196  inline void inplaceDiv(Real);
197  inline void inplaceNormalize();
198 
199  inline bool isZero(Real eps=Zero) const;
200  inline bool isEqual(const Vector3&,Real eps=Zero) const;
201 
202  bool Read(File&);
203  bool Write(File&) const;
204 
205  union {
206  Real data[3];
207  struct { Real x,y,z; };
208  };
209 };
210 
211 inline Real dot(const Vector3& a, const Vector3& b);
212 inline Vector3 cross(const Vector3& a, const Vector3& b);
213 inline void normalize(Vector3& a);
214 inline Vector3 project(const Vector3& a, const Vector3& b);
215 inline Vector3 operator - (const Vector3& a);
216 inline Vector3 operator + (const Vector3& a, const Vector3& b);
217 inline Vector3 operator - (const Vector3& a, const Vector3& b);
218 inline Vector3 operator * (const Vector3& a, Real b);
219 inline Vector3 operator * (Real a, const Vector3& b);
220 inline Vector3 operator / (const Vector3& a, Real b);
221 
222 
228 class Vector4
229 {
230  public:
231  Vector4();
232  Vector4(const Vector4&);
233  Vector4(Real x);
234  Vector4(Real x, Real y, Real z, Real w = One);
235  explicit Vector4(const Real* data);
236  explicit Vector4(const Vector3&); //point in homogeneous coords
237 
238  inline bool operator == (const Vector4&) const;
239  inline bool operator != (const Vector4&) const;
240  inline const Vector4& operator = (const Vector4&);
241  inline void operator += (const Vector4&);
242  inline void operator -= (const Vector4&);
243  inline void operator *= (Real);
244  inline void operator /= (Real);
245  inline void operator += (const Vector3&);
246  inline void operator -= (const Vector3&);
247  inline Real& operator [] (int);
248  inline const Real& operator [] (int) const;
249  inline operator Vector3() const;
250  inline operator Real* ();
251  inline operator const Real* () const;
252 
253  inline void add(const Vector4& a, const Vector4& b);
254  inline void sub(const Vector4& a, const Vector4& b);
255  inline void mul(const Vector4& a, Real b);
256  inline void div(const Vector4& a, Real b);
257  inline void madd(const Vector4& a, Real b);
258  inline void add(const Vector4& a, const Vector3& b);
259  inline void sub(const Vector4& a, const Vector3& b);
260  inline Real dot(const Vector4& a) const;
261  inline Real dot3(const Vector4& a) const;
262  inline Real dot3(const Vector3& a) const;
263  inline Real distance(const Vector4& a) const;
264  inline Real distanceSquared(const Vector4& a) const;
265  inline Real norm() const;
266  inline Real normSquared() const;
267  inline Real length() const; // = norm
268  inline Real minElement(int* index=NULL) const;
269  inline Real maxElement(int* index=NULL) const;
270  inline Real minAbsElement(int* index=NULL) const;
271  inline Real maxAbsElement(int* index=NULL) const;
272 
273  inline void set(const Vector4&);
274  inline void set(Real x);
275  inline void set(Real x, Real y, Real z, Real w = One);
276  inline void set(const Real* data);
277  inline void setZero();
278  inline void setVector(const Vector3&);
279  inline void setHomogeneous(const Vector3&);
280  inline void setNegative(const Vector4&);
281  inline void setNormalized(const Vector4&);
282  inline void setProjection(const Vector4&, const Vector4&);
283  inline void setMinimum(const Vector4&,const Vector4&);
284  inline void setMinimum(const Vector4&);
285  inline void setMaximum(const Vector4&,const Vector4&);
286  inline void setMaximum(const Vector4&);
287 
288  inline void get(Vector4&) const;
289  inline void get(Real& x, Real& y, Real& z, Real& w) const;
290  inline void get(Real data[4]) const;
291  inline void get(Vector3&) const;
292  inline void getNegative(Vector4&) const;
293  inline void getNormalized(Vector4&) const;
294 
295  inline void inplaceNegative();
296  inline void inplaceMul(Real);
297  inline void inplaceDiv(Real);
298  inline void inplaceNormalize();
299 
300  inline bool isZero(Real eps=Zero) const;
301  inline bool isEqual(const Vector4&,Real eps=Zero) const;
302 
303  bool Read(File&);
304  bool Write(File&) const;
305 
306  union {
307  Real data[4];
308  struct { Real x,y,z,w; };
309  };
310 };
311 
312 inline Real dot(const Vector4& a, const Vector4& b);
313 inline Real dot3(const Vector4& a, const Vector4& b);
314 inline Real dot3(const Vector4& a, const Vector3& b);
315 inline Real dot3(const Vector3& a, const Vector4& b);
316 inline void normalize(Vector4& a);
317 inline Vector4 project(const Vector4& a, const Vector4& b);
318 inline Vector4 operator - (const Vector4& a);
319 inline Vector4 operator + (const Vector4& a, const Vector4& b);
320 inline Vector4 operator - (const Vector4& a, const Vector4& b);
321 inline Vector4 operator * (const Vector4& a, Real b);
322 inline Vector4 operator * (Real a, const Vector4& b);
323 inline Vector4 operator / (const Vector4& a, Real b);
324 
325 
333 class Matrix2
334 {
335  public:
336  Matrix2();
337  Matrix2(const Matrix2&);
338  explicit Matrix2(Real);
339  explicit Matrix2(const Real [2][2]);
340  explicit Matrix2(const Real *);
341  Matrix2(const Vector2& xb, const Vector2& yb);
342 
343  bool operator == (const Matrix2&) const;
344  bool operator != (const Matrix2&) const;
345  inline const Matrix2& operator = (const Matrix2&);
346  inline void operator += (const Matrix2&);
347  inline void operator -= (const Matrix2&);
348  inline void operator *= (const Matrix2&);
349  inline void operator *= (Real scale);
350  inline void operator /= (Real scale);
351  operator const Real*() const { return &data[0][0]; }
352  inline Real& operator () (int i, int j) { return data[j][i]; }
353  inline const Real& operator () (int i, int j) const { return data[j][i]; }
354 
357  inline void add(const Matrix2& a, const Matrix2& b);
358  inline void sub(const Matrix2& a, const Matrix2& b);
359  inline void mul(const Matrix2& a, const Matrix2& b);
360  inline void mulTransposeA(const Matrix2& a, const Matrix2& b);
361  inline void mulTransposeB(const Matrix2& a, const Matrix2& b);
363 
366  inline void mul(const Matrix2& a, Real b);
367  inline void div(const Matrix2& a, Real b);
369 
372  inline void mul(const Vector2& a, Vector2& out) const; //result is incorrect if out = a
373  inline void mulTranspose(const Vector2& a, Vector2& out) const; //result is incorrect if out = a
375 
376  inline void set(const Matrix2&);
377  inline void set(Real);
378  inline void set(const Real [2][2]);
379  inline void set(const Real*);
380  inline void set(const Vector2& xb, const Vector2& yb);
381  inline void setZero();
382  inline void setIdentity();
383  inline void setDiagonal(const Vector2&);
384  inline void setTranspose(const Matrix2&);
385  inline void setNegative(const Matrix2&);
386  inline bool setInverse(const Matrix2&);
387  inline void setScale(Real s);
388  inline void setScale(Real sx, Real sy);
389  inline void setRotate(Real rads);
390  inline void setOuterProduct(const Vector2& a,const Vector2& b);
391 
392  inline void get(Matrix2&) const;
393  inline void get(Real [2][2]) const;
394  inline void get(Real [4]) const;
395  inline void get(Vector2& xb, Vector2& yb) const;
396  inline void getTranspose(Matrix2&) const;
397  inline void getNegative(Matrix2&) const;
398  inline bool getInverse(Matrix2&) const;
399 
400  inline void inplaceTranspose();
401  inline void inplaceNegative();
402  inline bool inplaceInverse();
403  inline void inplaceMul(Real s);
404  inline void inplaceDiv(Real s);
405  inline void inplaceRowScale(Real sx, Real sy);
406  inline void inplaceColScale(Real sx, Real sy);
407 
408  inline bool isZero(Real eps=Zero) const;
409  inline bool isIdentity(Real eps=Zero) const;
410  inline bool isEqual(const Matrix2&,Real eps=Zero) const;
411  inline bool isInvertible(Real eps=Zero) const;
412  inline Real determinant() const;
413  inline Real trace() const;
414  inline Real minElement(int* i=NULL,int* j=NULL) const;
415  inline Real maxElement(int* i=NULL,int* j=NULL) const;
416  inline Real minAbsElement(int* i=NULL,int* j=NULL) const;
417  inline Real maxAbsElement(int* i=NULL,int* j=NULL) const;
418 
419  bool Read(File&);
420  bool Write(File&) const;
421 
422  inline Real* col(int j) { return data[j]; }
423  inline Real* col1() { return data[0]; }
424  inline Real* col2() { return data[1]; }
425  inline const Real* col(int j) const { return data[j]; }
426  inline const Real* col1() const { return data[0]; }
427  inline const Real* col2() const { return data[1]; }
428 
429  inline void setCol(int j, const Vector2& v) { v.get(data[j]); }
430  inline void setCol1(const Vector2& v) { v.get(data[0]); }
431  inline void setCol2(const Vector2& v) { v.get(data[1]); }
432 
433  inline void setRow(int i, const Vector2& v) { v.get(data[0][i], data[1][i]); }
434  inline void setRow1(const Vector2& v) { v.get(data[0][0], data[1][0]); }
435  inline void setRow2(const Vector2& v) { v.get(data[0][1], data[1][1]); }
436 
437  inline void getCol(int j, Vector2& v) const { v.set(data[j]); }
438  inline void getCol1(Vector2& v) const { v.set(data[0]); }
439  inline void getCol2(Vector2& v) const { v.set(data[1]); }
440 
441  inline void getRow(int i, Vector2& v) const { v.set(data[0][i], data[1][i]); }
442  inline void getRow1(Vector2& v) const { v.set(data[0][0], data[1][0]); }
443  inline void getRow2(Vector2& v) const { v.set(data[0][1], data[1][1]); }
444 
445  inline Vector2 getXBasis() const { return Vector2(col1()); }
446  inline Vector2 getYBasis() const { return Vector2(col2()); }
447 
449  Real data[2][2];
450 };
451 
452 inline Real determinant(const Matrix2&);
453 inline Real trace(const Matrix2&);
454 inline Matrix2 operator + (const Matrix2& a, const Matrix2& b);
455 inline Matrix2 operator - (const Matrix2& a, const Matrix2& b);
456 inline Matrix2 operator * (const Matrix2& a, const Matrix2& b);
457 inline Vector2 operator * (const Matrix2& a, const Vector2& b);
458 inline Vector2 operator * (const Vector2& a, const Matrix2& b);
459 
460 
461 
469 class Matrix3
470 {
471  public:
472  Matrix3();
473  Matrix3(const Matrix3&);
474  explicit Matrix3(Real);
475  explicit Matrix3(const Real [3][3]);
476  explicit Matrix3(const Real *);
477  Matrix3(const Vector3& xb, const Vector3& yb, const Vector3& zb);
478 
479  bool operator == (const Matrix3&) const;
480  bool operator != (const Matrix3&) const;
481  inline const Matrix3& operator = (const Matrix3&);
482  inline void operator += (const Matrix3&);
483  inline void operator -= (const Matrix3&);
484  inline void operator *= (const Matrix3&);
485  inline void operator *= (Real scale);
486  inline void operator /= (Real scale);
487  operator const Real*() const { return &data[0][0]; }
488  inline Real& operator () (int i, int j) { return data[j][i]; }
489  inline const Real& operator () (int i, int j) const { return data[j][i]; }
490 
493  inline void add(const Matrix3& a, const Matrix3& b);
494  inline void sub(const Matrix3& a, const Matrix3& b);
495  void mul(const Matrix3& a, const Matrix3& b);
496  void mulTransposeA(const Matrix3& a, const Matrix3& b);
497  void mulTransposeB(const Matrix3& a, const Matrix3& b);
499 
502  inline void mul(const Matrix3& a, Real b);
503  inline void div(const Matrix3& a, Real b);
504 
507  inline void mul(const Vector3& a, Vector3& out) const;
508  inline void mulTranspose(const Vector3& a, Vector3& out) const;
509 
513  inline void mulPoint(const Vector2& a, Vector2& out) const;
514  inline void mulVector(const Vector2& a, Vector2& out) const;
515  inline void mulVectorTranspose(const Vector2& a, Vector2& out) const;
516 
518  inline void set(const Matrix3&);
519  inline void set(Real);
520  inline void set(const Real [3][3]);
521  inline void set(const Real [9]);
522  inline void set(const Vector3& xb, const Vector3& yb, const Vector3& zb);
523  inline void setZero();
524  inline void setIdentity();
525  inline void setDiagonal(const Vector3&);
526  inline void setTranspose(const Matrix3&);
527  inline void setNegative(const Matrix3&);
528  bool setInverse(const Matrix3&);
529  inline void setScale(Real s);
530  inline void setScale(Real sx, Real sy, Real sz);
531  inline void setCrossProduct(const Vector3&);
532  inline void setRotateX(Real rads);
533  inline void setRotateY(Real rads);
534  inline void setRotateZ(Real rads);
535  inline void setOuterProduct(const Vector3& a,const Vector3& b);
536 
537  inline void get(Matrix3&) const;
538  inline void get(Real [3][3]) const;
539  inline void get(Real [9]) const;
540  inline void get(Vector3& xb, Vector3& yb, Vector3& zb) const;
541  inline void getTranspose(Matrix3&) const;
542  inline void getNegative(Matrix3&) const;
543  inline bool getInverse(Matrix3&) const;
544  inline void getCrossProduct(Vector3&) const;
545 
546  inline void inplaceTranspose();
547  inline void inplaceNegative();
548  inline bool inplaceInverse();
549  inline void inplaceMul(Real s);
550  inline void inplaceDiv(Real s);
551  inline void inplaceRowScale(Real sx, Real sy, Real sz);
552  inline void inplaceColScale(Real sx, Real sy, Real sz);
553 
554  inline bool isZero(Real eps=Zero) const;
555  inline bool isIdentity(Real eps=Zero) const;
556  inline bool isEqual(const Matrix3&,Real eps=Zero) const;
557  inline bool isInvertible(Real eps=Zero) const;
558  Real cofactor(int i, int j) const;
559  Real determinant() const;
560  inline Real trace() const;
561  inline Real minElement(int* i=NULL,int* j=NULL) const;
562  inline Real maxElement(int* i=NULL,int* j=NULL) const;
563  inline Real minAbsElement(int* i=NULL,int* j=NULL) const;
564  inline Real maxAbsElement(int* i=NULL,int* j=NULL) const;
565 
566  bool Read(File&);
567  bool Write(File&) const;
568 
569  inline Real* col(int j) { return data[j]; }
570  inline Real* col1() { return data[0]; }
571  inline Real* col2() { return data[1]; }
572  inline Real* col3() { return data[2]; }
573  inline const Real* col(int j) const { return data[j]; }
574  inline const Real* col1() const { return data[0]; }
575  inline const Real* col2() const { return data[1]; }
576  inline const Real* col3() const { return data[2]; }
577 
578  inline void setCol(int j, const Vector3& v) { v.get(data[j]); }
579  inline void setCol1(const Vector3& v) { v.get(data[0]); }
580  inline void setCol2(const Vector3& v) { v.get(data[1]); }
581  inline void setCol3(const Vector3& v) { v.get(data[2]); }
582 
583  inline void setRow(int i, const Vector3& v) { v.get(data[0][i], data[1][i], data[2][i]); }
584  inline void setRow1(const Vector3& v) { v.get(data[0][0], data[1][0], data[2][0]); }
585  inline void setRow2(const Vector3& v) { v.get(data[0][1], data[1][1], data[2][1]); }
586  inline void setRow3(const Vector3& v) { v.get(data[0][2], data[1][2], data[2][2]); }
587 
588  inline void getCol(int j, Vector3& v) const { v.set(data[j]); }
589  inline void getCol1(Vector3& v) const { v.set(data[0]); }
590  inline void getCol2(Vector3& v) const { v.set(data[1]); }
591  inline void getCol3(Vector3& v) const { v.set(data[2]); }
592 
593  inline void getRow(int i, Vector3& v) const { v.set(data[0][i], data[1][i], data[2][i]); }
594  inline void getRow1(Vector3& v) const { v.set(data[0][0], data[1][0], data[2][0]); }
595  inline void getRow2(Vector3& v) const { v.set(data[0][1], data[1][1], data[2][1]); }
596  inline void getRow3(Vector3& v) const { v.set(data[0][2], data[1][2], data[2][2]); }
597 
598  inline Vector3 getXBasis() const { return Vector3(col1()); }
599  inline Vector3 getYBasis() const { return Vector3(col2()); }
600  inline Vector3 getZBasis() const { return Vector3(col3()); }
601 
602  inline Vector2 getXBasis2D() const { return Vector2(col1()); }
603  inline Vector2 getYBasis2D() const { return Vector2(col2()); }
604  inline Vector2 getTranslation2D() const { return Vector2(col3()); }
605 
607  Real data[3][3];
608 };
609 
610 inline Real determinant(const Matrix3&);
611 inline Real trace(const Matrix3&);
612 inline Matrix3 operator + (const Matrix3& a, const Matrix3& b);
613 inline Matrix3 operator - (const Matrix3& a, const Matrix3& b);
614 inline Matrix3 operator * (const Matrix3& a, const Matrix3& b);
615 inline Vector3 operator * (const Matrix3& a, const Vector3& b);
616 inline Vector3 operator * (const Vector3& a, const Matrix3& b);
617 
618 
626 class Matrix4
627 {
628  public:
629  Matrix4();
630  Matrix4(const Matrix4&);
631  explicit Matrix4(Real);
632  explicit Matrix4(const Real [4][4]);
633  explicit Matrix4(const Real *);
634  explicit Matrix4(const Vector3& xb, const Vector3& yb, const Vector3& zb, const Vector3& trans);
635  explicit Matrix4(const Vector4& x, const Vector4& y, const Vector4& z, const Vector4& w);
636  explicit Matrix4(const Matrix3&);
637  explicit Matrix4(const Matrix3&, const Vector3& trans);
638  explicit Matrix4(const Vector3& trans);
639 
640  bool operator == (const Matrix4&) const;
641  bool operator != (const Matrix4&) const;
642  inline const Matrix4& operator = (const Matrix4&);
643  inline void operator += (const Matrix4&);
644  inline void operator -= (const Matrix4&);
645  inline void operator *= (const Matrix4&);
646  inline void operator *= (Real scale);
647  inline void operator /= (Real scale);
648  operator Matrix3() const;
649  inline operator const Real*() const { return &data[0][0]; }
650  inline Real& operator () (int i, int j) { return data[j][i]; }
651  inline const Real& operator () (int i, int j) const { return data[j][i]; }
652 
655  inline void add(const Matrix4& a, const Matrix4& b);
656  inline void sub(const Matrix4& a, const Matrix4& b);
657  void mul(const Matrix4& a, const Matrix4& b);
658  void mulTransposeA(const Matrix4& a, const Matrix4& b);
659  void mulTransposeB(const Matrix4& a, const Matrix4& b);
661 
664  inline void mul(const Matrix4& a, Real b);
665  inline void div(const Matrix4& a, Real b);
667 
668  //vector ops (out = this op a)
670  inline void mul(const Vector4& a, Vector4& out) const;
671  inline void mulTranspose(const Vector4& a, Vector4& out) const;
673 
676  inline void mulPoint(const Vector3& a, Vector3& out) const;
677  inline void mulVector(const Vector3& a, Vector3& out) const;
678  inline void mulVectorTranspose(const Vector3& a, Vector3& out) const;
679 
681  inline void set(const Matrix4&);
682  inline void set(Real);
683  inline void set(const Real [4][4]);
684  inline void set(const Real *);
685  inline void set(const Vector3& xb, const Vector3& yb, const Vector3& zb, const Vector3& trans);
686  inline void set(const Vector4& x, const Vector4& y, const Vector4& z, const Vector4& w);
687  inline void set(const Matrix3&);
688  inline void set(const Matrix3&, const Vector3& trans);
689  inline void setZero();
690  inline void setIdentity();
691  inline void setDiagonal(const Vector4&);
692  inline void setTranslate(const Vector3& trans);
693  inline void setTranspose(const Matrix4&);
694  inline void setNegative(const Matrix4&);
695  bool setInverse(const Matrix4&);
696  inline void setOuterProduct(const Vector4& a,const Vector4& b);
697 
698  inline void get(Matrix4&) const;
699  inline void get(Real [4][4]) const;
700  inline void get(Real [16]) const;
701  inline void get(Vector3& xb, Vector3& yb, Vector3& zb, Vector3& trans) const;
702  inline void get(Vector4& x, Vector4& y, Vector4& z, Vector4& w) const;
703  inline void get(Matrix3&) const;
704  inline void get(Matrix3&, Vector3&) const;
705  inline void getTranspose(Matrix4&) const;
706  inline void getNegative(Matrix4&) const;
707  inline bool getInverse(Matrix4&) const;
708 
709  inline void inplaceTranspose();
710  inline void inplaceNegative();
711  inline bool inplaceInverse();
712  inline void inplaceMul(Real s);
713  inline void inplaceDiv(Real s);
714 
715  inline bool isZero(Real eps=Zero) const;
716  inline bool isIdentity(Real eps=Zero) const;
717  inline bool isEqual(const Matrix4&,Real eps=Zero) const;
718  inline bool isInvertible(Real eps=Zero) const;
719  Real cofactor(int i, int j) const;
720  Real determinant() const;
721  inline Real trace() const;
722  inline Real minElement(int* i=NULL,int* j=NULL) const;
723  inline Real maxElement(int* i=NULL,int* j=NULL) const;
724  inline Real minAbsElement(int* i=NULL,int* j=NULL) const;
725  inline Real maxAbsElement(int* i=NULL,int* j=NULL) const;
726 
727  bool Read(File&);
728  bool Write(File&) const;
729 
730  inline Real* col(int j) { return data[j]; }
731  inline Real* col1() { return data[0]; }
732  inline Real* col2() { return data[1]; }
733  inline Real* col3() { return data[2]; }
734  inline Real* col4() { return data[3]; }
735  inline const Real* col(int j) const { return data[j]; }
736  inline const Real* col1() const { return data[0]; }
737  inline const Real* col2() const { return data[1]; }
738  inline const Real* col3() const { return data[2]; }
739  inline const Real* col4() const { return data[3]; }
740 
741  inline void setCol(int j, const Vector4& v) { v.get(data[j]); }
742  inline void setCol1(const Vector4& v) { v.get(data[0]); }
743  inline void setCol2(const Vector4& v) { v.get(data[1]); }
744  inline void setCol3(const Vector4& v) { v.get(data[2]); }
745  inline void setCol4(const Vector4& v) { v.get(data[3]); }
746  inline void setCol(int j, const Vector3& v) { v.get(data[j]); }
747  inline void setCol1(const Vector3& v) { v.get(data[0]); }
748  inline void setCol2(const Vector3& v) { v.get(data[1]); }
749  inline void setCol3(const Vector3& v) { v.get(data[2]); }
750  inline void setCol4(const Vector3& v) { v.get(data[3]); }
751 
752  inline void setRow(int i, const Vector4& v) { v.get(data[0][i], data[1][i], data[2][i], data[3][i]); }
753  inline void setRow1(const Vector4& v) { v.get(data[0][0], data[1][0], data[2][0], data[3][0]); }
754  inline void setRow2(const Vector4& v) { v.get(data[0][1], data[1][1], data[2][1], data[3][1]); }
755  inline void setRow3(const Vector4& v) { v.get(data[0][2], data[1][2], data[2][2], data[3][2]); }
756  inline void setRow4(const Vector4& v) { v.get(data[0][3], data[1][3], data[2][3], data[3][3]); }
757  inline void setRow(int i, const Vector3& v) { v.get(data[0][i], data[1][i], data[2][i]); }
758  inline void setRow1(const Vector3& v) { v.get(data[0][0], data[1][0], data[2][0]); }
759  inline void setRow2(const Vector3& v) { v.get(data[0][1], data[1][1], data[2][1]); }
760  inline void setRow3(const Vector3& v) { v.get(data[0][2], data[1][2], data[2][2]); }
761  inline void setRow4(const Vector3& v) { v.get(data[0][3], data[1][3], data[2][3]); }
762 
763  inline void getCol(int j, Vector4& v) const { v.set(data[j]); }
764  inline void getCol1(Vector4& v) const { v.set(data[0]); }
765  inline void getCol2(Vector4& v) const { v.set(data[1]); }
766  inline void getCol3(Vector4& v) const { v.set(data[2]); }
767  inline void getCol4(Vector4& v) const { v.set(data[3]); }
768  inline void getCol(int j, Vector3& v) const { v.set(data[j]); }
769  inline void getCol1(Vector3& v) const { v.set(data[0]); }
770  inline void getCol2(Vector3& v) const { v.set(data[1]); }
771  inline void getCol3(Vector3& v) const { v.set(data[2]); }
772  inline void getCol4(Vector3& v) const { v.set(data[3]); }
773 
774  inline void getRow(int i, Vector4& v) const { v.set(data[0][i], data[1][i], data[2][i], data[3][i]); }
775  inline void getRow1(Vector4& v) const { v.set(data[0][0], data[1][0], data[2][0], data[3][0]); }
776  inline void getRow2(Vector4& v) const { v.set(data[0][1], data[1][1], data[2][1], data[3][1]); }
777  inline void getRow3(Vector4& v) const { v.set(data[0][2], data[1][2], data[2][2], data[3][2]); }
778  inline void getRow4(Vector4& v) const { v.set(data[0][3], data[1][3], data[2][3], data[3][3]); }
779  inline void getRow(int i, Vector3& v) const { v.set(data[0][i], data[1][i], data[2][i]); }
780  inline void getRow1(Vector3& v) const { v.set(data[0][0], data[1][0], data[2][0]); }
781  inline void getRow2(Vector3& v) const { v.set(data[0][1], data[1][1], data[2][1]); }
782  inline void getRow3(Vector3& v) const { v.set(data[0][2], data[1][2], data[2][2]); }
783  inline void getRow4(Vector3& v) const { v.set(data[0][3], data[1][3], data[2][3]); }
784 
786  inline Vector3 getXBasis() const { return Vector3(col1()); }
787  inline Vector3 getYBasis() const { return Vector3(col2()); }
788  inline Vector3 getZBasis() const { return Vector3(col3()); }
789  inline Vector3 getTranslation() const { return Vector3(col4()); }
790 
792  Real data[4][4];
793 };
794 
795 inline Real determinant(const Matrix4&);
796 inline Real trace(const Matrix4&);
797 inline Matrix4 operator + (const Matrix4& a, const Matrix4& b);
798 inline Matrix4 operator - (const Matrix4& a, const Matrix4& b);
799 inline Matrix4 operator * (const Matrix4& a, const Matrix4& b);
800 inline Vector4 operator * (const Matrix4& a, const Vector4& b);
801 inline Vector4 operator * (const Vector4& a, const Matrix4& b);
802 inline Vector3 operator * (const Matrix4& a, const Vector3& b);
803 inline Vector3 operator * (const Vector3& a, const Matrix4& b);
804 
805 
821 {
822  public:
823  RigidTransform();
825  RigidTransform(const Matrix3&, const Vector3&);
826  RigidTransform(const Vector3&, const Vector3&, const Vector3&, const Vector3&);
827  RigidTransform(const Matrix4&);
828 
829  inline bool operator == (const RigidTransform&) const;
830  inline bool operator != (const RigidTransform&) const;
831  inline const RigidTransform& operator = (const RigidTransform&);
832  inline void operator *= (const RigidTransform&); //this(v) = this(a(v))
833  inline void operator *= (const Matrix3&);
834  inline void operator += (const Vector3&);
835  inline void operator -= (const Vector3&);
836  inline operator Matrix4 () const;
837 
838  inline void compose(const RigidTransform& a, const RigidTransform& b);
839  inline void composeInverseA(const RigidTransform& a, const RigidTransform& b);
840  inline void composeInverseB(const RigidTransform& a, const RigidTransform& b);
841  inline void mul(const RigidTransform& a, const RigidTransform& b);
843  inline void mulInverseA(const RigidTransform& a, const RigidTransform& b);
844  inline void mulInverseB(const RigidTransform& a, const RigidTransform& b);
845 
848  inline void mul(const Vector3& a, Vector3& out) const;
849  inline void mul(const Vector4& a, Vector3& out) const;
850  inline void mulPoint(const Vector3& a, Vector3& out) const;
851  inline void mulVector(const Vector3& a, Vector3& out) const;
852  inline void mulInverse(const Vector3& a, Vector3& out) const;
853  inline void mulInverse(const Vector4& a, Vector3& out) const;
854  inline void mulPointInverse(const Vector3& a, Vector3& out) const;
855  inline void mulVectorInverse(const Vector3& a, Vector3& out) const;
857 
858  inline void setIdentity();
859  inline void set(const RigidTransform&);
860  inline void set(const Matrix3&, const Vector3&);
861  inline void set(const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& trans);
862  inline void set(const Matrix4&);
863  inline void setRotate(const Matrix3&);
864  inline void setTranslate(const Vector3&);
865  inline void setRotation(const Matrix3&);
866  inline void setTranslation(const Vector3&);
867  inline void setInverse(const RigidTransform&);
868  inline void setRotated(const RigidTransform& a, const Matrix3& r);
869  inline void setShifted(const RigidTransform& a, const Vector3& v);
870 
871  inline void get(RigidTransform&) const;
872  inline void get(Matrix3&, Vector3&) const;
873  inline void get(Vector3& x, Vector3& y, Vector3& z, Vector3& trans) const;
874  inline void get(Matrix4&) const;
875  inline void getRotation(Matrix3&) const;
876  inline void getTranslation(Vector3&) const;
877  inline void getInverse(RigidTransform&);
878 
879  inline void inplaceInverse();
880  inline void inplaceRotate(const Matrix3&);
881  inline void inplaceShift(const Vector3&);
882 
883  inline bool isIdentity(Real eps=Zero) const;
884  bool isValid(Real eps=Epsilon) const;
885 
886  bool Read(File&);
887  bool Write(File&) const;
888 
889  Matrix3 R;
890  Vector3 t;
891 };
892 
893 inline RigidTransform operator * (const RigidTransform&, const RigidTransform&);
894 inline RigidTransform operator * (const RigidTransform&, const Matrix3&);
895 inline RigidTransform operator * (const Matrix3& a, const RigidTransform& b);
896 inline Vector3 operator * (const RigidTransform&, const Vector3&);
897 inline RigidTransform operator + (const RigidTransform&, const Vector3&);
898 inline RigidTransform operator - (const RigidTransform&, const Vector3&);
899 
903 {
904 public:
907  RigidTransform2D(const Matrix3& m);
908  RigidTransform2D(const Matrix2& R,const Vector2& t);
909  RigidTransform2D(Real theta,const Vector2& t);
910 
911  inline const RigidTransform2D& operator = (const RigidTransform2D&);
912  inline void operator *= (const RigidTransform2D&); //this(v) = this(a(v))
913 
914  inline void compose(const RigidTransform2D& a, const RigidTransform2D& b);
915  inline void composeInverseA(const RigidTransform2D& a, const RigidTransform2D& b);
916  inline void composeInverseB(const RigidTransform2D& a, const RigidTransform2D& b);
917  inline void mul(const RigidTransform2D& a, const RigidTransform2D& b);
918  inline void mulInverseA(const RigidTransform2D& a, const RigidTransform2D& b);
919  inline void mulInverseB(const RigidTransform2D& a, const RigidTransform2D& b);
920 
921  inline void mul(const Vector3& a, Vector2& out) const;
922  inline void mul(const Vector2& a, Vector2& out) const;
923  inline void mulPoint(const Vector2& a, Vector2& out) const;
924  inline void mulVector(const Vector2& a, Vector2& out) const;
925  inline void mulInverse(const Vector2& a, Vector2& out) const;
926  inline void mulInverse(const Vector3& a, Vector2& out) const;
927  inline void mulPointInverse(const Vector2& a, Vector2& out) const;
928  inline void mulVectorInverse(const Vector2& a, Vector2& out) const;
929 
930  inline void setIdentity();
931  inline void set(const RigidTransform2D& rhs);
932  inline void set(const Matrix3& mat);
933  inline void set(Real theta,const Vector2& t);
934  inline void setInverse(const RigidTransform2D&);
935  inline void get(RigidTransform2D& rhs) const;
936  inline void get(Matrix3& mat) const;
937  inline void get(Real& theta,Vector2& t) const;
938 
939  inline bool isIdentity(Real eps=Zero) const;
940  bool isValid(Real eps=Epsilon) const;
941 
942  bool Read(File&);
943  bool Write(File&) const;
944 
945  Matrix2 R;
946  Vector2 t;
947 };
948 
949 inline RigidTransform2D operator * (const RigidTransform2D&, const RigidTransform2D&);
950 inline Vector2 operator * (const RigidTransform2D&, const Vector2&);
951 
952 
953 
954 //inlined member functions
955 inline bool Vector2::operator == (const Vector2& a) const { return a.x == x && a.y == y; }
956 inline bool Vector2::operator != (const Vector2& a) const { return a.x != x || a.y != y; }
957 inline const Vector2& Vector2::operator = (const Vector2& v) { set(v); return *this; }
958 inline void Vector2::operator += (const Vector2& v) { x += v.x; y += v.y; }
959 inline void Vector2::operator -= (const Vector2& v) { x -= v.x; y -= v.y; }
960 inline void Vector2::operator *= (Real c) { inplaceMul(c); }
961 inline void Vector2::operator /= (Real c) { inplaceDiv(c); }
962 inline Real& Vector2::operator [] (int i) { return data[i]; }
963 inline const Real& Vector2::operator [] (int i) const { return data[i]; }
964 inline Vector2::operator Real* () { return data; }
965 inline Vector2::operator const Real* () const { return data; }
966 inline void Vector2::add(const Vector2& a, const Vector2& b) { x=a.x+b.x; y=a.y+b.y; }
967 inline void Vector2::sub(const Vector2& a, const Vector2& b) { x=a.x-b.x; y=a.y-b.y; }
968 inline void Vector2::mul(const Vector2& a, Real b) { x=a.x*b; y=a.y*b; }
969 inline void Vector2::div(const Vector2& a, Real b) { x=a.x/b; y=a.y/b; }
970 inline void Vector2::madd(const Vector2& a, Real b) { x+=a.x*b; y+=a.y*b; }
971 inline Real Vector2::dot(const Vector2& a) const { return x*a.x + y*a.y; }
972 inline Real Vector2::cross(const Vector2& a) const { return x*a.y - y*a.x; }
973 inline Real Vector2::distance(const Vector2& a) const { return Sqrt(distanceSquared(a)); }
974 inline Real Vector2::distanceSquared(const Vector2& a) const { return Sqr(x-a.x)+Sqr(y-a.y); }
975 inline Real Vector2::minElement(int* index) const {
976  if(x <= y) { if(index) *index=0; return x; }
977  else { if(index) *index=1; return y; }
978 }
979 inline Real Vector2::maxElement(int* index) const {
980  if(x >= y) { if(index) *index=0; return x; }
981  else { if(index) *index=1; return y; }
982 }
983 inline Real Vector2::minAbsElement(int* index) const {
984  if(Abs(x) <= Abs(y)) { if(index) *index=0; return x; }
985  else { if(index) *index=1; return y; }
986 }
987 inline Real Vector2::maxAbsElement(int* index) const {
988  if(Abs(x) >= Abs(y)) { if(index) *index=0; return x; }
989  else { if(index) *index=1; return y; }
990 }
991 inline Real Vector2::norm() const { return Sqrt(normSquared()); }
992 inline Real Vector2::normSquared() const { return Sqr(x)+Sqr(y); }
993 inline Real Vector2::length() const { return norm(); }
994 inline void Vector2::set(const Vector2& a) { set(a.x,a.y); }
995 inline void Vector2::set(Real _x) { x = y = _x; }
996 inline void Vector2::set(Real _x, Real _y) { x=_x; y=_y; }
997 inline void Vector2::set(const Real* _data) { if(_data) set(_data[0],_data[1]); else setZero(); }
998 inline void Vector2::setZero() { x = y = Zero; }
999 inline void Vector2::setRotation(Real rads) { set(Cos(rads), Sin(rads)); }
1000 inline void Vector2::setPerpendicular(const Vector2& v) { set(-v.y, v.x); }
1001 inline void Vector2::setNegative(const Vector2& a) { x=-a.x; y=-a.y; }
1002 inline void Vector2::setNormalized(const Vector2& a) { mul(a,PseudoInv(a.norm())); }
1003 inline void Vector2::setProjection(const Vector2& a, const Vector2& b) { mul(b, a.dot(b)/b.dot(b)); }
1004 inline void Vector2::setMinimum(const Vector2& v) { if(v.x<x) x=v.x; if(v.y<y) y=v.y; }
1005 inline void Vector2::setMinimum(const Vector2& a,const Vector2& b) { set(Min(a.x,b.x),Min(a.y,b.y)); }
1006 inline void Vector2::setMaximum(const Vector2& v) { if(v.x>x) x=v.x; if(v.y>y) y=v.y; }
1007 inline void Vector2::setMaximum(const Vector2& a,const Vector2& b) { set(Max(a.x,b.x),Max(a.y,b.y)); }
1008 inline void Vector2::get(Vector2& v) const { get(v.x,v.y); }
1009 inline void Vector2::get(Real& _x, Real& _y) const { _x=x; _y=y; }
1010 inline void Vector2::get(Real _data[2]) const { get(_data[0],_data[1]); }
1011 inline void Vector2::getNegative(Vector2& v) const { v.setNegative(*this); }
1012 inline void Vector2::getNormalized(Vector2& v) const { v.setNormalized(*this); }
1013 inline void Vector2::getOrthogonal(Vector2& v) const { v.setOrthogonal(*this); }
1014 inline void Vector2::inplaceNegative() { x=-x; y=-y; }
1015 inline void Vector2::inplaceMul(Real c) { x*=c; y*=c; }
1016 inline void Vector2::inplaceDiv(Real c) { x/=c; y/=c; }
1017 inline void Vector2::inplaceNormalize() { inplaceMul(PseudoInv(norm())); }
1018 inline bool Vector2::isZero(Real eps) const { return FuzzyZero(x,eps)&&FuzzyZero(y,eps); }
1019 inline bool Vector2::isEqual(const Vector2&a,Real eps) const { return FuzzyEquals(x,a.x,eps) && FuzzyEquals(y,a.y,eps); }
1020 
1021 inline bool Vector3::operator == (const Vector3& a) const { return a.x == x && a.y == y && a.z == z; }
1022 inline bool Vector3::operator != (const Vector3& a) const { return a.x != x || a.y != y || a.z != z; }
1023 inline const Vector3& Vector3::operator = (const Vector3& v) { set(v); return *this; }
1024 inline void Vector3::operator += (const Vector3& v) { x += v.x; y += v.y; z += v.z; }
1025 inline void Vector3::operator -= (const Vector3& v) { x -= v.x; y -= v.y; z -= v.z; }
1026 inline void Vector3::operator *= (Real c) { inplaceMul(c); }
1027 inline void Vector3::operator /= (Real c) { inplaceDiv(c); }
1028 inline Real& Vector3::operator [] (int i) { return data[i]; }
1029 inline const Real& Vector3::operator [] (int i) const { return data[i]; }
1030 inline Vector3::operator Real* () { return data; }
1031 inline Vector3::operator const Real* () const { return data; }
1032 inline void Vector3::add(const Vector3& a, const Vector3& b) { x=a.x+b.x; y=a.y+b.y; z=a.z+b.z; }
1033 inline void Vector3::sub(const Vector3& a, const Vector3& b) { x=a.x-b.x; y=a.y-b.y; z=a.z-b.z; }
1034 inline void Vector3::mul(const Vector3& a, Real b) { x=a.x*b; y=a.y*b; z=a.z*b; }
1035 inline void Vector3::div(const Vector3& a, Real b) { x=a.x/b; y=a.y/b; z=a.z/b; }
1036 inline void Vector3::madd(const Vector3& a, Real b) { x+=a.x*b; y+=a.y*b; z+=a.z*b; }
1037 inline Real Vector3::dot(const Vector3& a) const { return x*a.x + y*a.y + z*a.z; }
1038 inline Real Vector3::distance(const Vector3& a) const { return Sqrt(distanceSquared(a)); }
1039 inline Real Vector3::distanceSquared(const Vector3& a) const { return Sqr(x-a.x)+Sqr(y-a.y)+Sqr(z-a.z); }
1040 inline Real Vector3::norm() const { return Sqrt(normSquared()); }
1041 inline Real Vector3::normSquared() const { return Sqr(x)+Sqr(y)+Sqr(z); }
1042 inline Real Vector3::length() const { return norm(); }
1043 inline Real Vector3::minElement(int* index) const
1044 {
1045  Real vmin=x;
1046  int imin=0;
1047  if(y < vmin) { vmin=y; imin=1; }
1048  if(z < vmin) { vmin=z; imin=2; }
1049  if(index) *index=imin;
1050  return vmin;
1051 }
1052 inline Real Vector3::maxElement(int* index) const
1053 {
1054  Real vmax=x;
1055  int imin=0;
1056  if(y > vmax) { vmax=y; imin=1; }
1057  if(z > vmax) { vmax=z; imin=2; }
1058  if(index) *index=imin;
1059  return vmax;
1060 }
1061 inline Real Vector3::minAbsElement(int* index) const
1062 {
1063  Real vmin=Abs(x);
1064  int imin=0;
1065  if(Abs(y) < vmin) { vmin=Abs(y); imin=1; }
1066  if(Abs(z) < vmin) { vmin=Abs(z); imin=2; }
1067  if(index) *index=imin;
1068  return vmin;
1069 }
1070 inline Real Vector3::maxAbsElement(int* index) const
1071 {
1072  Real vmax=Abs(x);
1073  int imin=0;
1074  if(Abs(y) > vmax) { vmax=Abs(y); imin=1; }
1075  if(Abs(z) > vmax) { vmax=Abs(z); imin=2; }
1076  if(index) *index=imin;
1077  return vmax;
1078 }
1079 inline void Vector3::set(const Vector3& a) { set(a.x,a.y,a.z); }
1080 inline void Vector3::set(Real _x) { x = y = z = _x; }
1081 inline void Vector3::set(Real _x, Real _y, Real _z) { x=_x; y=_y; z=_z; }
1082 inline void Vector3::set(const Real *_data) { if(_data) set(_data[0],_data[1],_data[2]); else setZero(); }
1083 inline void Vector3::setZero() { x = y = z = Zero; }
1084 inline void Vector3::setNegative(const Vector3& a) { x=-a.x; y=-a.y; z=-a.z; }
1085 inline void Vector3::setCross(const Vector3& a, const Vector3& b) { x=a.y*b.z-a.z*b.y; y=a.z*b.x-a.x*b.z; z=a.x*b.y-a.y*b.x; }
1086 inline void Vector3::setNormalized(const Vector3& a) { mul(a,PseudoInv(a.norm())); }
1087 inline void Vector3::setProjection(const Vector3& a, const Vector3& b) { mul(b, a.dot(b)/b.dot(b)); }
1088 inline void Vector3::setMinimum(const Vector3& v) { if(v.x<x) x=v.x; if(v.y<y) y=v.y; if(v.z<z) z=v.z; }
1089 inline void Vector3::setMinimum(const Vector3& a,const Vector3& b) { set(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z)); }
1090 inline void Vector3::setMaximum(const Vector3& v) { if(v.x>x) x=v.x; if(v.y>y) y=v.y; if(v.z>z) z=v.z; }
1091 inline void Vector3::setMaximum(const Vector3& a,const Vector3& b) { set(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z)); }
1092 inline void Vector3::get(Vector3& v) const { get(v.x,v.y,v.z); }
1093 inline void Vector3::get(Real& _x, Real& _y, Real& _z) const { _x=x; _y=y; _z=z; }
1094 inline void Vector3::get(Real _data[3]) const { get(_data[0],_data[1],_data[2]); }
1095 inline void Vector3::getNegative(Vector3& v) const { v.setNegative(*this); }
1096 inline void Vector3::getNormalized(Vector3& v) const { v.setNormalized(*this); }
1097 inline void Vector3::getOrthogonalBasis(Vector3& yb,Vector3& zb) const
1098 {
1099  Real scale;
1100  Real n = normSquared(),invn = 1.0;
1101  if(FuzzyZero(n)) {
1102  yb.set(0.0,1.0,0.0);
1103  zb.set(0.0,0.0,1.0);
1104  return;
1105  }
1106  if(!FuzzyEquals(n,1.0)) {
1107  n = Sqrt(n);
1108  invn = 1.0/n;
1109  }
1110  if(FuzzyEquals(x,n)) scale = 0;
1111  else if(FuzzyEquals(x,-n)) { //A complete flip of the basis
1112  yb.set(0.0,-1.0,0.0);
1113  zb.set(0.0,0.0,1.0);
1114  return;
1115  }
1116  else scale = n*(n-x)/(Sqr(n)-Sqr(x));
1117  yb.x = -y;
1118  yb.y = x + scale*Sqr(z);
1119  yb.z = -scale*y*z;
1120  zb.x = -z;
1121  zb.y = -scale*y*z;
1122  zb.z = x + scale*Sqr(y);
1123  if(invn != 1.0) {
1124  yb *= invn;
1125  zb *= invn;
1126  }
1127 }
1128 inline void Vector3::inplaceNegative() { x=-x; y=-y; z=-z; }
1129 inline void Vector3::inplaceMul(Real c) { x*=c; y*=c; z*=c; }
1130 inline void Vector3::inplaceDiv(Real c) { x/=c; y/=c; z/=c; }
1131 inline void Vector3::inplaceNormalize() { inplaceMul(PseudoInv(norm())); }
1132 inline bool Vector3::isZero(Real eps) const { return FuzzyZero(x,eps)&&FuzzyZero(y,eps)&&FuzzyZero(z,eps); }
1133 inline bool Vector3::isEqual(const Vector3&a,Real eps) const { return FuzzyEquals(x,a.x,eps) && FuzzyEquals(y,a.y,eps) && FuzzyEquals(z,a.z,eps); }
1134 
1135 inline bool Vector4::operator == (const Vector4& a) const { return a.x == x && a.y == y && a.z == z && a.w == w; }
1136 inline bool Vector4::operator != (const Vector4& a) const { return a.x != x || a.y != y || a.z != z || a.w != w; }
1137 inline const Vector4& Vector4::operator = (const Vector4& v) { set(v); return *this; }
1138 inline void Vector4::operator += (const Vector4& v) { x += v.x; y += v.y; z += v.z; w += v.w; }
1139 inline void Vector4::operator -= (const Vector4& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; }
1140 inline void Vector4::operator *= (Real c) { inplaceMul(c); }
1141 inline void Vector4::operator /= (Real c) { inplaceDiv(c); }
1142 inline void Vector4::operator += (const Vector3& v) { x += v.x; y += v.y; z += v.z; }
1143 inline void Vector4::operator -= (const Vector3& v) { x -= v.x; y -= v.y; z -= v.z; }
1144 inline Real& Vector4::operator [] (int i) { return data[i]; }
1145 inline const Real& Vector4::operator [] (int i) const { return data[i]; }
1146 inline Vector4::operator Vector3() const { return Vector3(x,y,z); }
1147 inline Vector4::operator Real* () { return data; }
1148 inline Vector4::operator const Real* () const { return data; }
1149 inline void Vector4::add(const Vector4& a, const Vector4& b) { x=a.x+b.x; y=a.y+b.y; z=a.z+b.z; w=a.w+b.w; }
1150 inline void Vector4::sub(const Vector4& a, const Vector4& b) { x=a.x-b.x; y=a.y-b.y; z=a.z-b.z; w=a.w-b.w; }
1151 inline void Vector4::mul(const Vector4& a, Real b) { x=a.x*b; y=a.y*b; z=a.z*b; w=a.w*b; }
1152 inline void Vector4::div(const Vector4& a, Real b) { x=a.x/b; y=a.y/b; z=a.z/b; w=a.w/b; }
1153 inline void Vector4::madd(const Vector4& a, Real b) { x+=a.x*b; y+=a.y*b; z+=a.z*b; w+=a.w*b; }
1154 inline Real Vector4::dot(const Vector4& a) const { return x*a.x + y*a.y + z*a.z + w*a.w; }
1155 inline Real Vector4::dot3(const Vector4& a) const { return x*a.x + y*a.y + z*a.z; }
1156 inline Real Vector4::dot3(const Vector3& a) const { return x*a.x + y*a.y + z*a.z; }
1157 inline Real Vector4::distance(const Vector4& a) const { return Sqrt(distanceSquared(a)); }
1158 inline Real Vector4::distanceSquared(const Vector4& a) const { return Sqr(x-a.x)+Sqr(y-a.y)+Sqr(z-a.z)+Sqr(w-a.w); }
1159 inline Real Vector4::norm() const { return Sqrt(normSquared()); }
1160 inline Real Vector4::normSquared() const { return Sqr(x)+Sqr(y)+Sqr(z)+Sqr(w); }
1161 inline Real Vector4::length() const { return norm(); }
1162 inline Real Vector4::minElement(int* index) const
1163 {
1164  Real vmin=x;
1165  int imin=0;
1166  if(y < vmin) { vmin=y; imin=1; }
1167  if(z < vmin) { vmin=z; imin=2; }
1168  if(w < vmin) { vmin=w; imin=3; }
1169  if(index) *index=imin;
1170  return vmin;
1171 }
1172 inline Real Vector4::maxElement(int* index) const
1173 {
1174  Real vmax=x;
1175  int imin=0;
1176  if(y > vmax) { vmax=y; imin=1; }
1177  if(z > vmax) { vmax=z; imin=2; }
1178  if(w > vmax) { vmax=w; imin=3; }
1179  if(index) *index=imin;
1180  return vmax;
1181 }
1182 inline Real Vector4::minAbsElement(int* index) const
1183 {
1184  Real vmin=Abs(x);
1185  int imin=0;
1186  if(Abs(y) < vmin) { vmin=Abs(y); imin=1; }
1187  if(Abs(z) < vmin) { vmin=Abs(z); imin=2; }
1188  if(Abs(w) < vmin) { vmin=Abs(w); imin=3; }
1189  if(index) *index=imin;
1190  return vmin;
1191 }
1192 inline Real Vector4::maxAbsElement(int* index) const
1193 {
1194  Real vmax=Abs(x);
1195  int imin=0;
1196  if(Abs(y) > vmax) { vmax=Abs(y); imin=1; }
1197  if(Abs(z) > vmax) { vmax=Abs(z); imin=2; }
1198  if(Abs(w) > vmax) { vmax=Abs(w); imin=3; }
1199  if(index) *index=imin;
1200  return vmax;
1201 }
1202 inline void Vector4::set(const Vector4& a) { x = a.x; y = a.y; z = a.z; w = a.w; }
1203 inline void Vector4::set(Real _x) { x = y = z = w = _x; }
1204 inline void Vector4::set(Real _x, Real _y, Real _z, Real _w) { x=_x; y=_y; z=_z; w=_w; }
1205 inline void Vector4::set(const Real *_data) { if(_data) set(_data[0],_data[1],_data[2],_data[3]); else setZero(); }
1206 inline void Vector4::setZero() { x = y = z = w = Zero; }
1207 inline void Vector4::setVector(const Vector3& v) { set(v.x,v.y,v.z,Zero); }
1208 inline void Vector4::setHomogeneous(const Vector3& v) { set(v.x,v.y,v.z,One); }
1209 inline void Vector4::setNegative(const Vector4& v) { set(-v.x, -v.y, -v.z, -v.w); }
1210 inline void Vector4::setNormalized(const Vector4& v) { mul(v, PseudoInv(v.norm())); }
1211 inline void Vector4::setProjection(const Vector4& a, const Vector4& b) { mul(b, a.dot(b)/b.dot(b)); }
1212 inline void Vector4::setMinimum(const Vector4& v) { if(v.x<x) x=v.x; if(v.y<y) y=v.y; if(v.z<z) z=v.z; if(v.w<w) w=v.w; }
1213 inline void Vector4::setMinimum(const Vector4& a,const Vector4& b) { set(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z),Min(a.w,b.w)); }
1214 inline void Vector4::setMaximum(const Vector4& v) { if(v.x>x) x=v.x; if(v.y>y) y=v.y; if(v.z>z) z=v.z; if(v.w>w) w=v.w; }
1215 inline void Vector4::setMaximum(const Vector4& a,const Vector4& b) { set(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z),Max(a.w,b.w)); }
1216 inline void Vector4::get(Vector4& v) const { get(v.x,v.y,v.z,v.w); }
1217 inline void Vector4::get(Real& _x, Real& _y, Real& _z, Real& _w) const { _x=x; _y=y; _z=z; _w=w; }
1218 inline void Vector4::get(Real _data[4]) const { get(_data[0],_data[1],_data[2],_data[3]); }
1219 inline void Vector4::get(Vector3& v) const { v.x=x; v.y=y; v.z=z; }
1220 inline void Vector4::getNegative(Vector4& v) const { v.setNegative(*this); }
1221 inline void Vector4::getNormalized(Vector4& v) const { v.setNormalized(*this); }
1222 inline void Vector4::inplaceNegative() { x=-x; y=-y; z=-z; w=-w; }
1223 inline void Vector4::inplaceMul(Real c) { x*=c; y*=c; z*=c; w*=c; }
1224 inline void Vector4::inplaceDiv(Real c) { x/=c; y/=c; z/=c; w/=c; }
1225 inline void Vector4::inplaceNormalize() { inplaceMul(PseudoInv(norm())); }
1226 inline bool Vector4::isZero(Real eps) const { return FuzzyZero(x,eps)&&FuzzyZero(y,eps)&&FuzzyZero(z,eps)&&FuzzyZero(w,eps); }
1227 inline bool Vector4::isEqual(const Vector4&a,Real eps) const { return FuzzyEquals(x,a.x,eps) && FuzzyEquals(y,a.y,eps) && FuzzyEquals(z,a.z,eps) && FuzzyEquals(w,a.w,eps); }
1228 
1229 
1230 
1231 inline const Matrix2& Matrix2::operator = (const Matrix2& m)
1232 {
1233  set(m);
1234  return *this;
1235 }
1236 
1237 inline void Matrix2::operator += (const Matrix2& m)
1238 {
1239  int i,j;
1240  for(i=0; i<2; i++)
1241  {
1242  for(j=0; j<2; j++)
1243  data[i][j] += m.data[i][j];
1244  }
1245 }
1246 
1247 inline void Matrix2::operator -= (const Matrix2& m)
1248 {
1249  int i,j;
1250  for(i=0; i<2; i++)
1251  {
1252  for(j=0; j<2; j++)
1253  data[i][j] -= m.data[i][j];
1254  }
1255 }
1256 
1257 inline void Matrix2::operator *= (const Matrix2& m)
1258 {
1259  mul(*this, m);
1260 }
1261 
1262 inline void Matrix2::operator *= (Real s)
1263 {
1264  inplaceMul(s);
1265 }
1266 
1267 inline void Matrix2::operator /= (Real s)
1268 {
1269  inplaceDiv(s);
1270 }
1271 
1272 inline void Matrix2::add(const Matrix2& a, const Matrix2& b)
1273 {
1274  int i,j;
1275  for(i=0; i<2; i++)
1276  for(j=0; j<2; j++)
1277  data[i][j] = a.data[i][j] + b.data[i][j];
1278 }
1279 
1280 inline void Matrix2::sub(const Matrix2& a, const Matrix2& b)
1281 {
1282  int i,j;
1283  for(i=0; i<2; i++)
1284  for(j=0; j<2; j++)
1285  data[i][j] = a.data[i][j] - b.data[i][j];
1286 }
1287 
1288 inline void Matrix2::mul(const Matrix2& a, const Matrix2& b)
1289 {
1290  int i,j;
1291  Real dat [2][2];
1292  //NOTE: remember column major
1293  for(i=0; i<2; i++)
1294  for(j=0; j<2; j++)
1295  dat[i][j] = b.data[i][0]*a.data[0][j] + b.data[i][1]*a.data[1][j];
1296  set(dat);
1297 }
1298 
1299 inline void Matrix2::mulTransposeA(const Matrix2& a, const Matrix2& b)
1300 {
1301  int i,j;
1302  Real dat [2][2];
1303  //NOTE: remember column major
1304  for(i=0; i<2; i++)
1305  for(j=0; j<2; j++)
1306  dat[i][j] = b.data[i][0]*a.data[j][0] + b.data[i][1]*a.data[j][1];
1307  set(dat);
1308 }
1309 
1310 inline void Matrix2::mulTransposeB(const Matrix2& a, const Matrix2& b)
1311 {
1312  int i,j;
1313  Real dat [2][2];
1314  //NOTE: remember column major
1315  for(i=0; i<2; i++)
1316  for(j=0; j<2; j++)
1317  dat[i][j] = b.data[0][i]*a.data[0][j] + b.data[1][i]*a.data[1][j];
1318  set(dat);
1319 }
1320 
1321 inline void Matrix2::mul(const Matrix2& a, Real b)
1322 {
1323  int i,j;
1324  for(i=0; i<2; i++)
1325  for(j=0; j<2; j++)
1326  data[i][j] = a.data[i][j]*b;
1327 }
1328 
1329 inline void Matrix2::div(const Matrix2& a, Real b)
1330 {
1331  int i,j;
1332  for(i=0; i<2; i++)
1333  for(j=0; j<2; j++)
1334  data[i][j] = a.data[i][j]/b;
1335 }
1336 
1337 inline void Matrix2::mul(const Vector2& a, Vector2& out) const
1338 {
1339  out.x = data[0][0]*a.x + data[1][0]*a.y;
1340  out.y = data[0][1]*a.x + data[1][1]*a.y;
1341 }
1342 
1343 inline void Matrix2::mulTranspose(const Vector2& a, Vector2& out) const
1344 {
1345  out.x = data[0][0]*a.x + data[0][1]*a.y;
1346  out.y = data[1][0]*a.x + data[1][1]*a.y;
1347 }
1348 
1349 inline void Matrix2::set(const Matrix2& m)
1350 {
1351  int i,j;
1352  for(i=0; i<2; i++)
1353  for(j=0; j<2; j++)
1354  data[i][j] = m.data[i][j];
1355 }
1356 
1357 inline void Matrix2::set(Real x)
1358 {
1359  int i,j;
1360  for(i=0; i<2; i++)
1361  for(j=0; j<2; j++)
1362  data[i][j] = x;
1363 }
1364 
1365 inline void Matrix2::set(const Real m[2][2])
1366 {
1367  int i,j;
1368  for(i=0; i<2; i++)
1369  for(j=0; j<2; j++)
1370  data[i][j] = m[i][j];
1371 }
1372 
1373 inline void Matrix2::set(const Real* m)
1374 {
1375  if(!m) {
1376  setZero();
1377  return;
1378  }
1379  int i,j,k=0;
1380  for(i=0; i<2; i++)
1381  for(j=0; j<2; j++, k++)
1382  data[i][j] = m[k];
1383 }
1384 
1385 inline void Matrix2::set(const Vector2& xb, const Vector2& yb)
1386 {
1387  setCol1(xb);
1388  setCol2(yb);
1389 }
1390 
1391 inline void Matrix2::setZero()
1392 {
1393  set(Zero);
1394 }
1395 
1396 inline void Matrix2::setIdentity()
1397 {
1398  int i,j;
1399  for(i=0; i<2; i++)
1400  for(j=0; j<2; j++)
1401  data[i][j] = Delta(i,j);
1402 }
1403 
1404 inline void Matrix2::setDiagonal(const Vector2& d)
1405 {
1406  setZero();
1407  d.get(data[0][0],data[1][1]);
1408 }
1409 
1410 inline void Matrix2::setTranspose(const Matrix2& m)
1411 {
1412  int i,j;
1413  for(i=0; i<2; i++)
1414  for(j=0; j<2; j++)
1415  data[i][j] = m.data[j][i];
1416 }
1417 
1418 inline void Matrix2::setNegative(const Matrix2& m)
1419 {
1420  int i,j;
1421  for(i=0; i<2; i++)
1422  for(j=0; j<2; j++)
1423  data[i][j] = -m.data[i][j];
1424 }
1425 
1426 inline bool Matrix2::setInverse(const Matrix2& m)
1427 {
1428  Real det = m.determinant();
1429  if(det == Zero) return false;
1430  Real detinv = Inv(det);
1431  data[0][0] = m.data[1][1];
1432  data[1][1] = m.data[0][0];
1433  data[0][1] = -m.data[0][1];
1434  data[1][0] = -m.data[1][0];
1435  inplaceMul(detinv);
1436  return true;
1437 }
1438 
1439 inline void Matrix2::setScale(Real s)
1440 {
1441  setZero();
1442  data[0][0] = data[1][1] = s;
1443 }
1444 
1445 inline void Matrix2::setScale(Real sx, Real sy)
1446 {
1447  setZero();
1448  data[0][0] = sx;
1449  data[1][1] = sy;
1450 }
1451 
1452 inline void Matrix2::setRotate(Real rads)
1453 {
1454  Real cr = Cos(rads);
1455  Real sr = Sin(rads);
1456 
1457  data[0][0] = cr; data[1][0] = -sr;
1458  data[0][1] = sr; data[1][1] = cr;
1459 }
1460 
1461 inline void Matrix2::setOuterProduct(const Vector2& a,const Vector2& b)
1462 {
1463  data[0][0] = a.x*b.x; data[1][0] = a.x*b.y;
1464  data[0][1] = a.y*b.x; data[1][1] = a.y*b.y;
1465 }
1466 
1467 
1468 inline void Matrix2::get(Matrix2& m) const
1469 {
1470  m.set(*this);
1471 }
1472 
1473 inline void Matrix2::get(Real m [2][2]) const
1474 {
1475  int i,j;
1476  for(i=0; i<2; i++)
1477  for(j=0; j<2; j++)
1478  m[i][j] = data[i][j];
1479 }
1480 
1481 inline void Matrix2::get(Real m [4]) const
1482 {
1483  int i,j,k=0;
1484  for(i=0; i<2; i++)
1485  for(j=0; j<2; j++, k++)
1486  m[k] = data[i][j];
1487 }
1488 
1489 inline void Matrix2::get(Vector2& xb, Vector2& yb) const
1490 {
1491  getCol1(xb);
1492  getCol2(yb);
1493 }
1494 
1495 inline void Matrix2::getTranspose(Matrix2& m) const
1496 {
1497  m.setTranspose(*this);
1498 }
1499 
1500 inline void Matrix2::getNegative(Matrix2& m) const
1501 {
1502  m.setNegative(*this);
1503 }
1504 
1505 inline bool Matrix2::getInverse(Matrix2& m) const
1506 {
1507  return m.setInverse(*this);
1508 }
1509 
1510 inline void Matrix2::inplaceTranspose()
1511 {
1512  Real temp;
1513  int i,j;
1514  for(i=0; i<2; i++) {
1515  for(j=0; j<i; j++) {
1516  temp = data[i][j];
1517  data[i][j] = data[j][i];
1518  data[j][i] = temp;
1519  }
1520  }
1521 }
1522 
1523 inline void Matrix2::inplaceNegative()
1524 {
1525  int i,j;
1526  for(i=0; i<2; i++)
1527  for(j=0; j<2; j++)
1528  data[i][j] = -data[i][j];
1529 }
1530 
1531 inline void Matrix2::inplaceMul(Real s)
1532 {
1533  int i,j;
1534  for(i=0; i<2; i++)
1535  for(j=0; j<2; j++)
1536  data[i][j] *= s;
1537 }
1538 
1539 inline void Matrix2::inplaceDiv(Real s)
1540 {
1541  int i,j;
1542  for(i=0; i<2; i++)
1543  for(j=0; j<2; j++)
1544  data[i][j] /= s;
1545 }
1546 
1547 inline void Matrix2::inplaceRowScale(Real sx, Real sy)
1548 {
1549  int j;
1550  for(j=0; j<2; j++) {
1551  data[0][j] *= sx;
1552  data[1][j] *= sy;
1553  }
1554 }
1555 
1556 inline void Matrix2::inplaceColScale(Real sx, Real sy)
1557 {
1558  int j;
1559  for(j=0; j<2; j++) {
1560  data[j][0] *= sx;
1561  data[j][1] *= sy;
1562  }
1563 }
1564 
1565 inline bool Matrix2::inplaceInverse()
1566 {
1567  Matrix2 tmp = *this;
1568  return setInverse(tmp);
1569 }
1570 
1571 inline bool Matrix2::isZero(Real eps) const
1572 {
1573  return FuzzyZero(data[0][0],eps)
1574  && FuzzyZero(data[0][1],eps)
1575  && FuzzyZero(data[1][0],eps)
1576  && FuzzyZero(data[1][1],eps);
1577 }
1578 
1579 inline bool Matrix2::isEqual(const Matrix2&a,Real eps) const
1580 {
1581  return FuzzyEquals(data[0][0],a.data[0][0],eps)
1582  && FuzzyEquals(data[0][1],a.data[0][1],eps)
1583  && FuzzyEquals(data[1][0],a.data[1][0],eps)
1584  && FuzzyEquals(data[1][1],a.data[1][1],eps);
1585 }
1586 
1587 inline bool Matrix2::isIdentity(Real eps) const
1588 {
1589  return FuzzyEquals(data[0][0],One,eps)
1590  && FuzzyZero(data[0][1],eps)
1591  && FuzzyZero(data[1][0],eps)
1592  && FuzzyEquals(data[1][1],One,eps);
1593 }
1594 
1595 inline bool Matrix2::isInvertible(Real eps) const
1596 {
1597  return !FuzzyZero(determinant(),eps);
1598 }
1599 
1600 inline Real Matrix2::trace() const { return data[0][0] + data[1][1]; }
1601 
1602 inline Real Matrix2::determinant() const
1603 {
1604  return data[0][0]*data[1][1]-data[0][1]*data[1][0];
1605 }
1606 
1607 inline Real Matrix2::minElement(int* _i,int* _j) const
1608 {
1609  Real vmin=Inf;
1610  int imin=0,jmin=0;
1611  for(int i=0;i<2;i++)
1612  for(int j=0;j<2;j++)
1613  if(data[i][j] < vmin) { //recall data is stored column-major
1614  vmin=data[i][j];
1615  imin=j;
1616  jmin=i;
1617  }
1618  if(_i) *_i=imin;
1619  if(_j) *_j=jmin;
1620  return vmin;
1621 }
1622 
1623 Real Matrix2::maxElement(int* _i,int* _j) const
1624 {
1625  Real vmax=-Inf;
1626  int imin=0,jmin=0;
1627  for(int i=0;i<2;i++)
1628  for(int j=0;j<2;j++)
1629  if(data[i][j] > vmax) { //recall data is stored column-major
1630  vmax=data[i][j];
1631  imin=j;
1632  jmin=i;
1633  }
1634  if(_i) *_i=imin;
1635  if(_j) *_j=jmin;
1636  return vmax;
1637 }
1638 
1639 Real Matrix2::minAbsElement(int* _i,int* _j) const
1640 {
1641  Real vmin=Inf;
1642  int imin=0,jmin=0;
1643  for(int i=0;i<2;i++)
1644  for(int j=0;j<2;j++)
1645  if(Abs(data[i][j]) < vmin) { //recall data is stored column-major
1646  vmin=Abs(data[i][j]);
1647  imin=j;
1648  jmin=i;
1649  }
1650  if(_i) *_i=imin;
1651  if(_j) *_j=jmin;
1652  return vmin;
1653 }
1654 
1655 Real Matrix2::maxAbsElement(int* _i,int* _j) const
1656 {
1657  Real vmax=0;
1658  int imin=0,jmin=0;
1659  for(int i=0;i<2;i++)
1660  for(int j=0;j<2;j++)
1661  if(Abs(data[i][j]) > vmax) { //recall data is stored column-major
1662  vmax=Abs(data[i][j]);
1663  imin=j;
1664  jmin=i;
1665  }
1666  if(_i) *_i=imin;
1667  if(_j) *_j=jmin;
1668  return vmax;
1669 }
1670 
1671 
1672 
1673 
1674 inline const Matrix3& Matrix3::operator = (const Matrix3& m)
1675 {
1676  set(m);
1677  return *this;
1678 }
1679 
1680 inline void Matrix3::operator += (const Matrix3& m)
1681 {
1682  int i,j;
1683  for(i=0; i<3; i++)
1684  {
1685  for(j=0; j<3; j++)
1686  data[i][j] += m.data[i][j];
1687  }
1688 }
1689 
1690 inline void Matrix3::operator -= (const Matrix3& m)
1691 {
1692  int i,j;
1693  for(i=0; i<3; i++)
1694  {
1695  for(j=0; j<3; j++)
1696  data[i][j] -= m.data[i][j];
1697  }
1698 }
1699 
1700 inline void Matrix3::operator *= (const Matrix3& m)
1701 {
1702  mul(*this, m);
1703 }
1704 
1705 inline void Matrix3::operator *= (Real s)
1706 {
1707  inplaceMul(s);
1708 }
1709 
1710 inline void Matrix3::operator /= (Real s)
1711 {
1712  inplaceDiv(s);
1713 }
1714 
1715 inline void Matrix3::add(const Matrix3& a, const Matrix3& b)
1716 {
1717  int i,j;
1718  for(i=0; i<3; i++)
1719  for(j=0; j<3; j++)
1720  data[i][j] = a.data[i][j] + b.data[i][j];
1721 }
1722 
1723 inline void Matrix3::sub(const Matrix3& a, const Matrix3& b)
1724 {
1725  int i,j;
1726  for(i=0; i<3; i++)
1727  for(j=0; j<3; j++)
1728  data[i][j] = a.data[i][j] - b.data[i][j];
1729 }
1730 
1731 inline void Matrix3::mul(const Matrix3& a, Real b)
1732 {
1733  int i,j;
1734  for(i=0; i<3; i++)
1735  for(j=0; j<3; j++)
1736  data[i][j] = a.data[i][j]*b;
1737 }
1738 
1739 inline void Matrix3::div(const Matrix3& a, Real b)
1740 {
1741  int i,j;
1742  for(i=0; i<3; i++)
1743  for(j=0; j<3; j++)
1744  data[i][j] = a.data[i][j]/b;
1745 }
1746 
1747 inline void Matrix3::mul(const Vector3& a, Vector3& out) const
1748 {
1749  out.x = data[0][0]*a.x + data[1][0]*a.y + data[2][0]*a.z;
1750  out.y = data[0][1]*a.x + data[1][1]*a.y + data[2][1]*a.z;
1751  out.z = data[0][2]*a.x + data[1][2]*a.y + data[2][2]*a.z;
1752 }
1753 
1754 inline void Matrix3::mulTranspose(const Vector3& a, Vector3& out) const
1755 {
1756  out.x = data[0][0]*a.x + data[0][1]*a.y + data[0][2]*a.z;
1757  out.y = data[1][0]*a.x + data[1][1]*a.y + data[1][2]*a.z;
1758  out.z = data[2][0]*a.x + data[2][1]*a.y + data[2][2]*a.z;
1759 }
1760 
1761 inline void Matrix3::mulPoint(const Vector2& a, Vector2& out) const
1762 {
1763  out.x = data[0][0]*a.x + data[1][0]*a.y + data[2][0];
1764  out.y = data[0][1]*a.x + data[1][1]*a.y + data[2][1];
1765 }
1766 
1767 inline void Matrix3::mulVector(const Vector2& a, Vector2& out) const
1768 {
1769  out.x = data[0][0]*a.x + data[1][0]*a.y;
1770  out.y = data[0][1]*a.x + data[1][1]*a.y;
1771 }
1772 
1773 inline void Matrix3::mulVectorTranspose(const Vector2& a, Vector2& out) const
1774 {
1775  out.x = data[0][0]*a.x + data[0][1]*a.y;
1776  out.y = data[1][0]*a.x + data[1][1]*a.y;
1777 }
1778 
1779 inline void Matrix3::set(const Matrix3& m)
1780 {
1781  int i,j;
1782  for(i=0; i<3; i++)
1783  for(j=0; j<3; j++)
1784  data[i][j] = m.data[i][j];
1785 }
1786 
1787 inline void Matrix3::set(Real x)
1788 {
1789  int i,j;
1790  for(i=0; i<3; i++)
1791  for(j=0; j<3; j++)
1792  data[i][j] = x;
1793 }
1794 
1795 inline void Matrix3::set(const Real m[3][3])
1796 {
1797  int i,j;
1798  for(i=0; i<3; i++)
1799  for(j=0; j<3; j++)
1800  data[i][j] = m[i][j];
1801 }
1802 
1803 inline void Matrix3::set(const Real* m)
1804 {
1805  if(!m) {
1806  setZero();
1807  return;
1808  }
1809  int i,j,k=0;
1810  for(i=0; i<3; i++)
1811  for(j=0; j<3; j++, k++)
1812  data[i][j] = m[k];
1813 }
1814 
1815 inline void Matrix3::set(const Vector3& xb, const Vector3& yb, const Vector3& zb)
1816 {
1817  setCol1(xb);
1818  setCol2(yb);
1819  setCol3(zb);
1820 }
1821 
1822 inline void Matrix3::setZero()
1823 {
1824  set(Zero);
1825 }
1826 
1827 inline void Matrix3::setIdentity()
1828 {
1829  int i,j;
1830  for(i=0; i<3; i++)
1831  for(j=0; j<3; j++)
1832  data[i][j] = Delta(i,j);
1833 }
1834 
1835 inline void Matrix3::setDiagonal(const Vector3& d)
1836 {
1837  setZero();
1838  d.get(data[0][0],data[1][1],data[2][2]);
1839 }
1840 
1841 inline void Matrix3::setTranspose(const Matrix3& m)
1842 {
1843  int i,j;
1844  for(i=0; i<3; i++)
1845  for(j=0; j<3; j++)
1846  data[i][j] = m.data[j][i];
1847 }
1848 
1849 inline void Matrix3::setNegative(const Matrix3& m)
1850 {
1851  int i,j;
1852  for(i=0; i<3; i++)
1853  for(j=0; j<3; j++)
1854  data[i][j] = -m.data[i][j];
1855 }
1856 
1857 inline void Matrix3::setScale(Real s)
1858 {
1859  setZero();
1860  data[0][0] = data[1][1] = data[2][2] = s;
1861 }
1862 
1863 inline void Matrix3::setScale(Real sx, Real sy, Real sz)
1864 {
1865  setZero();
1866  data[0][0] = sx;
1867  data[1][1] = sy;
1868  data[2][2] = sz;
1869 }
1870 
1871 inline void Matrix3::setRotateX(Real rads)
1872 {
1873  Real cr = Cos(rads);
1874  Real sr = Sin(rads);
1875  setIdentity();
1876  data[1][1] = cr; data[2][1] = -sr;
1877  data[1][2] = sr; data[2][2] = cr;
1878 }
1879 
1880 inline void Matrix3::setRotateY(Real rads)
1881 {
1882  Real cr = Cos(rads);
1883  Real sr = Sin(rads);
1884  setIdentity();
1885  data[0][0] = cr; data[2][0] = sr;
1886  data[0][2] = -sr; data[2][2] = cr;
1887 }
1888 
1889 inline void Matrix3::setRotateZ(Real rads)
1890 {
1891  Real cr = Cos(rads);
1892  Real sr = Sin(rads);
1893  setIdentity();
1894  data[0][0] = cr; data[1][0] = -sr;
1895  data[0][1] = sr; data[1][1] = cr;
1896 }
1897 
1898 inline void Matrix3::setCrossProduct(const Vector3& v)
1899 {
1900  data[1][0] = -v[2];
1901  data[2][1] = -v[0];
1902  data[2][0] = v[1];
1903 
1904  data[0][1] = v[2];
1905  data[1][2] = v[0];
1906  data[0][2] = -v[1];
1907 
1908  data[0][0] = data[1][1] = data[2][2] = Zero;
1909 }
1910 
1911 inline void Matrix3::setOuterProduct(const Vector3& a,const Vector3& b)
1912 {
1913  data[0][0] = a.x*b.x; data[1][0] = a.x*b.y; data[2][0] = a.x*b.z;
1914  data[0][1] = a.y*b.x; data[1][1] = a.y*b.y; data[2][1] = a.y*b.z;
1915  data[0][2] = a.z*b.x; data[1][2] = a.z*b.y; data[2][2] = a.z*b.z;
1916 }
1917 
1918 inline void Matrix3::get(Matrix3& m) const
1919 {
1920  m.set(*this);
1921 }
1922 
1923 inline void Matrix3::get(Real m [3][3]) const
1924 {
1925  int i,j;
1926  for(i=0; i<3; i++)
1927  for(j=0; j<3; j++)
1928  m[i][j] = data[i][j];
1929 }
1930 
1931 inline void Matrix3::get(Real m [9]) const
1932 {
1933  int i,j,k=0;
1934  for(i=0; i<3; i++)
1935  for(j=0; j<3; j++, k++)
1936  m[k] = data[i][j];
1937 }
1938 
1939 inline void Matrix3::get(Vector3& xb, Vector3& yb, Vector3& zb) const
1940 {
1941  getCol1(xb);
1942  getCol2(yb);
1943  getCol3(zb);
1944 }
1945 
1946 inline void Matrix3::getTranspose(Matrix3& m) const
1947 {
1948  m.setTranspose(*this);
1949 }
1950 
1951 inline void Matrix3::getNegative(Matrix3& m) const
1952 {
1953  m.setNegative(*this);
1954 }
1955 
1956 inline bool Matrix3::getInverse(Matrix3& m) const
1957 {
1958  return m.setInverse(*this);
1959 }
1960 
1961 inline void Matrix3::getCrossProduct(Vector3& v) const
1962 {
1963  v[0] = Half*(data[1][2]-data[2][1]);
1964  v[1] = Half*(data[2][0]-data[0][2]);
1965  v[2] = Half*(data[0][1]-data[1][0]);
1966 }
1967 
1968 inline void Matrix3::inplaceTranspose()
1969 {
1970  Real temp;
1971  int i,j;
1972  for(i=0; i<3; i++) {
1973  for(j=0; j<i; j++) {
1974  temp = data[i][j];
1975  data[i][j] = data[j][i];
1976  data[j][i] = temp;
1977  }
1978  }
1979 }
1980 
1981 inline void Matrix3::inplaceNegative()
1982 {
1983  int i,j;
1984  for(i=0; i<3; i++)
1985  for(j=0; j<3; j++)
1986  data[i][j] = -data[i][j];
1987 }
1988 
1989 inline void Matrix3::inplaceMul(Real s)
1990 {
1991  int i,j;
1992  for(i=0; i<3; i++)
1993  for(j=0; j<3; j++)
1994  data[i][j] *= s;
1995 }
1996 
1997 inline void Matrix3::inplaceDiv(Real s)
1998 {
1999  int i,j;
2000  for(i=0; i<3; i++)
2001  for(j=0; j<3; j++)
2002  data[i][j] /= s;
2003 }
2004 
2005 inline void Matrix3::inplaceRowScale(Real sx, Real sy, Real sz)
2006 {
2007  int j;
2008  for(j=0; j<3; j++) {
2009  data[0][j] *= sx;
2010  data[1][j] *= sy;
2011  data[2][j] *= sz;
2012  }
2013 }
2014 
2015 inline void Matrix3::inplaceColScale(Real sx, Real sy, Real sz)
2016 {
2017  int j;
2018  for(j=0; j<3; j++) {
2019  data[j][0] *= sx;
2020  data[j][1] *= sy;
2021  data[j][2] *= sz;
2022  }
2023 }
2024 
2025 inline bool Matrix3::inplaceInverse()
2026 {
2027  Matrix3 tmp = *this;
2028  return setInverse(tmp);
2029 }
2030 
2031 inline bool Matrix3::isZero(Real eps) const
2032 {
2033  int i,j;
2034  for(i=0;i<3;i++)
2035  for(j=0;j<3;j++)
2036  if(!FuzzyZero(data[i][j],eps)) return false;
2037  return true;
2038 }
2039 
2040 inline bool Matrix3::isEqual(const Matrix3& a,Real eps) const
2041 {
2042  int i,j;
2043  for(i=0;i<3;i++)
2044  for(j=0;j<3;j++)
2045  if(!FuzzyEquals(data[i][j],a.data[i][j],eps)) return false;
2046  return true;
2047 }
2048 
2049 inline bool Matrix3::isIdentity(Real eps) const
2050 {
2051  int i,j;
2052  for(i=0;i<3;i++)
2053  for(j=0;j<3;j++)
2054  if(!FuzzyEquals(data[i][j],Delta(i,j),eps)) return false;
2055  return true;
2056 }
2057 
2058 inline bool Matrix3::isInvertible(Real eps) const
2059 {
2060  return !FuzzyEquals(determinant(),eps);
2061 }
2062 
2063 inline Real Matrix3::trace() const { return data[0][0] + data[1][1] + data[2][2]; }
2064 
2065 inline Real Matrix3::minElement(int* _i,int* _j) const
2066 {
2067  Real vmin=Inf;
2068  int imin=0,jmin=0;
2069  for(int i=0;i<3;i++)
2070  for(int j=0;j<3;j++)
2071  if(data[i][j] < vmin) { //recall data is stored column-major
2072  vmin=data[i][j];
2073  imin=j;
2074  jmin=i;
2075  }
2076  if(_i) *_i=imin;
2077  if(_j) *_j=jmin;
2078  return vmin;
2079 }
2080 
2081 Real Matrix3::maxElement(int* _i,int* _j) const
2082 {
2083  Real vmax=-Inf;
2084  int imin=0,jmin=0;
2085  for(int i=0;i<3;i++)
2086  for(int j=0;j<3;j++)
2087  if(data[i][j] > vmax) { //recall data is stored column-major
2088  vmax=data[i][j];
2089  imin=j;
2090  jmin=i;
2091  }
2092  if(_i) *_i=imin;
2093  if(_j) *_j=jmin;
2094  return vmax;
2095 }
2096 
2097 Real Matrix3::minAbsElement(int* _i,int* _j) const
2098 {
2099  Real vmin=Inf;
2100  int imin=0,jmin=0;
2101  for(int i=0;i<3;i++)
2102  for(int j=0;j<3;j++)
2103  if(Abs(data[i][j]) < vmin) { //recall data is stored column-major
2104  vmin=Abs(data[i][j]);
2105  imin=j;
2106  jmin=i;
2107  }
2108  if(_i) *_i=imin;
2109  if(_j) *_j=jmin;
2110  return vmin;
2111 }
2112 
2113 Real Matrix3::maxAbsElement(int* _i,int* _j) const
2114 {
2115  Real vmax=0;
2116  int imin=0,jmin=0;
2117  for(int i=0;i<3;i++)
2118  for(int j=0;j<3;j++)
2119  if(Abs(data[i][j]) > vmax) { //recall data is stored column-major
2120  vmax=Abs(data[i][j]);
2121  imin=j;
2122  jmin=i;
2123  }
2124  if(_i) *_i=imin;
2125  if(_j) *_j=jmin;
2126  return vmax;
2127 }
2128 
2129 
2130 
2131 
2132 inline const Matrix4& Matrix4::operator = (const Matrix4& m)
2133 {
2134  set(m);
2135  return *this;
2136 }
2137 
2138 inline void Matrix4::operator += (const Matrix4& m)
2139 {
2140  int i,j;
2141  for(i=0; i<4; i++) {
2142  for(j=0; j<4; j++)
2143  data[i][j] += m.data[i][j];
2144  }
2145 }
2146 
2147 inline void Matrix4::operator -= (const Matrix4& m)
2148 {
2149  int i,j;
2150  for(i=0; i<4; i++) {
2151  for(j=0; j<4; j++)
2152  data[i][j] -= m.data[i][j];
2153  }
2154 }
2155 
2156 inline void Matrix4::operator *= (const Matrix4& m)
2157 {
2158  Matrix4 tmp(*this);
2159  mul(tmp, m);
2160 }
2161 
2162 inline void Matrix4::operator *= (Real s)
2163 {
2164  inplaceMul(s);
2165 }
2166 
2167 inline void Matrix4::operator /= (Real s)
2168 {
2169  inplaceDiv(s);
2170 }
2171 
2172 
2173 inline void Matrix4::add(const Matrix4& a, const Matrix4& b)
2174 {
2175  int i,j;
2176  for(i=0; i<4; i++) {
2177  for(j=0; j<4; j++)
2178  data[i][j] = a.data[i][j] + b.data[i][j];
2179  }
2180 }
2181 
2182 inline void Matrix4::sub(const Matrix4& a, const Matrix4& b)
2183 {
2184  int i,j;
2185  for(i=0; i<4; i++) {
2186  for(j=0; j<4; j++)
2187  data[i][j] = a.data[i][j] - b.data[i][j];
2188  }
2189 }
2190 
2191 inline void Matrix4::mul(const Matrix4& a, Real b)
2192 {
2193  int i,j;
2194  for(i=0; i<4; i++) {
2195  for(j=0; j<4; j++)
2196  data[i][j] = a.data[i][j]*b;
2197  }
2198 }
2199 
2200 inline void Matrix4::div(const Matrix4& a, Real b)
2201 {
2202  int i,j;
2203  for(i=0; i<4; i++) {
2204  for(j=0; j<4; j++)
2205  data[i][j] = a.data[i][j]/b;
2206  }
2207 }
2208 
2209 inline void Matrix4::mul(const Vector4& a, Vector4& out) const
2210 {
2211  out.x = data[0][0]*a.x + data[1][0]*a.y + data[2][0]*a.z + data[3][0]*a.w;
2212  out.y = data[0][1]*a.x + data[1][1]*a.y + data[2][1]*a.z + data[3][1]*a.w;
2213  out.z = data[0][2]*a.x + data[1][2]*a.y + data[2][2]*a.z + data[3][2]*a.w;
2214  out.w = data[0][3]*a.x + data[1][3]*a.y + data[2][3]*a.z + data[3][3]*a.w;
2215 }
2216 
2217 inline void Matrix4::mulTranspose(const Vector4& a, Vector4& out) const
2218 {
2219  out.x = data[0][0]*a.x + data[0][1]*a.y + data[0][2]*a.z + data[0][3]*a.w;
2220  out.y = data[1][0]*a.x + data[1][1]*a.y + data[1][2]*a.z + data[1][3]*a.w;
2221  out.z = data[2][0]*a.x + data[2][1]*a.y + data[2][2]*a.z + data[2][3]*a.w;
2222  out.w = data[3][0]*a.x + data[3][1]*a.y + data[3][2]*a.z + data[3][3]*a.w;
2223 }
2224 
2225 inline void Matrix4::mulPoint(const Vector3& a, Vector3& out) const
2226 {
2227  out.x = data[0][0]*a.x + data[1][0]*a.y + data[2][0]*a.z + data[3][0];
2228  out.y = data[0][1]*a.x + data[1][1]*a.y + data[2][1]*a.z + data[3][1];
2229  out.z = data[0][2]*a.x + data[1][2]*a.y + data[2][2]*a.z + data[3][2];
2230 }
2231 
2232 inline void Matrix4::mulVector(const Vector3& a, Vector3& out) const
2233 {
2234  out.x = data[0][0]*a.x + data[1][0]*a.y + data[2][0]*a.z;
2235  out.y = data[0][1]*a.x + data[1][1]*a.y + data[2][1]*a.z;
2236  out.z = data[0][2]*a.x + data[1][2]*a.y + data[2][2]*a.z;
2237 }
2238 
2239 inline void Matrix4::mulVectorTranspose(const Vector3& a, Vector3& out) const
2240 {
2241  out.x = data[0][0]*a.x + data[0][1]*a.y + data[0][2]*a.z;
2242  out.y = data[1][0]*a.x + data[1][1]*a.y + data[1][2]*a.z;
2243  out.z = data[2][0]*a.x + data[2][1]*a.y + data[2][2]*a.z;
2244 }
2245 
2246 inline void Matrix4::set(const Matrix4& m)
2247 {
2248  int i,j;
2249  for(i=0; i<4; i++)
2250  for(j=0; j<4; j++)
2251  data[i][j] = m.data[i][j];
2252 }
2253 
2254 inline void Matrix4::set(Real x)
2255 {
2256  int i,j;
2257  for(i=0; i<4; i++)
2258  for(j=0; j<4; j++)
2259  data[i][j] = x;
2260 }
2261 
2262 inline void Matrix4::set(const Real m [4][4])
2263 {
2264  int i,j;
2265  for(i=0; i<4; i++)
2266  for(j=0; j<4; j++)
2267  data[i][j] = m[i][j];
2268 }
2269 
2270 inline void Matrix4::set(const Real* m)
2271 {
2272  if(!m) {
2273  setZero();
2274  return;
2275  }
2276  int i,j,k=0;
2277  for(i=0; i<4; i++)
2278  for(j=0; j<4; j++, k++)
2279  data[i][j] = m[k];
2280 
2281 }
2282 
2283 inline void Matrix4::set(const Vector3& xb, const Vector3& yb, const Vector3& zb, const Vector3& trans)
2284 {
2285  data[0][3] = data[1][3] = data[2][3] = Zero;
2286  data[3][3] = One;
2287  setCol1(xb);
2288  setCol2(yb);
2289  setCol3(zb);
2290  setCol4(trans);
2291 }
2292 
2293 inline void Matrix4::set(const Vector4& x, const Vector4& y, const Vector4& z, const Vector4& w)
2294 {
2295  setCol1(x);
2296  setCol2(y);
2297  setCol3(z);
2298  setCol4(w);
2299 }
2300 
2301 inline void Matrix4::set(const Matrix3& m)
2302 {
2303  data[0][3] = data[1][3] = data[2][3] = Zero;
2304  data[3][3] = One;
2305  int i,j;
2306  for(i=0; i<3; i++)
2307  for(j=0; j<3; j++)
2308  data[i][j] = m.data[i][j];
2309  data[3][0] = data[3][1] = data[3][2] = Zero;
2310 }
2311 
2312 inline void Matrix4::set(const Matrix3& m, const Vector3& trans)
2313 {
2314  data[0][3] = data[1][3] = data[2][3] = Zero;
2315  data[3][3] = One;
2316  int i,j;
2317  for(i=0; i<3; i++)
2318  for(j=0; j<3; j++)
2319  data[i][j] = m.data[i][j];
2320  setCol4(trans);
2321 }
2322 
2323 inline void Matrix4::setZero()
2324 {
2325  set(Zero);
2326 }
2327 
2328 inline void Matrix4::setIdentity()
2329 {
2330  int i,j;
2331  for(i=0; i<4; i++)
2332  for(j=0; j<4; j++)
2333  data[i][j] = Delta(i,j);
2334 }
2335 
2336 inline void Matrix4::setDiagonal(const Vector4& d)
2337 {
2338  setZero();
2339  d.get(data[0][0],data[1][1],data[2][2],data[3][3]);
2340 }
2341 
2342 inline void Matrix4::setTranslate(const Vector3& trans)
2343 {
2344  int i,j;
2345  for(i=0; i<3; i++)
2346  for(j=0; j<4; j++)
2347  data[i][j] = Delta(i,j);
2348 
2349  trans.get(col4());
2350  data[3][3] = One;
2351 }
2352 
2353 inline void Matrix4::setTranspose(const Matrix4& m)
2354 {
2355  int i,j;
2356  for(i=0; i<4; i++)
2357  for(j=0; j<4; j++)
2358  data[i][j] = m.data[j][i];
2359 }
2360 
2361 inline void Matrix4::setNegative(const Matrix4& m)
2362 {
2363  int i,j;
2364  for(i=0; i<4; i++)
2365  for(j=0; j<4; j++)
2366  data[i][j] = -m.data[i][j];
2367 
2368 }
2369 
2370 inline void Matrix4::setOuterProduct(const Vector4& a,const Vector4& b)
2371 {
2372  data[0][0] = a.x*b.x; data[1][0] = a.x*b.y; data[2][0] = a.x*b.z; data[3][0] = a.x*b.z;
2373  data[0][1] = a.y*b.x; data[1][1] = a.y*b.y; data[2][1] = a.y*b.z; data[3][1] = a.y*b.z;
2374  data[0][2] = a.z*b.x; data[1][2] = a.z*b.y; data[2][2] = a.z*b.z; data[3][2] = a.z*b.z;
2375  data[0][3] = a.w*b.x; data[1][3] = a.w*b.y; data[2][3] = a.w*b.z; data[3][3] = a.w*b.w;
2376 }
2377 
2378 inline void Matrix4::get(Matrix4& m) const { m.set(*this); }
2379 
2380 inline void Matrix4::get(Real m[4][4]) const
2381 {
2382  int i,j;
2383  for(i=0; i<4; i++)
2384  for(j=0; j<4; j++)
2385  m[i][j] = data[i][j];
2386 }
2387 
2388 inline void Matrix4::get(Real m[16]) const
2389 {
2390  int i,j,k=0;
2391  for(i=0; i<4; i++)
2392  for(j=0; j<4; j++, k++)
2393  m[k] = data[i][j];
2394 }
2395 
2396 inline void Matrix4::get(Vector3& xb, Vector3& yb, Vector3& zb, Vector3& trans) const
2397 {
2398  getCol1(xb);
2399  getCol2(yb);
2400  getCol3(zb);
2401  getCol4(trans);
2402 }
2403 
2404 inline void Matrix4::get(Vector4& x, Vector4& y, Vector4& z, Vector4& w) const
2405 {
2406  getCol1(x);
2407  getCol2(y);
2408  getCol3(z);
2409  getCol4(w);
2410 }
2411 
2412 inline void Matrix4::get(Matrix3& m) const
2413 {
2414  int i,j;
2415  for(i=0; i<3; i++)
2416  for(j=0; j<3; j++)
2417  m.data[i][j] = data[i][j];
2418 }
2419 
2420 inline void Matrix4::get(Matrix3& m, Vector3& trans) const
2421 {
2422  int i,j;
2423  for(i=0; i<3; i++)
2424  for(j=0; j<3; j++)
2425  m.data[i][j] = data[i][j];
2426  getCol4(trans);
2427 }
2428 
2429 inline void Matrix4::getTranspose(Matrix4& m) const { m.setTranspose(*this); }
2430 inline void Matrix4::getNegative(Matrix4& m) const { m.setNegative(*this); }
2431 inline bool Matrix4::getInverse(Matrix4& m) const { return m.setInverse(*this); }
2432 
2433 inline void Matrix4::inplaceTranspose()
2434 {
2435  Real temp;
2436  int i,j;
2437  for(i=0; i<4; i++) {
2438  for(j=0; j<i; j++) {
2439  temp = data[i][j];
2440  data[i][j] = data[j][i];
2441  data[j][i] = temp;
2442  }
2443  }
2444 }
2445 
2446 inline void Matrix4::inplaceNegative()
2447 {
2448  int i,j;
2449  for(i=0; i<4; i++) {
2450  for(j=0; j<4; j++) {
2451  data[i][j] = -data[i][j];
2452  }
2453  }
2454 }
2455 
2456 inline bool Matrix4::inplaceInverse()
2457 {
2458  Matrix4 tmp = *this;
2459  return setInverse(tmp);
2460 }
2461 
2462 inline void Matrix4::inplaceMul(Real s)
2463 {
2464  int i,j;
2465  for(i=0;i<4;i++)
2466  for(j=0;j<4;j++)
2467  data[i][j] *= s;
2468 }
2469 
2470 inline void Matrix4::inplaceDiv(Real s)
2471 {
2472  int i,j;
2473  for(i=0;i<4;i++)
2474  for(j=0;j<4;j++)
2475  data[i][j] /= s;
2476 }
2477 
2478 inline bool Matrix4::isZero(Real eps) const
2479 {
2480  int i,j;
2481  for(i=0;i<4;i++)
2482  for(j=0;j<4;j++)
2483  if(!FuzzyZero(data[i][j],eps)) return false;
2484  return true;
2485 }
2486 
2487 inline bool Matrix4::isEqual(const Matrix4& a,Real eps) const
2488 {
2489  int i,j;
2490  for(i=0;i<4;i++)
2491  for(j=0;j<4;j++)
2492  if(!FuzzyEquals(data[i][j],a.data[i][j],eps)) return false;
2493  return true;
2494 }
2495 
2496 inline bool Matrix4::isIdentity(Real eps) const
2497 {
2498  int i,j;
2499  for(i=0;i<4;i++)
2500  for(j=0;j<4;j++)
2501  if(!FuzzyEquals(data[i][j],Delta(i,j),eps)) return false;
2502  return true;
2503 }
2504 
2505 inline bool Matrix4::isInvertible(Real eps) const
2506 {
2507  return !FuzzyEquals(determinant(),eps);
2508 }
2509 
2510 inline Real Matrix4::trace() const { return data[0][0] + data[1][1] + data[2][2] + data[3][3]; }
2511 
2512 inline Real Matrix4::minElement(int* _i,int* _j) const
2513 {
2514  Real vmin=Inf;
2515  int imin=0,jmin=0;
2516  for(int i=0;i<4;i++)
2517  for(int j=0;j<4;j++)
2518  if(data[i][j] < vmin) { //recall data is stored column-major
2519  vmin=data[i][j];
2520  imin=j;
2521  jmin=i;
2522  }
2523  if(_i) *_i=imin;
2524  if(_j) *_j=jmin;
2525  return vmin;
2526 }
2527 
2528 Real Matrix4::maxElement(int* _i,int* _j) const
2529 {
2530  Real vmax=-Inf;
2531  int imin=0,jmin=0;
2532  for(int i=0;i<4;i++)
2533  for(int j=0;j<4;j++)
2534  if(data[i][j] > vmax) { //recall data is stored column-major
2535  vmax=data[i][j];
2536  imin=j;
2537  jmin=i;
2538  }
2539  if(_i) *_i=imin;
2540  if(_j) *_j=jmin;
2541  return vmax;
2542 }
2543 
2544 Real Matrix4::minAbsElement(int* _i,int* _j) const
2545 {
2546  Real vmin=Inf;
2547  int imin=0,jmin=0;
2548  for(int i=0;i<4;i++)
2549  for(int j=0;j<4;j++)
2550  if(Abs(data[i][j]) < vmin) { //recall data is stored column-major
2551  vmin=Abs(data[i][j]);
2552  imin=j;
2553  jmin=i;
2554  }
2555  if(_i) *_i=imin;
2556  if(_j) *_j=jmin;
2557  return vmin;
2558 }
2559 
2560 Real Matrix4::maxAbsElement(int* _i,int* _j) const
2561 {
2562  Real vmax=0;
2563  int imin=0,jmin=0;
2564  for(int i=0;i<4;i++)
2565  for(int j=0;j<4;j++)
2566  if(Abs(data[i][j]) > vmax) { //recall data is stored column-major
2567  vmax=Abs(data[i][j]);
2568  imin=j;
2569  jmin=i;
2570  }
2571  if(_i) *_i=imin;
2572  if(_j) *_j=jmin;
2573  return vmax;
2574 }
2575 
2576 
2577 
2578 
2579 inline bool RigidTransform::operator == (const RigidTransform& a) const { return a.R == R && a.t == t; }
2580 inline bool RigidTransform::operator != (const RigidTransform& a) const { return a.R != R || a.t != t; }
2581 inline const RigidTransform& RigidTransform::operator = (const RigidTransform& x) { set(x); return *this; }
2582 inline void RigidTransform::operator *= (const RigidTransform& x) { t += R*x.t; R *= x.R; }
2583 inline void RigidTransform::operator *= (const Matrix3& r) { inplaceRotate(r); }
2584 inline void RigidTransform::operator += (const Vector3& v) { t += v; }
2585 inline void RigidTransform::operator -= (const Vector3& v) { t -= v; }
2586 inline RigidTransform::operator Matrix4 () const { Matrix4 tmp; tmp.set(R, t); return tmp; }
2588 {
2589  //t = ta + Ra*tb
2590  //R = Ra*Rb
2591  a.R.mul(b.t, t);
2592  t += a.t;
2593  R.mul(a.R,b.R);
2594 }
2596 {
2597  //Ra' = Ra^t
2598  //ta' = -Ra'*ta
2599  //t = ta' + Ra'*tb
2600  //R = Ra'*Rb
2601  a.R.mulTranspose(b.t-a.t, t);
2602  R.mulTransposeA(a.R,b.R);
2603 }
2605 {
2606  //Rb' = Rb^t
2607  //tb' = -Rb'*tb
2608  //t = ta + Ra*tb'
2609  //R = Ra*Rb'
2610  R.mulTransposeB(a.R,b.R);
2611  R.mul(b.t, t);
2612  t.inplaceNegative();
2613  t += a.t;
2614 }
2615 inline void RigidTransform::mul(const RigidTransform& a, const RigidTransform& b) { compose(a,b); }
2616 inline void RigidTransform::mulInverseA(const RigidTransform& a, const RigidTransform& b) { composeInverseA(a,b); }
2617 inline void RigidTransform::mulInverseB(const RigidTransform& a, const RigidTransform& b) { composeInverseB(a,b); }
2618 //vector operators
2619 inline void RigidTransform::mul(const Vector3& a, Vector3& out) const { mulPoint(a,out); }
2620 inline void RigidTransform::mul(const Vector4& a, Vector3& out) const { R.mul(Vector3(a.x,a.y,a.z), out); out.madd(t, a.w); }
2621 inline void RigidTransform::mulPoint(const Vector3& a, Vector3& out) const { R.mul(a,out); out += t; }
2622 inline void RigidTransform::mulVector(const Vector3& a, Vector3& out) const { R.mul(a,out); }
2623 inline void RigidTransform::mulInverse(const Vector3& a, Vector3& out) const { mulPointInverse(a,out); }
2624 inline void RigidTransform::mulInverse(const Vector4& a, Vector3& out) const { Vector3 tmp(a.x,a.y,a.z); tmp.madd(t,-a.w); R.mulTranspose(tmp,out); }
2625 inline void RigidTransform::mulPointInverse(const Vector3& a, Vector3& out) const { R.mulTranspose(a-t,out); }
2626 inline void RigidTransform::mulVectorInverse(const Vector3& a, Vector3& out) const { R.mulTranspose(a,out); }
2627 inline void RigidTransform::setIdentity() { R.setIdentity(); t.setZero(); }
2628 inline void RigidTransform::set(const RigidTransform& x) { set(x.R, x.t); }
2629 inline void RigidTransform::set(const Matrix3& m, const Vector3& v) { R.set(m); t.set(v); }
2630 inline void RigidTransform::set(const Vector3& x, const Vector3& y, const Vector3& z, const Vector3& trans) { R.set(x,y,z); t.set(trans); }
2631 inline void RigidTransform::set(const Matrix4& m) { m.get(R,t); }
2632 inline void RigidTransform::setRotate(const Matrix3& m) { R.set(m); t.setZero(); }
2633 inline void RigidTransform::setTranslate(const Vector3& v) { R.setIdentity(); t.set(v); }
2634 inline void RigidTransform::setRotation(const Matrix3& m) { R.set(m); }
2635 inline void RigidTransform::setTranslation(const Vector3& v) { t.set(v); }
2636 inline void RigidTransform::setInverse(const RigidTransform& x) { R.setTranspose(x.R); R.mul(x.t,t); t.inplaceNegative(); }
2637 inline void RigidTransform::setRotated(const RigidTransform& a, const Matrix3& r) { R.mul(a.R,r); t.set(a.t); }
2638 inline void RigidTransform::setShifted(const RigidTransform& a, const Vector3& v) { R.set(a.R); t.add(a.t,v); }
2639 inline void RigidTransform::get(RigidTransform& x) const { x.set(*this); }
2640 inline void RigidTransform::get(Matrix3& m, Vector3& v) const { m.set(R); v.set(t); }
2641 inline void RigidTransform::get(Vector3& x, Vector3& y, Vector3& z, Vector3& trans) const { R.get(x,y,z); t.get(trans); }
2642 inline void RigidTransform::get(Matrix4& m) const { m.set(R,t); }
2643 inline void RigidTransform::getRotation(Matrix3& m) const { m.set(R); }
2644 inline void RigidTransform::getTranslation(Vector3& v) const { v.set(t); }
2645 inline void RigidTransform::getInverse(RigidTransform& x) { x.setInverse(*this); }
2646 inline void RigidTransform::inplaceInverse() { R.inplaceTranspose(); Vector3 tmp; tmp.setNegative(t); R.mul(tmp,t); }
2647 inline void RigidTransform::inplaceRotate(const Matrix3& m) { R *= m; }
2648 inline void RigidTransform::inplaceShift(const Vector3& v) { t += v; }
2649 inline bool RigidTransform::isIdentity(Real eps) const { return R.isIdentity(eps) && t.isZero(eps); }
2650 
2651 inline const RigidTransform2D& RigidTransform2D::operator = (const RigidTransform2D& x) { set(x); return *this; }
2652 inline void RigidTransform2D::operator *= (const RigidTransform2D& x) { t += R*x.t; R *= x.R; }
2653 inline void RigidTransform2D::compose(const RigidTransform2D& a, const RigidTransform2D& b)
2654 {
2655  a.R.mul(b.t, t);
2656  t += a.t;
2657  R.mul(a.R,b.R);
2658 }
2659 inline void RigidTransform2D::composeInverseA(const RigidTransform2D& a, const RigidTransform2D& b)
2660 {
2661  a.R.mulTranspose(b.t-a.t, t);
2662  R.mulTransposeA(a.R,b.R);
2663 }
2664 inline void RigidTransform2D::composeInverseB(const RigidTransform2D& a, const RigidTransform2D& b)
2665 {
2666  R.mulTransposeB(a.R,b.R);
2667  R.mulTranspose(b.t, t);
2668  t.inplaceNegative();
2669  t += a.t;
2670 }
2671 inline void RigidTransform2D::mul(const RigidTransform2D& a, const RigidTransform2D& b) { compose(a,b); }
2672 inline void RigidTransform2D::mulInverseA(const RigidTransform2D& a, const RigidTransform2D& b) { composeInverseA(a,b); }
2673 inline void RigidTransform2D::mulInverseB(const RigidTransform2D& a, const RigidTransform2D& b) { composeInverseB(a,b); }
2674 inline void RigidTransform2D::mul(const Vector3& a, Vector2& out) const { R.mul(Vector2(a.x,a.y),out); out.madd(t,a.z); }
2675 inline void RigidTransform2D::mul(const Vector2& a, Vector2& out) const { mulPoint(a,out); }
2676 inline void RigidTransform2D::mulPoint(const Vector2& a, Vector2& out) const { R.mul(a,out); out+=t; }
2677 inline void RigidTransform2D::mulVector(const Vector2& a, Vector2& out) const { R.mul(a,out); }
2678 inline void RigidTransform2D::mulInverse(const Vector2& a, Vector2& out) const { mulPointInverse(a,out); }
2679 inline void RigidTransform2D::mulInverse(const Vector3& a, Vector2& out) const { Vector2 tmp(a.x,a.y); tmp.madd(t,-a.z); R.mulTranspose(tmp,out); }
2680 inline void RigidTransform2D::mulPointInverse(const Vector2& a, Vector2& out) const { R.mulTranspose(a-t,out); }
2681 inline void RigidTransform2D::mulVectorInverse(const Vector2& a, Vector2& out) const { R.mulTranspose(a,out); }
2682 inline void RigidTransform2D::setIdentity() { R.setIdentity(); t.setZero(); }
2683 inline void RigidTransform2D::set(const RigidTransform2D& rhs) { R=rhs.R; t=rhs.t; }
2684 inline void RigidTransform2D::set(const Matrix3& mat) { R.set(Vector2(mat(0,0),mat(0,1)),Vector2(mat(1,0),mat(1,1))); t.set(mat(2,0),mat(2,1)); }
2685 inline void RigidTransform2D::set(Real theta,const Vector2& _t) { R.setRotate(theta); t=_t; }
2686 inline void RigidTransform2D::setInverse(const RigidTransform2D& x) { R.setTranspose(x.R); R.mul(x.t,t); t.inplaceNegative(); }
2687 inline void RigidTransform2D::get(RigidTransform2D& rhs) const { rhs.R=R; rhs.t=t; }
2688 inline void RigidTransform2D::get(Matrix3& m) const { m.set(Vector3(R(0,0),R(1,0),Zero),Vector3(R(0,1),R(1,1),Zero),Vector3(t.x,t.y,One)); }
2689 inline void RigidTransform2D::get(Real& theta,Vector2& _t) const { theta=Acos(R(0,0)); if(R(1,0)<0) theta=-theta; _t=t; }
2690 inline bool RigidTransform2D::isIdentity(Real eps) const { return R.isIdentity(eps) && t.isZero(eps); }
2691 
2692 
2693 //inlined standalone functions/operators (often less efficient than the member functions)
2694 
2695 //Vector2
2696 
2697 inline Real dot(const Vector2& a, const Vector2& b)
2698 {
2699  return a.dot(b);
2700 }
2701 
2702 inline void normalize(Vector2& a)
2703 {
2704  a.inplaceNormalize();
2705 }
2706 
2707 inline Real cross(const Vector2& a, const Vector2& b)
2708 {
2709  return a.cross(b);
2710 }
2711 
2712 inline Vector2 project(const Vector2& a, const Vector2& b)
2713 {
2714  Vector2 temp;
2715  temp.setProjection(a,b);
2716  return temp;
2717 }
2718 
2719 inline Vector2 operator - (const Vector2& a)
2720 {
2721  Vector2 temp;
2722  temp.setNegative(a);
2723  return temp;
2724 }
2725 
2726 inline Vector2 operator + (const Vector2& a, const Vector2& b)
2727 {
2728  Vector2 temp;
2729  temp.add(a,b);
2730  return temp;
2731 }
2732 
2733 inline Vector2 operator - (const Vector2& a, const Vector2& b)
2734 {
2735  Vector2 temp;
2736  temp.sub(a,b);
2737  return temp;
2738 }
2739 
2740 inline Vector2 operator * (const Vector2& a, Real b)
2741 {
2742  Vector2 temp;
2743  temp.mul(a,b);
2744  return temp;
2745 }
2746 
2747 inline Vector2 operator * (Real a, const Vector2& b)
2748 {
2749  Vector2 temp;
2750  temp.mul(b,a);
2751  return temp;
2752 }
2753 
2754 inline Vector2 operator / (const Vector2& a, Real b)
2755 {
2756  Vector2 temp;
2757  temp.div(a,b);
2758  return temp;
2759 }
2760 
2761 //Vector3
2762 
2763 inline Real dot(const Vector3& a, const Vector3& b)
2764 {
2765  return a.dot(b);
2766 }
2767 
2768 inline void normalize(Vector3& a)
2769 {
2770  a.inplaceNormalize();
2771 }
2772 
2773 inline Vector3 cross(const Vector3& a, const Vector3& b)
2774 {
2775  Vector3 temp;
2776  temp.setCross(a,b);
2777  return temp;
2778 }
2779 
2780 inline Vector3 project(const Vector3& a, const Vector3& b)
2781 {
2782  Vector3 temp;
2783  temp.setProjection(a,b);
2784  return temp;
2785 }
2786 
2787 inline Vector3 operator - (const Vector3& a)
2788 {
2789  Vector3 temp;
2790  temp.setNegative(a);
2791  return temp;
2792 }
2793 
2794 inline Vector3 operator + (const Vector3& a, const Vector3& b)
2795 {
2796  Vector3 temp;
2797  temp.add(a,b);
2798  return temp;
2799 }
2800 
2801 inline Vector3 operator - (const Vector3& a, const Vector3& b)
2802 {
2803  Vector3 temp;
2804  temp.sub(a,b);
2805  return temp;
2806 }
2807 
2808 inline Vector3 operator * (const Vector3& a, Real b)
2809 {
2810  Vector3 temp;
2811  temp.mul(a,b);
2812  return temp;
2813 }
2814 
2815 inline Vector3 operator * (Real a, const Vector3& b)
2816 {
2817  Vector3 temp;
2818  temp.mul(b,a);
2819  return temp;
2820 }
2821 
2822 inline Vector3 operator / (const Vector3& a, Real b)
2823 {
2824  Vector3 temp;
2825  temp.div(a,b);
2826  return temp;
2827 }
2828 
2829 //Vector4
2830 
2831 inline Real dot(const Vector4& a, const Vector4& b)
2832 {
2833  return a.dot(b);
2834 }
2835 
2836 inline Real dot3(const Vector4& a, const Vector4& b)
2837 {
2838  return a.dot3(b);
2839 }
2840 
2841 inline Real dot3(const Vector4& a, const Vector3& b)
2842 {
2843  return a.dot3(b);
2844 }
2845 
2846 inline Real dot3(const Vector3& a, const Vector4& b)
2847 {
2848  return b.dot3(a);
2849 }
2850 
2851 inline void normalize(Vector4& a)
2852 {
2853  a.inplaceNormalize();
2854 }
2855 
2856 inline Vector4 operator - (const Vector4& a)
2857 {
2858  Vector4 temp;
2859  temp.setNegative(a);
2860  return temp;
2861 }
2862 
2863 inline Vector4 operator + (const Vector4& a, const Vector4& b)
2864 {
2865  Vector4 temp;
2866  temp.add(a,b);
2867  return temp;
2868 }
2869 
2870 inline Vector4 operator - (const Vector4& a, const Vector4& b)
2871 {
2872  Vector4 temp;
2873  temp.sub(a,b);
2874  return temp;
2875 }
2876 
2877 inline Vector4 operator * (const Vector4& a, Real b)
2878 {
2879  Vector4 temp;
2880  temp.mul(a,b);
2881  return temp;
2882 }
2883 
2884 inline Vector4 operator * (Real a, const Vector4& b)
2885 {
2886  Vector4 temp;
2887  temp.mul(b,a);
2888  return temp;
2889 }
2890 
2891 inline Vector4 operator / (const Vector4& a, Real b)
2892 {
2893  Vector4 temp;
2894  temp.div(a,b);
2895  return temp;
2896 }
2897 
2898 //Matrix2
2899 
2900 inline Real determinant(const Matrix2& m) { return m.determinant(); }
2901 inline Real trace(const Matrix2& m) { return m.trace(); }
2902 
2903 inline Matrix2 transpose(const Matrix2& m)
2904 {
2905  Matrix2 temp;
2906  temp.setTranspose(m);
2907  return temp;
2908 }
2909 
2910 inline Matrix2 inverse(const Matrix2& m)
2911 {
2912  Matrix2 temp;
2913  if(!temp.setInverse(m)) { temp.setZero(); temp.inplaceDiv(0.0); }
2914  return temp;
2915 }
2916 
2917 inline Matrix2 outerProduct(const Vector2& a,const Vector2& b) { Matrix2 m; m.setOuterProduct(a,b); return m; }
2918 
2919 inline Matrix2 operator + (const Matrix2& a, const Matrix2& b)
2920 {
2921  Matrix2 m;
2922  m.add(a,b);
2923  return m;
2924 }
2925 
2926 inline Matrix2 operator - (const Matrix2& a, const Matrix2& b)
2927 {
2928  Matrix2 m;
2929  m.sub(a,b);
2930  return m;
2931 }
2932 
2933 inline Matrix2 operator * (const Matrix2& a, const Matrix2& b)
2934 {
2935  Matrix2 m;
2936  m.mul(a,b);
2937  return m;
2938 }
2939 
2940 
2941 inline Matrix2 operator * (const Matrix2& a, Real b)
2942 {
2943  Matrix2 m;
2944  m.mul(a,b);
2945  return m;
2946 }
2947 
2948 inline Matrix2 operator / (const Matrix2& a, Real b)
2949 {
2950  Matrix2 m;
2951  m.div(a,b);
2952  return m;
2953 }
2954 
2955 inline Vector2 operator * (const Matrix2& a, const Vector2& b)
2956 {
2957  Vector2 v;
2958  a.mul(b,v);
2959  return v;
2960 }
2961 
2962 inline Vector2 operator * (const Vector2& a, const Matrix2& b)
2963 {
2964  Vector2 v;
2965  b.mulTranspose(a,v);
2966  return v;
2967 }
2968 
2969 //Matrix3
2970 
2971 inline Real determinant(const Matrix3& m) { return m.determinant(); }
2972 inline Real trace(const Matrix3& m) { return m.trace(); }
2973 
2974 inline Matrix3 transpose(const Matrix3& m)
2975 {
2976  Matrix3 temp;
2977  temp.setTranspose(m);
2978  return temp;
2979 }
2980 
2981 inline Matrix3 inverse(const Matrix3& m)
2982 {
2983  Matrix3 temp;
2984  if(!temp.setInverse(m)) { temp.setZero(); temp.inplaceDiv(0.0); }
2985  return temp;
2986 }
2987 
2988 inline Matrix3 outerProduct(const Vector3& a,const Vector3& b) { Matrix3 m; m.setOuterProduct(a,b); return m; }
2989 
2990 
2991 inline Matrix3 operator + (const Matrix3& a, const Matrix3& b)
2992 {
2993  Matrix3 m;
2994  m.add(a,b);
2995  return m;
2996 }
2997 
2998 inline Matrix3 operator - (const Matrix3& a, const Matrix3& b)
2999 {
3000  Matrix3 m;
3001  m.sub(a,b);
3002  return m;
3003 }
3004 
3005 inline Matrix3 operator * (const Matrix3& a, const Matrix3& b)
3006 {
3007  Matrix3 m;
3008  m.mul(a,b);
3009  return m;
3010 }
3011 
3012 inline Matrix3 operator * (const Matrix3& a, Real b)
3013 {
3014  Matrix3 m;
3015  m.mul(a,b);
3016  return m;
3017 }
3018 
3019 inline Matrix3 operator / (const Matrix3& a, Real b)
3020 {
3021  Matrix3 m;
3022  m.div(a,b);
3023  return m;
3024 }
3025 
3026 inline Vector3 operator * (const Matrix3& a, const Vector3& b)
3027 {
3028  Vector3 v;
3029  a.mul(b,v);
3030  return v;
3031 }
3032 
3033 inline Vector3 operator * (const Vector3& a, const Matrix3& b)
3034 {
3035  Vector3 v;
3036  b.mulTranspose(a,v);
3037  return v;
3038 }
3039 
3040 
3041 //Matrix4
3042 
3043 inline Real determinant(const Matrix4& m) { return m.determinant(); }
3044 inline Real trace(const Matrix4& m) { return m.determinant(); }
3045 
3046 inline Matrix4 transpose(const Matrix4& m)
3047 {
3048  Matrix4 temp;
3049  temp.setTranspose(m);
3050  return temp;
3051 }
3052 
3053 inline Matrix4 inverse(const Matrix4& m)
3054 {
3055  Matrix4 temp;
3056  if(!temp.setInverse(m)) { temp.setZero(); temp.inplaceDiv(0.0); }
3057  return temp;
3058 }
3059 
3060 inline Matrix4 outerProduct(const Vector4& a,const Vector4& b) { Matrix4 m; m.setOuterProduct(a,b); return m; }
3061 
3062 inline Matrix4 operator + (const Matrix4& a, const Matrix4& b)
3063 {
3064  Matrix4 m;
3065  m.add(a,b);
3066  return m;
3067 }
3068 
3069 inline Matrix4 operator - (const Matrix4& a, const Matrix4& b)
3070 {
3071  Matrix4 m;
3072  m.sub(a,b);
3073  return m;
3074 }
3075 
3076 inline Matrix4 operator * (const Matrix4& a, const Matrix4& b)
3077 {
3078  Matrix4 m;
3079  m.mul(a,b);
3080  return m;
3081 }
3082 
3083 inline Matrix4 operator * (const Matrix4& a, Real b)
3084 {
3085  Matrix4 m;
3086  m.mul(a,b);
3087  return m;
3088 }
3089 
3090 inline Matrix4 operator / (const Matrix4& a, Real b)
3091 {
3092  Matrix4 m;
3093  m.div(a,b);
3094  return m;
3095 }
3096 
3097 inline Vector4 operator * (const Matrix4& a, const Vector4& b)
3098 {
3099  Vector4 v;
3100  a.mul(b,v);
3101  return v;
3102 }
3103 
3104 inline Vector4 operator * (const Vector4& a, const Matrix4& b)
3105 {
3106  Vector4 v;
3107  b.mulTranspose(a,v);
3108  return v;
3109 }
3110 
3111 inline Vector3 operator * (const Matrix4& a, const Vector3& b)
3112 {
3113  Vector3 v;
3114  a.mulVector(b,v);
3115  return v;
3116 }
3117 
3118 inline Vector3 operator * (const Vector3& a, const Matrix4& b)
3119 {
3120  Vector3 v;
3121  b.mulVectorTranspose(a,v);
3122  return v;
3123 }
3124 
3125 
3126 //RigidTransform
3127 
3128 inline RigidTransform operator * (const RigidTransform& a, const RigidTransform& b)
3129 {
3130  RigidTransform x;
3131  x.compose(a,b);
3132  return x;
3133 }
3134 
3135 inline RigidTransform operator * (const RigidTransform& a, const Matrix3& b)
3136 {
3137  RigidTransform x;
3138  x.R.mul(a.R,b);
3139  x.t = a.t;
3140  return x;
3141 }
3142 
3143 inline RigidTransform operator * (const Matrix3& a, const RigidTransform& b)
3144 {
3145  RigidTransform x;
3146  x.R.mul(a,b.R);
3147  a.mul(b.t,x.t);
3148  return x;
3149 }
3150 
3151 inline Vector3 operator * (const RigidTransform& a, const Vector3& b)
3152 {
3153  Vector3 x;
3154  a.mul(b,x);
3155  return x;
3156 }
3157 
3158 
3159 inline RigidTransform operator + (const RigidTransform& a, const Vector3& b)
3160 {
3161  return RigidTransform (a.R,a.t+b);
3162 }
3163 
3164 inline RigidTransform operator - (const RigidTransform& a, const Vector3& b)
3165 {
3166  return RigidTransform (a.R,a.t-b);
3167 }
3168 
3169 
3170 
3171 //RigidTransform2D
3172 
3173 inline RigidTransform2D operator * (const RigidTransform2D& a, const RigidTransform2D& b)
3174 {
3175  RigidTransform2D x;
3176  x.compose(a,b);
3177  return x;
3178 }
3179 
3180 inline Vector2 operator * (const RigidTransform2D& a, const Vector2& b)
3181 {
3182  Vector2 x;
3183  a.mul(b,x);
3184  return x;
3185 }
3186 
3187 
3188 
3189 
3190 //IO functions
3191 
3192 std::ostream& operator << (std::ostream&, const Vector2&);
3193 std::istream& operator >> (std::istream&, Vector2&);
3194 
3195 std::ostream& operator << (std::ostream&, const Vector3&);
3196 std::istream& operator >> (std::istream&, Vector3&);
3197 
3198 std::ostream& operator << (std::ostream&, const Vector4&);
3199 std::istream& operator >> (std::istream&, Vector4&);
3200 
3201 std::ostream& operator << (std::ostream&, const Matrix2&);
3202 std::istream& operator >> (std::istream&, Matrix2&);
3203 
3204 std::ostream& operator << (std::ostream&, const Matrix3&);
3205 std::istream& operator >> (std::istream&, Matrix3&);
3206 
3207 std::ostream& operator << (std::ostream&, const Matrix4&);
3208 std::istream& operator >> (std::istream&, Matrix4&);
3209 
3210 std::ostream& operator << (std::ostream&, const RigidTransform&);
3211 std::istream& operator >> (std::istream&, RigidTransform&);
3212 
3213 std::ostream& operator << (std::ostream&, const RigidTransform2D&);
3214 std::istream& operator >> (std::istream&, RigidTransform2D&);
3215 
3217 }
3218 
3219 #endif
Common math typedefs, constants, functions.
A 2x2 matrix class.
Definition: math3d/primitives.h:333
Real length() const
= norm
Definition: math3d/primitives.h:1042
void setRotate(const Matrix3 &)
sets the xform to just rotate
Definition: math3d/primitives.h:2632
void getCrossProduct(Vector3 &) const
if this is a cross-product matrix, returns the vector that performs the cross product ...
Definition: math3d/primitives.h:1961
void compose(const RigidTransform &a, const RigidTransform &b)
this(v) = a(b(v))
Definition: math3d/primitives.h:2587
A 3D vector class.
Definition: math3d/primitives.h:136
void setRotateZ(Real rads)
sets the matrix that rotates ccw by rads around the x axis
Definition: math3d/primitives.h:1889
void getOrthogonalBasis(Vector3 &yb, Vector3 &zb) const
calculates two unit vectors orthogonal to this vector (and positively oriented)
Definition: math3d/primitives.h:1097
Real length() const
= norm
Definition: math3d/primitives.h:993
void mulVectorTranspose(const Vector2 &a, Vector2 &out) const
Definition: math3d/primitives.h:1773
void setOuterProduct(const Vector3 &a, const Vector3 &b)
this = a*b^t
Definition: math3d/primitives.h:1911
double PseudoInv(double x, double eps=dZero)
Returns 1/x if x is nonzero, otherwise 0.
Definition: math.h:226
void setRotateY(Real rads)
sets the matrix that rotates ccw by rads around the x axis
Definition: math3d/primitives.h:1880
void setTranslate(const Vector3 &)
sets the xform to just translate
Definition: math3d/primitives.h:2633
Real Delta(T i, T j)
Kronecker delta.
Definition: math.h:233
Utilities commonly used throughout a program.
A 4D vector class.
Definition: math3d/primitives.h:228
bool setInverse(const Matrix2 &)
returns true when successful
Definition: math3d/primitives.h:1426
A rigid-body transformation.
Definition: math3d/primitives.h:820
void getOrthogonal(Vector2 &) const
calculates an orthogonal vector
Definition: math3d/primitives.h:1013
A 4x4 matrix class.
Definition: math3d/primitives.h:626
void setRotateX(Real rads)
sets the matrix that rotates ccw by rads around the x axis
Definition: math3d/primitives.h:1871
void setProjection(const Vector2 &, const Vector2 &)
sets this to the projection of a on b
Definition: math3d/primitives.h:1003
void mul(const RigidTransform &a, const RigidTransform &b)
mul = compose
Definition: math3d/primitives.h:2615
void composeInverseB(const RigidTransform &a, const RigidTransform &b)
Definition: math3d/primitives.h:2604
Contains all the definitions in the Math3D package.
Definition: AnyGeometry.h:13
void setOuterProduct(const Vector4 &a, const Vector4 &b)
this = a*b^t
Definition: math3d/primitives.h:2370
void mulVector(const Vector3 &a, Vector3 &out) const
assumes w = 0
Definition: math3d/primitives.h:2232
void setPerpendicular(const Vector2 &)
sets this to the vector rotated 90 degrees ccw
Definition: math3d/primitives.h:1000
void setCrossProduct(const Vector3 &)
sets the matrix that performs the vector cross product
Definition: math3d/primitives.h:1898
void composeInverseA(const RigidTransform &a, const RigidTransform &b)
this(v) = a^-1(b(v))
Definition: math3d/primitives.h:2595
Real data[3][3]
column major format
Definition: math3d/primitives.h:607
void setRotation(Real rads)
sets x=cos(rads), y=sin(rads)
Definition: math3d/primitives.h:999
A 3x3 matrix class.
Definition: math3d/primitives.h:469
double Inv(double x)
1/x
Definition: math.h:205
void setRotate(Real rads)
sets the matrix that rotates ccw by rads
Definition: math3d/primitives.h:1452
void mulPoint(const Vector3 &a, Vector3 &out) const
assumes w = 1
Definition: math3d/primitives.h:2225
Vector3 getXBasis() const
the following are for 4x4 homogeneous transforms
Definition: math3d/primitives.h:786
void mulVector(const Vector2 &a, Vector2 &out) const
assumes w = 0
Definition: math3d/primitives.h:1767
Real data[2][2]
column major format
Definition: math3d/primitives.h:449
void mulVectorTranspose(const Vector3 &a, Vector3 &out) const
Definition: math3d/primitives.h:2239
void mulTranspose(const Vector3 &a, Vector3 &out) const
Definition: math3d/primitives.h:1754
Contains all definitions in the Math package.
Definition: WorkspaceBound.h:12
Real cross(const Vector2 &a) const
2d cross product
Definition: math3d/primitives.h:972
A 2D vector class.
Definition: math3d/primitives.h:41
void mulPoint(const Vector2 &a, Vector2 &out) const
assumes w = 1
Definition: math3d/primitives.h:1761
Same as above, but in 2D.
Definition: math3d/primitives.h:902
bool FuzzyEquals(double a, double b, double eps=dEpsilon)
Returns true if a and b are within +/- eps.
Definition: math.h:222
void setOuterProduct(const Vector2 &a, const Vector2 &b)
this = a*b^t
Definition: math3d/primitives.h:1461
void mulInverse(const Vector3 &a, Vector3 &out) const
= mulPointInverse
Definition: math3d/primitives.h:2623
A cross-platform class for reading/writing binary data.
Definition: File.h:47
void setVector(const Vector3 &)
sets w = 0
Definition: math3d/primitives.h:1207
void setHomogeneous(const Vector3 &)
sets w = 1
Definition: math3d/primitives.h:1208
Real data[4][4]
column major format
Definition: math3d/primitives.h:792