Mercurial > Math
changeset 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 | e00321d11fe1 |
children | ea32c94fc495 |
files | include/Math.h include/Transform.h |
diffstat | 2 files changed, 201 insertions(+), 64 deletions(-) [+] |
line diff
1.1 --- a/include/Math.h Wed May 08 22:50:09 2013 -0500 1.2 +++ b/include/Math.h Sun May 12 03:05:37 2013 -0500 1.3 @@ -3,6 +3,7 @@ 1.4 1.5 #include "Vector.h" 1.6 #include "Matrix.h" 1.7 +#include "Transform.h" 1.8 1.9 /////////////////////////////////////////////////////////////////////////////////// 1.10 // Notes for improvement 1.11 @@ -132,15 +133,6 @@ 1.12 1.13 ////////////////////////////////////////////////////////////////////////// 1.14 1.15 - template <typename T> 1.16 - void get_rot_mat33(Matrix33<T> & m, float angle, Vector3<T> v); 1.17 - 1.18 - template <typename T> 1.19 - void get_transform_mat44(Matrix33<T> & m, float angle, Vector3<T> v, Vector3<T> o); 1.20 - 1.21 - 1.22 - ////////////////////////////////////////////////////////////////////////// 1.23 - 1.24 inline double deg_to_rad(double deg) { return deg * PI_DIV_180; }; 1.25 inline double rad_to_deg(double rad) { return rad * INV_PI_DIV_180; }; 1.26 1.27 @@ -148,60 +140,5 @@ 1.28 1.29 } // namespace arda 1.30 1.31 -//////////////////////////////////////////////////////////////////////////////// 1.32 -template <typename T> 1.33 -void arda::Math::get_rot_mat33(arda::Math::Matrix33<T> & m, float angle, arda::Math::Vector3<T> v) 1.34 - { 1.35 - // TODO Replace == comparision of floating point number! 1.36 - if (0.0 == v.length()) 1.37 - return; 1.38 - 1.39 - // TODO: I should also immediately return identity if angle is a multiple of 2*PI but I'm not 1.40 - // yet sure how I should I check for that (taking into account floating point imprecision). 1.41 - 1.42 - 1.43 - v.normalize(); 1.44 - 1.45 - float c = cos(angle); 1.46 - float s = sin(angle); 1.47 - float one_minus_c = 1.0f - c; 1.48 - 1.49 - m.assign( 1.50 - 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 , 1.51 - 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 , 1.52 - 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 1.53 - ); 1.54 - } 1.55 - 1.56 -//////////////////////////////////////////////////////////////////////////////// 1.57 -template <typename T> 1.58 -void arda::Math::get_transform_mat44(arda::Math::Matrix44<T> & m, 1.59 - float angle, arda::Math::Vector3<T> v, 1.60 - arda::Math::Vector3<T> p) 1.61 - { 1.62 - arda::Math::Matrix33f m33(0); 1.63 - get_rot_mat33(m33, angle, v); 1.64 - arda::Math::Vector3f p1 = m33 * p; 1.65 - 1.66 - m[0] = m33[0]; 1.67 - m[1] = m33[1]; 1.68 - m[2] = m33[2]; 1.69 - m[3] = 0.0f; 1.70 - 1.71 - m[4] = m33[3]; 1.72 - m[5] = m33[4]; 1.73 - m[6] = m33[5]; 1.74 - m[7] = 0.0f; 1.75 - 1.76 - m[8] = m33[6]; 1.77 - m[9] = m33[7]; 1.78 - m[10] = m33[8]; 1.79 - m[11] = 0.0f; 1.80 - 1.81 - m[12] = p.x - p1.x; 1.82 - m[13] = p.y - p1.y; 1.83 - m[14] = p.z - p1.z; 1.84 - m[15] = 1.0f; 1.85 - } 1.86 1.87 #endif
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/include/Transform.h Sun May 12 03:05:37 2013 -0500 2.3 @@ -0,0 +1,200 @@ 2.4 +#ifndef TRANSFORM_H_ 2.5 +#define TRANSFORM_H_ 2.6 + 2.7 +// Needs Vector.h and Matrix.h, but this file is not intended to be included 2.8 +// directly. Just include Math.h and everything will be set up correctly. 2.9 + 2.10 +namespace arda 2.11 + { 2.12 + namespace Math 2.13 + { 2.14 + 2.15 + ////////////////////////////////////////////////////////////////////////// 2.16 + 2.17 + // Transformation by distance vector d 2.18 + template <typename T> 2.19 + void get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector4<T> d); 2.20 + 2.21 + // Rotation by angle around vector v 2.22 + template <typename T> 2.23 + void get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v); 2.24 + 2.25 + template <typename T> 2.26 + void get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v); 2.27 + 2.28 + // Uniform scaling by factor of s 2.29 + template <typename T> 2.30 + void get_scale_mat44(arda::Math::Matrix44<T> & M, float s); 2.31 + 2.32 + // Non-uniform scaling 2.33 + template <typename T> 2.34 + void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s); 2.35 + 2.36 + // Non-uniform scaling along arbitrary axes 2.37 + template <typename T> 2.38 + void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s, 2.39 + arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z); 2.40 + 2.41 + // Shear ith coordinate with respect to jth coordinate by s. i and j are zero based column indexes. 2.42 + // (x = 0, y = 1, z = 2) 2.43 + template <typename T> 2.44 + void get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s); 2.45 + 2.46 + template <typename T> 2.47 + void get_transform_mat44(arda::Math::Matrix44<T> & M, 2.48 + float angle, arda::Math::Vector3<T> v, 2.49 + arda::Math::Vector3<T> d); 2.50 + 2.51 + // 2.52 + template <typename T> 2.53 + void get_rot_about_point_mat44(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v, arda::Math::Vector3<T> p); 2.54 + 2.55 + } // namespace Math 2.56 + 2.57 + } // namespace arda 2.58 + 2.59 + 2.60 +//////////////////////////////////////////////////////////////////////////////// 2.61 +template <typename T> 2.62 +void arda::Math::get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> d) 2.63 + { 2.64 + M.setidentity(); 2.65 + M.setcol(3, d.x, d.y, d.z, 1); 2.66 + } 2.67 + 2.68 +//////////////////////////////////////////////////////////////////////////////// 2.69 +template <typename T> 2.70 +void arda::Math::get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v) 2.71 + { 2.72 + // TODO Replace == comparision of floating point number! 2.73 + if (0.0 == v.length()) { 2.74 + M.setidentity(); 2.75 + return; 2.76 + } 2.77 + 2.78 + // TODO: I should also immediately return identity if angle is a multiple of 2*PI but I'm not 2.79 + // yet sure how I should I check for that (taking into account floating point imprecision). 2.80 + 2.81 + 2.82 + v.normalize(); 2.83 + 2.84 + float c = cos(angle); 2.85 + float s = sin(angle); 2.86 + float one_minus_c = 1.0f - c; 2.87 + 2.88 + M.assign( 2.89 + 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 , 2.90 + 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 , 2.91 + 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 2.92 + ); 2.93 + } 2.94 + 2.95 +//////////////////////////////////////////////////////////////////////////////// 2.96 +template <typename T> 2.97 +void arda::Math::get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v) 2.98 + { 2.99 + arda::Math::Matrix33<T> M33; 2.100 + arda::Math::get_rot_mat33(M33, angle, v); 2.101 + 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); 2.102 + } 2.103 + 2.104 +//////////////////////////////////////////////////////////////////////////////// 2.105 +template <typename T> 2.106 +void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, float s) 2.107 + { 2.108 + M.setidentity(); 2.109 + M *= s; 2.110 + M[15] = 1; 2.111 + } 2.112 + 2.113 +//////////////////////////////////////////////////////////////////////////////// 2.114 +template <typename T> 2.115 +void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s) 2.116 + { 2.117 + M.setidentity(); 2.118 + M[0] = s.x; 2.119 + M[5] = s.y; 2.120 + M[10] = s.z; 2.121 + } 2.122 + 2.123 +//////////////////////////////////////////////////////////////////////////////// 2.124 +template <typename T> 2.125 +void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s, 2.126 + arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z) 2.127 + { 2.128 + // TODO Replace == comparision of floating point number! 2.129 + assert(0 == x.dot(y)); 2.130 + assert(0 == x.dot(z)); 2.131 + assert(0 == y.dot(z)); 2.132 + 2.133 + arda::Math::Matrix44<T> F, Ft, S; 2.134 + F.setcol(0, x.x, x.y, x.z, 0); 2.135 + F.setcol(1, y.x, y.y, y.z, 0); 2.136 + F.setcol(2, z.x, z.y, z.z, 0); 2.137 + F.setcol(3, 0, 0, 0, 1); 2.138 + 2.139 + Ft = arda::Math::transpose(F); 2.140 + arda::Math::get_scale_mat44(S, s); 2.141 + 2.142 + M = F * S * Ft; 2.143 + } 2.144 + 2.145 +//////////////////////////////////////////////////////////////////////////////// 2.146 +template <typename T> 2.147 +void arda::Math::get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s) 2.148 + { 2.149 + assert(i<3 && i>=0); 2.150 + assert(j<3 && j>=0); 2.151 + M.setidentity(); 2.152 + M[4*j + i] = s; 2.153 + } 2.154 + 2.155 + 2.156 +//////////////////////////////////////////////////////////////////////////////// 2.157 +template <typename T> 2.158 +void arda::Math::get_transform_mat44(arda::Math::Matrix44<T> & M, 2.159 + float angle, arda::Math::Vector3<T> v, 2.160 + arda::Math::Vector3<T> d) 2.161 + { 2.162 + arda::Math::Matrix33<T> M33; 2.163 + arda::Math::get_rot_mat33(M33, angle, v); 2.164 + 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); 2.165 + } 2.166 + 2.167 + 2.168 + 2.169 +//////////////////////////////////////////////////////////////////////////////// 2.170 +// I initially wrote this while trying to do a rotation about an arbitrary vector with the center of rotation at point p. 2.171 +// It seems to work, but I'm not sure of it's generality. 2.172 + 2.173 +template <typename T> 2.174 +void arda::Math::get_rot_about_point_mat44(arda::Math::Matrix44<T> & M, 2.175 + float angle, arda::Math::Vector3<T> v, 2.176 + arda::Math::Vector3<T> p) 2.177 + { 2.178 + arda::Math::Matrix33f M33(0); 2.179 + get_rot_mat33(M33, angle, v); 2.180 + arda::Math::Vector3f p1 = M33 * p; 2.181 + 2.182 + M[0] = M33[0]; 2.183 + M[1] = M33[1]; 2.184 + M[2] = M33[2]; 2.185 + M[3] = 0; 2.186 + 2.187 + M[4] = M33[3]; 2.188 + M[5] = M33[4]; 2.189 + M[6] = M33[5]; 2.190 + M[7] = 0; 2.191 + 2.192 + M[8] = M33[6]; 2.193 + M[9] = M33[7]; 2.194 + M[10] = M33[8]; 2.195 + M[11] = 0; 2.196 + 2.197 + M[12] = p.x - p1.x; 2.198 + M[13] = p.y - p1.y; 2.199 + M[14] = p.z - p1.z; 2.200 + M[15] = 1; 2.201 + } 2.202 + 2.203 +#endif