view include/Math.h @ 12:1d2b25d4517f

Lot's of updates, some quite old since I guess I forgot to commit a while back. But I just added rotation matrix related things.
author Eris Caffee <discordia@eldalin.com>
date Mon, 06 May 2013 01:06:12 -0500
parents 398894c52b69
children e00321d11fe1
line source
1 #ifndef MATH_H_
2 #define MATH_H_
4 #include "Vector.h"
5 #include "Matrix.h"
7 ///////////////////////////////////////////////////////////////////////////////////
8 // Notes for improvement
9 //
10 // The angle related constants (PI, 2PI, etc) and functions (deg_to_rad, rad_to_deg)
11 // could be made faster by using #define's. In fact, this would turn them into
12 // compile time operations. But it would also put them, effectively, in the
13 // global namespace. Do I want that? For now I'm leaving things as const
14 // variables and inline functions. I can profile things later to see if changes
15 // are really needed.
17 namespace arda
18 {
20 ////////////////////////////////////////////////////////////////////////////////
21 // Angles
23 namespace Math
24 {
25 // This many decimals is enough to cover even IEEE quad precision (128 bit)
26 // reals. Run on PA-RISC lately? :)
27 long double const PI = 3.14159265358979323846264338327950288;
28 long double const TWO_PI = 6.28318530717958647692528676655900577;
29 long double const PI_DIV_180 = 0.01745329251994329576923690768488613;
30 long double const INV_PI_DIV_180 = 57.29577951308232087679815481410517033;
32 //////////////////////////////////////////////////////////////////////////
33 // Mixed Vector / Matrix operations.
34 // * *=
35 // Defined for Vector * Matrix and Matrix * Vector, but these
36 // operators are not part of the class. They are defined independently.
37 //
39 // Vector2 * Matrix22
40 template <typename T>
41 inline Vector2<T>& operator*=(Vector2<T> & v,
42 Matrix22<T> const & m)
43 {
44 Vector2<T> vres(0);
45 vres[0] = v[0]*m[0] + v[1]*m[1];
46 vres[1] = v[0]*m[2] + v[1]*m[3];
47 v = vres;
48 return v;
49 }
51 template <typename T>
52 inline Vector2<T> operator*(Vector2<T> const & v,
53 Matrix22<T> const & m)
54 { return Vector2<T>(v) *= m; }
56 // Note: can't define Matrix *= Vector since the result is a Vector.
57 template <typename T>
58 inline Vector2<T> operator*(Matrix22<T> const & m,
59 Vector2<T> const & v)
60 {
61 Vector2<T> vres(0);
62 vres[0] = m[0]*v[0] + m[2]*v[1];
63 vres[1] = m[1]*v[0] + m[3]*v[1];
64 return vres;
65 }
67 ////////////////////////////////////////
68 // Vector3 * Matrix33
69 template <typename T>
70 inline Vector3<T>& operator*=(Vector3<T> & v,
71 Matrix33<T> const & m)
72 {
73 Vector3<T> vres(0);
74 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2];
75 vres[1] = v[0]*m[3] + v[1]*m[4] + v[2]*m[5];
76 vres[2] = v[0]*m[6] + v[1]*m[7] + v[2]*m[8];
77 v = vres;
78 return v;
79 }
81 template <typename T>
82 inline Vector3<T> operator*(Vector3<T> const & v,
83 Matrix33<T> const & m)
84 { return Vector3<T>(v) *= m; }
86 // Matrix * Vector
87 // Note: can't define Matrix *= Vector since the result is a Vector.
88 template <typename T>
89 inline Vector3<T> operator*(Matrix33<T> const & m,
90 Vector3<T> const & v)
91 {
92 Vector3<T> vres(0);
93 vres[0] = m[0]*v[0] + m[3]*v[1] + m[6]*v[2];
94 vres[1] = m[1]*v[0] + m[4]*v[1] + m[7]*v[2];
95 vres[2] = m[2]*v[0] + m[5]*v[1] + m[8]*v[2];
96 return vres;
97 }
99 ////////////////////////////////////////
100 // Vector4 * Matrix44
101 template <typename T>
102 inline Vector4<T>& operator*=(Vector4<T> & v,
103 Matrix44<T> const & m)
104 {
105 Vector4<T> vres(0);
106 vres[0] = v[0]*m[0] + v[1]*m[1] + v[2]*m[2] + v[3]*m[3];
107 vres[1] = v[0]*m[4] + v[1]*m[5] + v[2]*m[6] + v[3]*m[7];
108 vres[8] = v[0]*m[8] + v[1]*m[9] + v[2]*m[10] + v[3]*m[11];
109 vres[3] = v[0]*m[12] + v[1]*m[13] + v[2]*m[14] + v[3]*m[15];
110 v = vres;
111 return v;
112 }
114 template <typename T>
115 inline Vector4<T> operator*(Vector4<T> const & v,
116 Matrix44<T> const & m)
117 { return Vector4<T>(v) *= m; }
119 // Matrix * Vector
120 // Note: can't define Matrix *= Vector since the result is a Vector.
121 template <typename T>
122 inline Vector4<T> operator*(Matrix44<T> const & m,
123 Vector4<T> const & v)
124 {
125 Vector4<T> vres(0);
126 vres[0] = m[0]*v[0] + m[4]*v[1] + m[8]*v[2] + m[12]*v[3];
127 vres[1] = m[1]*v[0] + m[5]*v[1] + m[9]*v[2] + m[13]*v[3];
128 vres[2] = m[2]*v[0] + m[6]*v[1] + m[10]*v[2] + m[14]*v[3];
129 vres[3] = m[3]*v[0] + m[7]*v[1] + m[11]*v[2] + m[15]*v[3];
130 return vres;
131 }
133 //////////////////////////////////////////////////////////////////////////
135 template <typename T>
136 void get_rot_mat33(Matrix33<T> & m, float rot, Vector3<T> v);
139 //////////////////////////////////////////////////////////////////////////
141 inline double deg_to_rad(double deg) { return deg * PI_DIV_180; };
142 inline double rad_to_deg(double rad) { return rad * INV_PI_DIV_180; };
144 } // namespace Math
146 } // namespace arda
148 ////////////////////////////////////////////////////////////////////////////////
149 template <typename T>
150 void arda::Math::get_rot_mat33(arda::Math::Matrix33<T> & m, float theta, arda::Math::Vector3<T> v)
151 {
152 m.setidentity();
153 if (0.0 == v.length())
154 return;
156 // TODO: I should also immediately return identity if theta is a multiple of 2*PI but I'm not
157 // yet sure how I should I check for that (taking into account floating point imprecision).
160 v.normalize();
162 float c = cos(theta);
163 float s = sin(theta);
164 float one_minus_c = 1.0f - c;
166 m.assign(
167 c + one_minus_c * v.x * v.x , one_minus_c * v.x * v.y + s * v.z , one_minus_c * v.x * v.z - s * v.y ,
168 one_minus_c * v.x * v.y - s * v.z , c + one_minus_c * v.y * v.y , one_minus_c * v.y * v.z + s * v.x ,
169 one_minus_c * v.x * v.z + s * v.y , one_minus_c * v.y * v.z - s * v.x , c + one_minus_c * v.z * v.z
170 );
171 }
173 #endif