RTFX  0.3
Real time special effects collaborative visualization and production library.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
algebra.hpp
Go to the documentation of this file.
1 
20 #ifndef CS488_ALGEBRA_HPP
21 #define CS488_ALGEBRA_HPP
22 
23 #pragma warning(disable: 4996)
24 
25 #include <iostream>
26 #include <algorithm>
27 #include <cmath>
28 
29 #include "RTFX_API.h"
30 #include "RTFXBoostIncludes.h"
31 
33 namespace RTFX
34 {
35  #ifndef M_PI
36 
38  static const double M_PI = 3.14159265358979323846;
39 
40  #endif
41 
46  class RTFXAPI Point2D
47  {
48  public:
49 
52  {
53  v[0] = 0.0;
54  v[1] = 0.0;
55  }
56 
58  Point2D( double _x, double _y )
59  {
60  v[0] = _x;
61  v[1] = _y;
62  }
63 
65  Point2D( const Point2D& _other )
66  {
67  v[0] = _other.v[0];
68  v[1] = _other.v[1];
69  }
70 
72  Point2D& operator =( const Point2D& _other )
73  {
74  v[0] = _other.v[0];
75  v[1] = _other.v[1];
76  return *this;
77  }
78 
80  double& operator[](size_t _idx)
81  {
82  return v[ _idx ];
83  }
84 
86  double operator[]( size_t _idx ) const
87  {
88  return v[ _idx ];
89  }
90 
92  double * data()
93  {
94  return v;
95  }
96 
97  private:
98  friend class boost::serialization::access;
99 
100  double v[2];
101 
102  template<class Archive>
103  void serialize( Archive &_ar, const unsigned int _version )
104  {
105  _ar & v[0] & v[1];
106  }
107  };
108 
113  class RTFXAPI Point3D
114  {
115  public:
116 
119  {
120  v[0] = 0.0;
121  v[1] = 0.0;
122  v[2] = 0.0;
123  }
124 
126  Point3D( double _other[3] )
127  {
128  v[0] = _other[0];
129  v[1] = _other[1];
130  v[2] = _other[2];
131  }
132 
134  Point3D( double _x, double _y, double _z )
135  {
136  v[0] = _x;
137  v[1] = _y;
138  v[2] = _z;
139  }
140 
142  Point3D( const Point3D& _other )
143  {
144  v[0] = _other.v[0];
145  v[1] = _other.v[1];
146  v[2] = _other.v[2];
147  }
148 
150  Point3D& operator =( const Point3D& _other )
151  {
152  v[0] = _other.v[0];
153  v[1] = _other.v[1];
154  v[2] = _other.v[2];
155  return *this;
156  }
157 
159  Point3D& operator =( const double _other[3] )
160  {
161  v[0] = _other[0];
162  v[1] = _other[1];
163  v[2] = _other[2];
164  return *this;
165  }
166 
168  bool operator ==( const Point3D _other )
169  {
170  if ( v[0] == _other[0] && v[1] == _other[1] && v[2] == _other[2] )
171  return true;
172  return false;
173  }
174 
177  Point3D& operator =(const int _other[2])
178  {
179  v[0] = _other[0];
180  v[1] = _other[1];
181  v[2] = 0;
182  return *this;
183  }
184 
186  double length2() const
187  {
188  return ( v[0] * v[0] ) + ( v[1] * v[1] ) + ( v[2] * v[2] );
189  }
190 
192  double length() const
193  {
194  return sqrt( length2() );
195  }
196 
198  double& operator[]( size_t _idx )
199  {
200  return v[ _idx ];
201  }
202 
204  double operator[]( size_t _idx ) const
205  {
206  return v[ _idx ];
207  }
208 
210  double dot(const Point3D& _other) const
211  {
212  return ( v[0] * _other.v[0] ) + ( v[1] * _other.v[1] ) + ( v[2] * _other.v[2] );
213  }
214 
216  double * data()
217  {
218  return v;
219  }
220 
221  private:
222  friend class boost::serialization::access;
223 
224  double v[3];
225 
226  template<class Archive>
227  void serialize( Archive &_ar, const unsigned int _version )
228  {
229  _ar & v[0] & v[1] & v[2];
230  }
231  };
232 
235  class RTFXAPI Vector3D
236  {
237  public:
238 
241  {
242  v[0] = 0.0;
243  v[1] = 0.0;
244  v[2] = 0.0;
245  }
246 
248  Vector3D( double _x, double _y, double _z )
249  {
250  v[0] = _x;
251  v[1] = _y;
252  v[2] = _z;
253  }
254 
256  Vector3D( const Vector3D& _other )
257  {
258  v[0] = _other.v[0];
259  v[1] = _other.v[1];
260  v[2] = _other.v[2];
261  }
262 
264  Vector3D& operator =( const Vector3D& _other )
265  {
266  v[0] = _other.v[0];
267  v[1] = _other.v[1];
268  v[2] = _other.v[2];
269  return *this;
270  }
271 
273  double& operator[]( size_t _idx )
274  {
275  return v[ _idx ];
276  }
277 
279  double operator[]( size_t _idx ) const
280  {
281  return v[ _idx ];
282  }
283 
285  double dot( const Vector3D& _other ) const
286  {
287  return ( v[0] * _other.v[0] ) + ( v[1] * _other.v[1] ) + ( v[2] * _other.v[2] );
288  }
289 
291  double length2() const
292  {
293  return ( v[0] * v[0] ) + ( v[1] * v[1] ) + ( v[2] * v[2] );
294  }
295 
297  double length() const
298  {
299  return sqrt( length2() );
300  }
301 
303  double normalize();
304 
306  Vector3D cross(const Vector3D& _other) const
307  {
308  return Vector3D( v[1]*_other[2] - v[2]*_other[1],
309  v[2]*_other[0] - v[0]*_other[2],
310  v[0]*_other[1] - v[1]*_other[0] );
311  }
312 
314  double * data()
315  {
316  return v;
317  }
318 
319  private:
320  friend class boost::serialization::access;
321 
322  double v[3];
323 
324  template<class Archive>
325  void serialize( Archive &_ar, const unsigned int _version )
326  {
327  _ar & v[0] & v[1] & v[2];
328  }
329  };
330 
332  inline Vector3D operator *( double _s, const Vector3D& _v )
333  {
334  return Vector3D( _s * _v[0], _s * _v[1], _s * _v[2] );
335  }
336 
338  inline Vector3D operator +( const Vector3D& _a, const Vector3D& _b )
339  {
340  return Vector3D( _a[0] + _b[0], _a[1] + _b[1], _a[2] + _b[2] );
341  }
342 
344  inline Point3D operator +( const Point3D& _a, const Vector3D& _b )
345  {
346  return Point3D(_a[0]+_b[0], _a[1]+_b[1], _a[2]+_b[2]);
347  }
348 
350  inline Point2D operator +( const Point2D& _a, const Point2D& _b )
351  {
352  return Point2D(_a[0]+_b[0], _a[1]+_b[1] );
353  }
354 
356  inline Point2D operator -( const Point2D& _a, const Point2D& _b )
357  {
358  return Point2D(_a[0]-_b[0], _a[1]-_b[1] );
359  }
360 
362  inline Point3D operator +( const Point3D& _a, const Point3D& _b )
363  {
364  return Point3D(_a[0]+_b[0], _a[1]+_b[1], _a[2]+_b[2]);
365  }
366 
368  inline Point3D operator *( const double& _a, const Point3D& _b )
369  {
370  return Point3D( _a * _b[0], _a * _b[1], _a * _b[2] );
371  }
372 
374  inline Vector3D operator -( const Point3D& _a, const Point3D& _b )
375  {
376  return Vector3D(_a[0]-_b[0], _a[1]-_b[1], _a[2]-_b[2]);
377  }
378 
380  inline Vector3D operator -( const Vector3D& _a, const Vector3D& _b )
381  {
382  return Vector3D(_a[0]-_b[0], _a[1]-_b[1], _a[2]-_b[2]);
383  }
384 
386  inline Vector3D operator -( const Vector3D& _a )
387  {
388  return Vector3D(-_a[0], -_a[1], -_a[2]);
389  }
390 
392  inline Point3D operator -( const Point3D& _a, const Vector3D& _b )
393  {
394  return Point3D(_a[0]-_b[0], _a[1]-_b[1], _a[2]-_b[2]);
395  }
396 
398  inline bool operator == ( const Vector3D& _a, const Vector3D& _b )
399  {
400  return ( _a[0] == _b[0] && _a[1] == _b[1] && _a[2] == _b[2] );
401  }
402 
404  inline bool operator != ( const Vector3D& _a, const Vector3D& _b )
405  {
406  return ( _a[0] != _b[0] && _a[1] != _b[1] && _a[2] != _b[2] );
407  }
408 
410  inline Point3D operator -( const Vector3D& _a, const Point3D& _b )
411  {
412  return Point3D(_a[0]-_b[0], _a[1]-_b[1], _a[2]-_b[2]);
413  }
414 
416  inline Vector3D cross( const Vector3D& _a, const Vector3D& _b )
417  {
418  return _a.cross(_b);
419  }
420 
422  inline std::ostream& operator <<( std::ostream& _os, const Point2D& _p )
423  {
424  return _os << "p<" << _p[0] << "," << _p[1] << ">";
425  }
426 
428  inline std::ostream& operator <<( std::ostream& _os, const Point3D& _p )
429  {
430  return _os << "p<" << _p[0] << "," << _p[1] << "," << _p[2] << ">";
431  }
432 
434  inline std::ostream& operator <<( std::ostream& _os, const Vector3D& _v )
435  {
436  return _os << "v<" << _v[0] << "," << _v[1] << "," << _v[2] << ">";
437  }
438 
439  /* Forward reference for Matrix4x4 */
440  class RTFXAPI Matrix4x4;
441 
447  class RTFXAPI Vector4D
448  {
449  public:
450 
453  {
454  v[0] = 0.0;
455  v[1] = 0.0;
456  v[2] = 0.0;
457  v[3] = 0.0;
458  }
459 
461  Vector4D( double _x, double _y, double _z, double _w )
462  {
463  v[0] = _x;
464  v[1] = _y;
465  v[2] = _z;
466  v[3] = _w;
467  }
468 
470  Vector4D(const Vector4D& _other)
471  {
472  v[0] = _other.v[0];
473  v[1] = _other.v[1];
474  v[2] = _other.v[2];
475  v[3] = _other.v[3];
476  }
477 
479  Vector4D& operator =(const Vector4D& _other)
480  {
481  v[0] = _other.v[0];
482  v[1] = _other.v[1];
483  v[2] = _other.v[2];
484  v[3] = _other.v[3];
485  return *this;
486  }
487 
489  double& operator[]( size_t _idx )
490  {
491  return v[ _idx ];
492  }
493 
495  double operator[]( size_t _idx ) const
496  {
497  return v[ _idx ];
498  }
499 
500  private:
501  friend class boost::serialization::access;
502 
503  double v[4];
504 
505  template<class Archive>
506  void serialize( Archive &_ar, const unsigned int _version )
507  {
508  _ar & v[0] & v[1] & v[2] & v[3];
509  }
510  };
511 
518  class RTFXAPI Matrix4x4
519  {
520  public:
521 
524  {
525  // Construct an identity matrix
526  std::fill(v, v+16, 0.0);
527  v[0] = 1.0;
528  v[5] = 1.0;
529  v[10] = 1.0;
530  v[15] = 1.0;
531  }
532 
535  Matrix4x4( double _a0, double _a1, double _a2,
536  double _b0, double _b1, double _b2,
537  double _c0, double _c1, double _c2 )
538  {
539  v[0] = _a0;
540  v[1] = _a1;
541  v[2] = _a2;
542  v[3] = 0;
543 
544  v[4] = _b0;
545  v[5] = _b1;
546  v[6] = _b2;
547  v[7] = 0;
548 
549  v[8] = _c0;
550  v[9] = _c1;
551  v[10] = _c2;
552  v[11] = 0;
553 
554  v[12] = 0;
555  v[13] = 0;
556  v[14] = 0;
557  v[15] = 1;
558  }
559 
561  Matrix4x4( const Matrix4x4& _other )
562  {
563  for ( int i = 0; i < 16; i ++ )
564  v[i] = _other.v[i];
565  }
566 
568  Matrix4x4( const Vector4D _row1, const Vector4D _row2, const Vector4D _row3,
569  const Vector4D _row4)
570  {
571  v[0] = _row1[0];
572  v[1] = _row1[1];
573  v[2] = _row1[2];
574  v[3] = _row1[3];
575 
576  v[4] = _row2[0];
577  v[5] = _row2[1];
578  v[6] = _row2[2];
579  v[7] = _row2[3];
580 
581  v[8] = _row3[0];
582  v[9] = _row3[1];
583  v[10] = _row3[2];
584  v[11] = _row3[3];
585 
586  v[12] = _row4[0];
587  v[13] = _row4[1];
588  v[14] = _row4[2];
589  v[15] = _row4[3];
590  }
591 
593  Matrix4x4( double *_vals )
594  {
595  for ( int i = 0; i < 16; i ++ )
596  v[i] = _vals[i];
597  }
598 
600  Matrix4x4& operator=( const Matrix4x4& _other )
601  {
602  for ( int i = 0; i < 16; i ++ )
603  v[i] = _other.v[i];
604 
605  return *this;
606  }
607 
609  Vector4D getRow( size_t _row ) const
610  {
611  return Vector4D(v[4*_row], v[4*_row+1], v[4*_row+2], v[4*_row+3]);
612  }
613 
615  double *getRow( size_t _row )
616  {
617  return (double*)v + 4*_row;
618  }
619 
621  Vector4D getColumn( size_t _col ) const
622  {
623  return Vector4D(v[_col], v[4+_col], v[8+_col], v[12+_col]);
624  }
625 
628  Vector4D operator[]( size_t _row ) const
629  {
630  return getRow( _row );
631  }
632 
635  double *operator[]( size_t _row )
636  {
637  return getRow( _row );
638  }
639 
641  Matrix4x4 transpose() const
642  {
643  return Matrix4x4( getColumn(0), getColumn(1),
644  getColumn(2), getColumn(3) );
645  }
646 
648  Matrix4x4 invert() const;
649 
651  double det ();
652 
654  const double *begin() const
655  {
656  return (double*)v;
657  }
658 
660  const double *end() const
661  {
662  return begin() + 16;
663  }
664 
666  double * data()
667  {
668  return v;
669  }
670 
672  bool operator ==( Matrix4x4 &_o )
673  {
674  const double * data = _o.data();
675  for ( int i = 0; i < 16; i ++ )
676  {
677  if ( v[i] != data[i] )
678  return false;
679  }
680  return true;
681  }
682 
683  private:
684  double v[16];
685 
686  friend class boost::serialization::access;
687 
688  template<class Archive>
689  void serialize( Archive &_ar, const unsigned int _version )
690  {
691  for ( int i = 0; i < 16; i ++ )
692  _ar & v[i];
693  }
694  };
695 
697  inline Matrix4x4 operator *( const Matrix4x4& _a, const Matrix4x4& _b )
698  {
699  Matrix4x4 ret_;
700 
701  for(size_t i = 0; i < 4; ++i)
702  {
703  Vector4D row_ = _a.getRow(i);
704 
705  for(size_t j = 0; j < 4; ++j)
706  {
707  ret_[i][j] = row_[0] * _b[0][j] + row_[1] * _b[1][j] +
708  row_[2] * _b[2][j] + row_[3] * _b[3][j];
709  }
710  }
711 
712  return ret_;
713  }
714 
716  inline Vector3D operator *( const Matrix4x4& _M, const Vector3D& _v )
717  {
718  return Vector3D(
719  _v[0] * _M[0][0] + _v[1] * _M[0][1] + _v[2] * _M[0][2],
720  _v[0] * _M[1][0] + _v[1] * _M[1][1] + _v[2] * _M[1][2],
721  _v[0] * _M[2][0] + _v[1] * _M[2][1] + _v[2] * _M[2][2]);
722  }
723 
725  inline Point3D operator *( const Matrix4x4& _M, const Point3D& _p )
726  {
727  return Point3D(
728  _p[0] * _M[0][0] + _p[1] * _M[0][1] + _p[2] * _M[0][2] + _M[0][3],
729  _p[0] * _M[1][0] + _p[1] * _M[1][1] + _p[2] * _M[1][2] + _M[1][3],
730  _p[0] * _M[2][0] + _p[1] * _M[2][1] + _p[2] * _M[2][2] + _M[2][3]);
731  }
732 
734  inline Vector3D transNorm( const Matrix4x4& _M, const Vector3D& _n )
735  {
736  return Vector3D(
737  _n[0] * _M[0][0] + _n[1] * _M[1][0] + _n[2] * _M[2][0],
738  _n[0] * _M[0][1] + _n[1] * _M[1][1] + _n[2] * _M[2][1],
739  _n[0] * _M[0][2] + _n[1] * _M[1][2] + _n[2] * _M[2][2]);
740  }
741 
743  inline std::ostream& operator <<( std::ostream& _os, const Matrix4x4& _M )
744  {
745  return _os << "[" << _M[0][0] << " " << _M[0][1] << " "
746  << _M[0][2] << " " << _M[0][3] << "]" << std::endl
747  << "[" << _M[1][0] << " " << _M[1][1] << " "
748  << _M[1][2] << " " << _M[1][3] << "]" << std::endl
749  << "[" << _M[2][0] << " " << _M[2][1] << " "
750  << _M[2][2] << " " << _M[2][3] << "]" << std::endl
751  << "[" << _M[3][0] << " " << _M[3][1] << " "
752  << _M[3][2] << " " << _M[3][3] << "]";
753  }
754 
757  class RTFXAPI Colour
758  {
759  public:
760 
762  Colour() {};
763 
765  ~Colour() {};
766 
767 
769  Colour( const Colour& _other )
770  {
771  rgb[0] = _other.rgb[0];
772  rgb[1] = _other.rgb[1];
773  rgb[2] = _other.rgb[2];
774 
775  hsv[0] = _other.hsv[0];
776  hsv[1] = _other.hsv[1];
777  hsv[2] = _other.hsv[2];
778 
779  alpha = _other.alpha;
780  }
781 
783  Colour& operator =( const Colour& _other )
784  {
785  rgb[0] = _other.rgb[0];
786  rgb[1] = _other.rgb[1];
787  rgb[2] = _other.rgb[2];
788 
789  hsv[0] = _other.hsv[0];
790  hsv[1] = _other.hsv[1];
791  hsv[2] = _other.hsv[2];
792 
793  alpha = _other.alpha;
794  return *this;
795  }
796 
798  void SetRGB( double _r, double _g, double _b )
799  {
800  rgb[0] = _r;
801  rgb[1] = _g;
802  rgb[2] = _b;
803  }
804 
806  void SetRed( double _r )
807  {
808  rgb[0] = _r;
809  }
810 
812  void SetGreen( double _g )
813  {
814  rgb[1] = _g;
815  }
816 
818  void SetBlue( double _b )
819  {
820  rgb[2] = _b;
821  }
822 
824  void SetHSV( double _h, double _s, double _v )
825  {
826  hsv[0] = _h;
827  hsv[1] = _s;
828  hsv[2] = _v;
829  }
830 
832  void SetHue( double _h )
833  {
834  hsv[0] = _h;
835  }
836 
838  void SetSaturation( double _s )
839  {
840  hsv[1] = _s;
841  }
842 
844  void SetValue( double _v )
845  {
846  hsv[2] = _v;
847  }
848 
850  double * GetRGB() { return rgb; }
851 
853  double GetRed() { return rgb[0]; }
854 
856  double GetGreen() { return rgb[1]; }
857 
859  double GetBlue() { return rgb[2]; }
860 
862  double * GetHSV() { return hsv; }
863 
865  double GetHue() { return hsv[0]; }
866 
868  double GetSaturation() { return hsv[1]; }
869 
871  double GetValue() { return hsv[2]; }
872 
874  void SetAlpha( double _alpha )
875  {
876  alpha = _alpha;
877  }
878 
880  double GetAlpha() { return alpha; }
881 
883  void MultiplyByScalar( double _s )
884  {
885  SetRGB( rgb[0] * _s, rgb[1] * _s, rgb[2] * _s );
886  SetHSV( hsv[0] * _s, hsv[1] * _s, hsv[2] * _s );
887  alpha *= _s;
888  }
889 
891  void AddColour( Colour _c )
892  {
893  SetRGB( rgb[0] + _c.GetRed(), rgb[1] + _c.GetGreen(), rgb[2] + _c.GetBlue() );
894  SetHSV( hsv[0] + _c.GetHue(), hsv[1] + _c.GetSaturation(), hsv[2] + _c.GetValue() );
895  alpha += _c.GetAlpha();
896  }
897 
899  bool operator ==( Colour &_c )
900  {
901  if ( GetRed() != _c.GetRed() ||
902  GetGreen() != _c.GetGreen() ||
903  GetBlue() != _c.GetBlue() )
904  return false;
905 
906  if ( GetAlpha() != _c.GetAlpha() )
907  return false;
908 
909  if ( GetHue() != _c.GetHue() ||
910  GetSaturation() != _c.GetSaturation() ||
911  GetValue() != _c.GetValue() )
912  return false;
913  return true;
914  }
915 
916  private:
917 
919  void Init()
920  {
921  SetRGB( 0, 0, 0 );
922  SetHSV( 0, 0, 0 );
923  SetAlpha( 1 );
924  }
925 
927  double rgb[3];
928 
930  double hsv[3];
931 
933  double alpha;
934 
935  friend class boost::serialization::access;
936 
937  template<class Archive>
938  void serialize( Archive &_ar, const unsigned int _version )
939  {
940  _ar & rgb[0] & rgb[1] & rgb[2] & hsv[0] & hsv[1] & hsv[2] & alpha;
941  };
942  };
943 }
944 #endif // CS488_ALGEBRA_HPP