view include/Transform.h @ 14:c029247daf0e

Started new header Transform.h to collect functions that produce transformation matrices.
author Eris Caffee <discordia@eldalin.com>
date Sun, 12 May 2013 03:05:37 -0500
parents
children ea32c94fc495
line source
1 #ifndef TRANSFORM_H_
2 #define TRANSFORM_H_
4 // Needs Vector.h and Matrix.h, but this file is not intended to be included
5 // directly. Just include Math.h and everything will be set up correctly.
7 namespace arda
8 {
9 namespace Math
10 {
12 //////////////////////////////////////////////////////////////////////////
14 // Transformation by distance vector d
15 template <typename T>
16 void get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector4<T> d);
18 // Rotation by angle around vector v
19 template <typename T>
20 void get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v);
22 template <typename T>
23 void get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v);
25 // Uniform scaling by factor of s
26 template <typename T>
27 void get_scale_mat44(arda::Math::Matrix44<T> & M, float s);
29 // Non-uniform scaling
30 template <typename T>
31 void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s);
33 // Non-uniform scaling along arbitrary axes
34 template <typename T>
35 void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s,
36 arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z);
38 // Shear ith coordinate with respect to jth coordinate by s. i and j are zero based column indexes.
39 // (x = 0, y = 1, z = 2)
40 template <typename T>
41 void get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s);
43 template <typename T>
44 void get_transform_mat44(arda::Math::Matrix44<T> & M,
45 float angle, arda::Math::Vector3<T> v,
46 arda::Math::Vector3<T> d);
48 //
49 template <typename T>
50 void get_rot_about_point_mat44(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v, arda::Math::Vector3<T> p);
52 } // namespace Math
54 } // namespace arda
57 ////////////////////////////////////////////////////////////////////////////////
58 template <typename T>
59 void arda::Math::get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> d)
60 {
61 M.setidentity();
62 M.setcol(3, d.x, d.y, d.z, 1);
63 }
65 ////////////////////////////////////////////////////////////////////////////////
66 template <typename T>
67 void arda::Math::get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v)
68 {
69 // TODO Replace == comparision of floating point number!
70 if (0.0 == v.length()) {
71 M.setidentity();
72 return;
73 }
75 // TODO: I should also immediately return identity if angle is a multiple of 2*PI but I'm not
76 // yet sure how I should I check for that (taking into account floating point imprecision).
79 v.normalize();
81 float c = cos(angle);
82 float s = sin(angle);
83 float one_minus_c = 1.0f - c;
85 M.assign(
86 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 ,
87 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 ,
88 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
89 );
90 }
92 ////////////////////////////////////////////////////////////////////////////////
93 template <typename T>
94 void arda::Math::get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v)
95 {
96 arda::Math::Matrix33<T> M33;
97 arda::Math::get_rot_mat33(M33, angle, v);
98 M.assign(M33[0], M33[1], M33[2], 0, M33[3], M33[4], M33[5], 0, M33[6], M33[7], M33[8], 0, 0, 0, 0, 1);
99 }
101 ////////////////////////////////////////////////////////////////////////////////
102 template <typename T>
103 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, float s)
104 {
105 M.setidentity();
106 M *= s;
107 M[15] = 1;
108 }
110 ////////////////////////////////////////////////////////////////////////////////
111 template <typename T>
112 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s)
113 {
114 M.setidentity();
115 M[0] = s.x;
116 M[5] = s.y;
117 M[10] = s.z;
118 }
120 ////////////////////////////////////////////////////////////////////////////////
121 template <typename T>
122 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s,
123 arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z)
124 {
125 // TODO Replace == comparision of floating point number!
126 assert(0 == x.dot(y));
127 assert(0 == x.dot(z));
128 assert(0 == y.dot(z));
130 arda::Math::Matrix44<T> F, Ft, S;
131 F.setcol(0, x.x, x.y, x.z, 0);
132 F.setcol(1, y.x, y.y, y.z, 0);
133 F.setcol(2, z.x, z.y, z.z, 0);
134 F.setcol(3, 0, 0, 0, 1);
136 Ft = arda::Math::transpose(F);
137 arda::Math::get_scale_mat44(S, s);
139 M = F * S * Ft;
140 }
142 ////////////////////////////////////////////////////////////////////////////////
143 template <typename T>
144 void arda::Math::get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s)
145 {
146 assert(i<3 && i>=0);
147 assert(j<3 && j>=0);
148 M.setidentity();
149 M[4*j + i] = s;
150 }
153 ////////////////////////////////////////////////////////////////////////////////
154 template <typename T>
155 void arda::Math::get_transform_mat44(arda::Math::Matrix44<T> & M,
156 float angle, arda::Math::Vector3<T> v,
157 arda::Math::Vector3<T> d)
158 {
159 arda::Math::Matrix33<T> M33;
160 arda::Math::get_rot_mat33(M33, angle, v);
161 M.assign(M33[0], M33[1], M33[2], 0, M33[3], M33[4], M33[5], 0, M33[6], M33[7], M33[8], 0, d.x, d.y, d.z, 1);
162 }
166 ////////////////////////////////////////////////////////////////////////////////
167 // I initially wrote this while trying to do a rotation about an arbitrary vector with the center of rotation at point p.
168 // It seems to work, but I'm not sure of it's generality.
170 template <typename T>
171 void arda::Math::get_rot_about_point_mat44(arda::Math::Matrix44<T> & M,
172 float angle, arda::Math::Vector3<T> v,
173 arda::Math::Vector3<T> p)
174 {
175 arda::Math::Matrix33f M33(0);
176 get_rot_mat33(M33, angle, v);
177 arda::Math::Vector3f p1 = M33 * p;
179 M[0] = M33[0];
180 M[1] = M33[1];
181 M[2] = M33[2];
182 M[3] = 0;
184 M[4] = M33[3];
185 M[5] = M33[4];
186 M[6] = M33[5];
187 M[7] = 0;
189 M[8] = M33[6];
190 M[9] = M33[7];
191 M[10] = M33[8];
192 M[11] = 0;
194 M[12] = p.x - p1.x;
195 M[13] = p.y - p1.y;
196 M[14] = p.z - p1.z;
197 M[15] = 1;
198 }
200 #endif