Page principale | Liste des namespaces | Hiérarchie des classes | Liste par ordre alphabétique | Liste des composants | Liste des fichiers | Membres des namespaces | Composants | Déclarations

ExQuaternion.cpp

Aller à la documentation de ce fichier.
00001 /*
00002  * ExNihilo 3D Engine
00003  * 
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Library General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  *
00018  * Please read AUTHORS file !!!
00019  * 
00020  * $Id: ExQuaternion.cpp,v 1.4 2002/06/16 00:51:09 binny Exp $
00021  *
00022  */
00023 
00024 #include "ExQuaternion.h"
00025 
00026 ExQuaternion::ExQuaternion()
00027 {
00028         SetQuaternion(1,0,0,0);
00029 }
00030 
00031 ExQuaternion::ExQuaternion(float w,float x,float y,float z)
00032 {
00033         SetQuaternion(w,x,y,z);
00034 }
00035 
00036 ExQuaternion::~ExQuaternion()
00037 {
00038 
00039 }
00040 
00042 // Methode
00044 void ExQuaternion::SetQuaternion(float w,float x,float y,float z)
00045 {
00046         qw=w;
00047         qx=x;
00048         qy=y;
00049         qz=z;
00050 }
00051 
00052 void ExQuaternion::Conjugate(void)
00053 {
00054 
00055 }
00056 
00057 void ExQuaternion::LoadIdentity(void)
00058 {
00059         qx=-qx;
00060         qy=-qy;
00061         qz=-qz;
00062 }
00063 float ExQuaternion::GetMagnitude(void)
00064 {
00065         return(sqrt(qw*qw+qx*qx+qy*qy+qz*qz));
00066         
00067 }
00068 void ExQuaternion::Normalize(void)
00069 {
00070         float factor=GetMagnitude();
00071         float scaleby(1.0/sqrt(factor));
00072         qw=qw*scaleby;
00073         qx=qx*scaleby;
00074         qy=qy*scaleby;
00075         qz=qz*scaleby;
00076 }
00077 
00078 void ExQuaternion::SetEuler(float yaw,float pitch,float roll)
00079 {
00080         float cosY = cosf(yaw/2.0f);
00081         float sinY = sinf(yaw/2.0f);
00082         float cosP = cosf(pitch/2.0f);
00083         float sinP = sinf(pitch/2.0f);
00084         float cosR = cosf(roll/2.0f);
00085         float sinR = sinf(roll/2.0f);
00086 
00087         qw=cosR*sinP*cosY+sinR*cosP*sinY;
00088         qx=cosR*cosP*sinY-sinR*sinP*cosY;
00089         qy=sinR*cosP*cosY-cosR*sinP*sinY;
00090         qz=cosR*cosP*cosY+sinR*sinP*sinY;
00091 
00092 }
00093 void ExQuaternion::CreateFromAxisAngle(float X, float Y, float Z, float degree) 
00094 { 
00095         // This function takes an angle and an axis of rotation, then converts
00096         // it to a quaternion.  An example of an axis and angle is what we pass into
00097         // glRotatef().  That is an axis angle rotation.  It is assumed an angle in 
00098         // degrees is being passed in.  Instead of using glRotatef(), we can now handle
00099         // the rotations our self.
00100 
00101         // The equations for axis angle to quaternions are such:
00102 
00103         // w = cos( theta / 2 )
00104         // x = X * sin( theta / 2 )
00105         // y = Y * sin( theta / 2 )
00106         // z = Z * sin( theta / 2 )
00107 
00108         // First we want to convert the degrees to radians 
00109         // since the angle is assumed to be in radians
00110         float angle = float((degree / 180.0f) * PI);
00111 
00112         // Here we calculate the sin( theta / 2) once for optimization
00113         float result = (float)sin( angle / 2.0f );
00114                 
00115         // Calcualte the w value by cos( theta / 2 )
00116         qw = (float)cos( angle / 2.0f );
00117 
00118         // Calculate the x, y and z of the quaternion
00119         qx = float(X * result);
00120         qy = float(Y * result);
00121         qz = float(Z * result);
00122 }
00123 
00124 void ExQuaternion::CreateMatrix(float *pMatrix)
00125 {
00126         // Make sure the matrix has allocated memory to store the rotation data
00127         if(!pMatrix) return;
00128 
00129         // This function is a necessity when it comes to doing almost anything
00130         // with quaternions.  Since we are working with OpenGL, which uses a 4x4
00131         // homogeneous matrix, we need to have a way to take our quaternion and
00132         // convert it to a rotation matrix to modify the current model view matrix.
00133         // We pass in a 4x4 matrix, which is a 1D array of 16 floats.  This is how OpenGL
00134         // allows us to pass in a matrix to glMultMatrixf(), so we use a single dimensioned array.
00135         // After about 300 trees murdered and 20 packs of chalk depleted, the
00136         // mathematicians came up with these equations for a quaternion to matrix converion:
00137         //
00138         //     ¦        2     2                                                                                          ¦
00139     //     ¦ 1 - (2y  + 2z )   2xy + 2zw         2xz - 2yw                      0        ¦
00140     //     ¦                                                                                                                     ¦
00141     //     ¦                          2     2                                                    ¦
00142     // M = ¦ 2xy - 2zw         1 - (2x  + 2z )   2zy + 2xw                      0        ¦
00143     //     ¦                                                                                                                     ¦
00144     //     ¦                                            2     2                  ¦
00145     //     ¦ 2xz + 2yw         2yz - 2xw         1 - (2x  + 2y )        0        ¦
00146     //     ¦                                                                                                                     ¦
00147         //     ¦                                                                                                                         ¦
00148         //     ¦ 0                                 0                             0                                      1        |                                                                                                       ¦
00149         //     ¦                                                                                                                         ¦
00150         // 
00151         // This is of course a 4x4 matrix.  Notice that a rotational matrix can just
00152         // be a 3x3 matrix, but since OpenGL uses a 4x4 matrix, we need to conform to the man.
00153         // Remember that the identity matrix of a 4x4 matrix has a diagonal of 1's, where
00154         // the rest of the indices are 0.  That is where we get the 0's lining the sides, and
00155         // the 1 at the bottom-right corner.  Since OpenGL matrices are row by column, we fill
00156         // in our matrix accordingly below.
00157         
00158         // First row
00159         pMatrix[ 0] = 1.0f - 2.0f * ( qy * qy + qz * qz );  
00160         pMatrix[ 1] = 2.0f * ( qx * qy - qw * qz );  
00161         pMatrix[ 2] = 2.0f * ( qx * qz + qw * qy );  
00162         pMatrix[ 3] = 0.0f;  
00163 
00164         // Second row
00165         pMatrix[ 4] = 2.0f * ( qx * qy + qw * qz );  
00166         pMatrix[ 5] = 1.0f - 2.0f * ( qx * qx + qz * qz );  
00167         pMatrix[ 6] = 2.0f * ( qy * qz - qw * qx );  
00168         pMatrix[ 7] = 0.0f;  
00169 
00170         // Third row
00171         pMatrix[ 8] = 2.0f * ( qx * qz - qw * qy );  
00172         pMatrix[ 9] = 2.0f * ( qy * qz + qw * qx );  
00173         pMatrix[10] = 1.0f - 2.0f * ( qx * qx + qy * qy );  
00174         pMatrix[11] = 0.0f;  
00175 
00176         // Fourth row
00177         pMatrix[12] = 0;  
00178         pMatrix[13] = 0;  
00179         pMatrix[14] = 0;  
00180         pMatrix[15] = 1.0f;
00181 
00182         // Now pMatrix[] is a 4x4 homogeneous matrix that can be applied to an OpenGL Matrix
00183 }
00184 
00186 // Operator
00188 ExQuaternion ExQuaternion::operator* (const ExQuaternion &Q)
00189 {
00190         ExQuaternion result;
00191         result.qw=(Q.qw*qw)-(Q.qx*qx)-(Q.qy*qy)-(Q.qz*qz);
00192         result.qx=(Q.qw*qx)-(Q.qx*qw)-(Q.qy*qz)-(Q.qz*qy);
00193         result.qy=(Q.qw*qy)-(Q.qy*qw)-(Q.qz*qx)-(Q.qx*qz);
00194         result.qz=(Q.qw*qz)-(Q.qz*qw)-(Q.qx*qy)-(Q.qz*qx);
00195         return result;
00196 }
00197 ExQuaternion ExQuaternion::operator+ (const ExQuaternion &Q)
00198 {
00199          return ExQuaternion(qw+Q.qw,qx+Q.qx,qy+Q.qy,qz+Q.qz);
00200 }
00202 // friends methode
00204 
00205 std::ostream& operator<<(std::ostream& s,const ExQuaternion &q)
00206 {
00207 Guard(friend std::ostream& operator<<(std::ostream& s,const ExQuaternion &q))
00208         s<<"W:"<<q.qw<<"X:"<<q.qx<<"Y:"<<q.qy<<"Z:"<<q.qz<<std::endl;
00209         return s;
00210 UnGuard
00211 }

Généré le Tue Oct 28 12:43:38 2003 pour ExNihilo par doxygen 1.3.4