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