Go to the documentation of this file.00001
00002 #include <blort/TomGine/tgQuaternion.h>
00003 #include <stdio.h>
00004
00005 using namespace TomGine;
00006
00007 tgQuaternion::tgQuaternion(){
00008 x=0.0;
00009 y=0.0;
00010 z=0.0;
00011 w=1.0;
00012 }
00013
00014 tgQuaternion::tgQuaternion(float x, float y, float z, float w){
00015 this->x = x;
00016 this->y = y;
00017 this->z = z;
00018 this->w = w;
00019 }
00020
00021
00022
00023
00024 void tgQuaternion::normalise(){
00025
00026 float mag2 = w * w + x * x + y * y + z * z;
00027 if (fabs(mag2 - 1.0f) > ftol) {
00028 float mag = sqrt(mag2);
00029 w /= mag;
00030 x /= mag;
00031 y /= mag;
00032 z /= mag;
00033 }
00034 }
00035
00036
00037
00038 tgQuaternion tgQuaternion::getConjugate() const{
00039 return tgQuaternion(-x, -y, -z, w);
00040 }
00041
00042
00043 tgQuaternion tgQuaternion::operator+ (const tgQuaternion &q2) const{
00044 tgQuaternion rq;
00045 rq.x = x+q2.x;
00046 rq.y = y+q2.y;
00047 rq.z = z+q2.z;
00048 rq.w = w+q2.w;
00049
00050 return rq;
00051 }
00052
00053
00054 tgQuaternion tgQuaternion::operator- (const tgQuaternion &q2) const{
00055 tgQuaternion rq;
00056 rq.x = x-q2.x;
00057 rq.y = y-q2.y;
00058 rq.z = z-q2.z;
00059 rq.w = w-q2.w;
00060 return rq;
00061 }
00062
00063
00064
00065 tgQuaternion tgQuaternion::operator* (const tgQuaternion &rq){
00066
00067 return tgQuaternion(w * rq.x + x * rq.w + y * rq.z - z * rq.y,
00068 w * rq.y + y * rq.w + z * rq.x - x * rq.z,
00069 w * rq.z + z * rq.w + x * rq.y - y * rq.x,
00070 w * rq.w - x * rq.x - y * rq.y - z * rq.z);
00071 }
00072
00073 tgQuaternion tgQuaternion::operator* (const float f){
00074 return tgQuaternion(x*f, y*f, z*f, w*f);
00075 }
00076
00077
00078
00079 vec3 tgQuaternion::operator* (const vec3 &vec){
00080 vec3 vn(vec);
00081 vn.normalize();
00082
00083 tgQuaternion vecQuat, resQuat;
00084 vecQuat.x = vn.x;
00085 vecQuat.y = vn.y;
00086 vecQuat.z = vn.z;
00087 vecQuat.w = 0.0f;
00088
00089 resQuat = vecQuat * getConjugate();
00090 resQuat = *this * resQuat;
00091
00092 return (vec3(resQuat.x, resQuat.y, resQuat.z));
00093 }
00094
00095
00096 void tgQuaternion::fromAxis(const vec3 &v, float angle){
00097 float sinAngle;
00098 angle *= 0.5f;
00099 vec3 vn(v);
00100 vn.normalize();
00101
00102 sinAngle = sin(angle);
00103
00104 x = (vn.x * sinAngle);
00105 y = (vn.y * sinAngle);
00106 z = (vn.z * sinAngle);
00107 w = cos(angle);
00108 }
00109
00110
00111 void tgQuaternion::fromEuler(float roll, float pitch, float yaw){
00112
00113
00114
00115
00116 float p = pitch / 2.0f;
00117 float y = yaw / 2.0f;
00118 float r = roll / 2.0f;
00119
00120 float sinp = sin(p);
00121 float siny = sin(y);
00122 float sinr = sin(r);
00123 float cosp = cos(p);
00124 float cosy = cos(y);
00125 float cosr = cos(r);
00126
00127 this->x = sinr * cosp * cosy - cosr * sinp * siny;
00128 this->y = cosr * sinp * cosy + sinr * cosp * siny;
00129 this->z = cosr * cosp * siny - sinr * sinp * cosy;
00130 this->w = cosr * cosp * cosy + sinr * sinp * siny;
00131
00132 normalise();
00133 }
00134
00135
00136 void tgQuaternion::fromMatrix(mat4 m){
00137 w = sqrt(1.0f + m[0] + m[5] + m[10]) / 2.0f;
00138 float w4 = (4.0f * w);
00139 x = (m[9] - m[6]) / w4 ;
00140 y = (m[2] - m[8]) / w4 ;
00141 z = (m[4] - m[1]) / w4 ;
00142
00143 normalise();
00144 }
00145
00146
00147 void tgQuaternion::fromMatrix(mat3 m){
00148 w = sqrt(1.0f + m[0] + m[4] + m[8]) / 2.0f;
00149 float w4 = (4.0f * w);
00150 x = (m[7] - m[5]) / w4 ;
00151 y = (m[2] - m[6]) / w4 ;
00152 z = (m[3] - m[1]) / w4 ;
00153
00154 normalise();
00155 }
00156
00157
00158 mat4 tgQuaternion::getMatrix4() const{
00159 float x2 = x * x;
00160 float y2 = y * y;
00161 float z2 = z * z;
00162 float xy = x * y;
00163 float xz = x * z;
00164 float yz = y * z;
00165 float wx = w * x;
00166 float wy = w * y;
00167 float wz = w * z;
00168
00169 mat4 rot;
00170 rot[0]=1.0f - 2.0f * (y2 + z2);
00171 rot[1]=2.0f * (xy - wz);
00172 rot[2]=2.0f * (xz + wy);
00173 rot[3]=0.0f;
00174 rot[4]=2.0f * (xy + wz);
00175 rot[5]=1.0f - 2.0f * (x2 + z2);
00176 rot[6]=2.0f * (yz - wx);
00177 rot[7]=0.0f;
00178 rot[8]=2.0f * (xz - wy);
00179 rot[9]=2.0f * (yz + wx);
00180 rot[10]=1.0f - 2.0f * (x2 + y2);
00181 rot[11]=0.0f;
00182 rot[12]=0.0f;
00183 rot[13]=0.0f;
00184 rot[14]=0.0f;
00185 rot[15]=1.0f;
00186
00187 return rot;
00188 }
00189
00190
00191 mat3 tgQuaternion::getMatrix3() const{
00192 float x2 = x * x;
00193 float y2 = y * y;
00194 float z2 = z * z;
00195 float xy = x * y;
00196 float xz = x * z;
00197 float yz = y * z;
00198 float wx = w * x;
00199 float wy = w * y;
00200 float wz = w * z;
00201
00202 mat3 rot;
00203 rot[0]=1.0f - 2.0f * (y2 + z2);
00204 rot[1]=2.0f * (xy - wz);
00205 rot[2]=2.0f * (xz + wy);
00206 rot[3]=2.0f * (xy + wz);
00207 rot[4]=1.0f - 2.0f * (x2 + z2);
00208 rot[5]=2.0f * (yz - wx);
00209 rot[6]=2.0f * (xz - wy);
00210 rot[7]=2.0f * (yz + wx);
00211 rot[8]=1.0f - 2.0f * (x2 + y2);
00212
00213 return rot;
00214 }
00215
00216
00217
00218 void tgQuaternion::getAxisAngle(vec3& axis, float& angle) const{
00219 float scale = sqrt(x * x + y * y + z * z);
00220 axis.x = x / scale;
00221 axis.y = y / scale;
00222 axis.z = z / scale;
00223 angle = acos(w) * 2.0f;
00224 if(angle < 0.0 || angle > (2.0*PI))
00225 angle = 0.0;
00226 }
00227
00228 void tgQuaternion::print() const{
00229 printf("x: %f y: %f z: %f w: %f\n", x, y, z, w);
00230 }