Allink
v0.1
|
00001 #include <Matematica.h> 00002 00003 00004 Quaternione::Quaternione(){ 00005 m_x = m_y = m_z = 0.; 00006 m_w = 1.0; 00007 } 00008 void Quaternione::AxisRotation(double x,double y,double z, double degrees){ 00009 double Angle = double((degrees / 180.0) * PI); 00010 // Here we calculate the sin( theta / 2) once for optimization 00011 double Result = (double)sin( Angle / 2.0 ); 00012 // Calcualte the w value by cos( theta / 2 ) 00013 m_w = (double)cos( Angle / 2.0 ); 00014 // Calculate the x, y and z of the quaternion 00015 m_x = double(x * Result); 00016 m_y = double(y * Result); 00017 m_z = double(z * Result); 00018 //printf("%lf %lf %lf %lf\n",m_x,m_y,m_z,m_w); 00019 } 00020 void Quaternione::CreateMatrix(double *pMatrix) 00021 { 00022 // Make sure the matrix has allocated memory to store the rotation data 00023 if(!pMatrix) return; 00024 // First row 00025 pMatrix[ 0] = 1.0 - 2.0 * ( m_y * m_y + m_z * m_z ); 00026 pMatrix[ 1] = 2.0 * (m_x * m_y + m_z * m_w); 00027 pMatrix[ 2] = 2.0 * (m_x * m_z - m_y * m_w); 00028 pMatrix[ 3] = 0.0; 00029 // Second row 00030 pMatrix[ 4] = 2.0 * ( m_x * m_y - m_z * m_w ); 00031 pMatrix[ 5] = 1.0 - 2.0 * ( m_x * m_x + m_z * m_z ); 00032 pMatrix[ 6] = 2.0 * (m_z * m_y + m_x * m_w ); 00033 pMatrix[ 7] = 0.0; 00034 // Third row 00035 pMatrix[ 8] = 2.0 * ( m_x * m_z + m_y * m_w ); 00036 pMatrix[ 9] = 2.0 * ( m_y * m_z - m_x * m_w ); 00037 pMatrix[10] = 1.0 - 2.0 * ( m_x * m_x + m_y * m_y ); 00038 pMatrix[11] = 0.0; 00039 // Fourth row 00040 pMatrix[12] = 0; 00041 pMatrix[13] = 0; 00042 pMatrix[14] = 0; 00043 pMatrix[15] = 1.0f; 00044 // Now pMatrix[] is a 4x4 homogeneous matrix that can be applied to an OpenGL Matrix 00045 } 00046 00047 Quaternione Quaternione::operator *(Quaternione q) 00048 { 00049 Quaternione r; 00050 r.m_w = m_w*q.m_w - m_x*q.m_x - m_y*q.m_y - m_z*q.m_z; 00051 r.m_x = m_w*q.m_x + m_x*q.m_w + m_y*q.m_z - m_z*q.m_y; 00052 r.m_y = m_w*q.m_y + m_y*q.m_w + m_z*q.m_x - m_x*q.m_z; 00053 r.m_z = m_w*q.m_z + m_z*q.m_w + m_x*q.m_y - m_y*q.m_x; 00054 00055 return(r); 00056 } 00057 Quadri::Quadri(){ 00058 } 00059 Quadri::Quadri(double *Vett,double Angle){ 00060 w = cos(Angle*.5); 00061 double NormaInv = NormInv(Vett); 00062 double Sin = sin(Angle*.5); 00063 x = Sin*Vett[0]*NormaInv; 00064 y = Sin*Vett[1]*NormaInv; 00065 z = Sin*Vett[2]*NormaInv; 00066 //printf("%lf %lf %lf %lf\n",x,y,z,w); 00067 } 00068 Quadri::Quadri(double Pitch,double Yaw,double Roll){ 00069 double cp = cos(Pitch*.5); 00070 double sp = sin(Pitch*.5); 00071 double cy = cos(Yaw*.5); 00072 double sy = sin(Yaw*.5); 00073 double cr = cos(Roll*.5); 00074 double sr = sin(Roll*.5); 00075 x = sr*cp*cy - cr*sp*sy; 00076 y = cr*sp*cy + sr*cp*sy; 00077 z = cr*cp*sy - sr*sp*cy; 00078 w = cr*cp*cy + sr*sp*sy; 00079 Normalize(); 00080 } 00081 Quadri::Quadri(double ww,double xx,double yy,double zz){ 00082 x = xx; 00083 y = yy; 00084 z = zz; 00085 w = ww; 00086 } 00087 void Quadri::RotMatrix(double *data,int dim){ 00088 //FIXME: the determinant is not zero! 00089 if(dim == 4){ 00090 int NRow = 4; 00091 data[NRow*0+0] = w*w + x*x - y*y - z*z; 00092 data[NRow*0+1] = 2.*x*y + 2.*w*z; 00093 data[NRow*0+2] = 2.*x*z - 2.*w*y; 00094 data[NRow*0+3] = 0.; 00095 00096 data[NRow*1+0] = 2.*x*y - 2.*w*z; 00097 data[NRow*1+1] = w*w - x*x + y*y - z*z; 00098 data[NRow*1+2] = 2.*y*z + 2.*w*x; 00099 data[NRow*1+3] = 0.; 00100 00101 data[NRow*2+0] = 2.*x*z + 2.*w*y; 00102 data[NRow*2+1] = 2.*y*z - 2.*w*x; 00103 data[NRow*2+2] = w*w - x*x - y*y + z*z; 00104 data[NRow*2+3] = 0.; 00105 00106 data[NRow*3+0] = 0.; 00107 data[NRow*3+1] = 0.; 00108 data[NRow*3+2] = 0.; 00109 data[NRow*3+3] = w*w + x*x + y*y + z*z; 00110 } 00111 else{ 00112 int NRow = 3; 00113 data[NRow*0+0] = 1. - 2.*SQR(y) - 2.*SQR(z); 00114 data[NRow*0+1] = 2.*x*y + 2.*w*z; 00115 data[NRow*0+2] = 2.*x*z - 2.*w*y; 00116 00117 data[NRow*1+0] = 2.*x*y - 2.*w*z; 00118 data[NRow*1+1] = 1. - 2.*SQR(x) - 2.*SQR(z); 00119 data[NRow*1+2] = 2.*y*z + 2.*w*x; 00120 00121 data[NRow*2+0] = 2.*x*z + 2.*w*y; 00122 data[NRow*2+1] = 2.*y*z - 2.*w*x; 00123 data[NRow*2+2] = 1. - 2.*SQR(x) - 2.*SQR(y); 00124 } 00125 } 00126 void Quadri::Basis(double a,double b,double c,double d,double *M){ 00127 // first row 00128 M[0] = a; 00129 M[1] = -b; 00130 M[2] = d; 00131 M[3] = c; 00132 // 00133 M[4] = b; 00134 M[5] = a; 00135 M[6] = c; 00136 M[7] = -d; 00137 // 00138 M[8] = -d; 00139 M[9] = -c; 00140 M[10]= a; 00141 M[11]= -b; 00142 // 00143 M[12] = -c; 00144 M[13] = d; 00145 M[14] = b; 00146 M[15] = a; 00147 } 00148 void Quadri::PrintMatrix(double *M){ 00149 printf("|%lf %lf %lf %lf|\n",M[0],M[4],M[8],M[12]); 00150 printf("|%lf %lf %lf %lf|\n",M[1],M[5],M[9],M[13]); 00151 printf("|%lf %lf %lf %lf|\n",M[2],M[6],M[10],M[14]); 00152 printf("|%lf %lf %lf %lf|\n",M[3],M[7],M[11],M[15]); 00153 } 00154 void Quadri::Conj(){ 00155 x = -x; 00156 y = -y; 00157 z = -z; 00158 w = w; 00159 } 00160 Quadri Quadri::GetConj(){ 00161 Quadri Resp; 00162 Resp.x = -x; 00163 Resp.y = -y; 00164 Resp.z = -z; 00165 Resp.w = w; 00166 return Resp; 00167 } 00168 double Quadri::Norm(){ 00169 double Resp = 0.; 00170 Resp = QUAD(x) + QUAD(y) + QUAD(z) + QUAD(w); 00171 return sqrt(Resp); 00172 } 00173 double Quadri::Normalize(){ 00174 double Den = 1./Norm(); 00175 x = x*Den; 00176 y = y*Den; 00177 z = z*Den; 00178 w = w*Den; 00179 return Den; 00180 } 00181 double Quadri::Normalize(double *Vett){ 00182 double Norm = 0.; 00183 for(int d=0;d<3;d++) 00184 Norm += SQR(Vett[d]); 00185 Norm = Norm > 0. ? 1./sqrt(Norm) : 1.; 00186 for(int d=0;d<3;d++) 00187 Vett[d] *= Norm; 00188 return 1./Norm; 00189 } 00190 double Quadri::NormInv(double *Vett){ 00191 double Norm = 0.; 00192 for(int d=0;d<3;d++) 00193 Norm += SQR(Vett[d]); 00194 Norm = Norm > 0. ? 1./sqrt(Norm) : 1.; 00195 return Norm; 00196 } 00197 Quadri Quadri::operator* (const Quadri &rq) const 00198 { 00199 // the constructor takes its arguments as (x, y, z, w) 00200 return Quadri(w * rq.x + x * rq.w + y * rq.z - z * rq.y, 00201 w * rq.y + y * rq.w + z * rq.x - x * rq.z, 00202 w * rq.z + z * rq.w + x * rq.y - y * rq.x, 00203 w * rq.w - x * rq.x - y * rq.y - z * rq.z); 00204 } 00205 Quadri Quadri::operator= (const Quadri &rq) const 00206 { 00207 // the constructor takes its arguments as (x, y, z, w) 00208 return Quadri(rq.w,rq.x,rq.y,rq.z); 00209 } 00210 // Multiplying a quaternion q with a vector v applies the q-rotation to v 00211 double *Quadri::operator* (const double *Vet) const 00212 { 00213 // product v' = q v q* 00214 double Resp[3]; 00215 // for(int d=0;d<3;d++) 00216 // Resp[d] = Vet[d]; 00217 // Normalize(Resp); 00218 // Quadri vecQuat, resQuat; 00219 // vecQuat.x = Resp[0]; 00220 // vecQuat.y = Resp[1]; 00221 // vecQuat.z = Resp[2]; 00222 // vecQuat.w = 0.0; 00223 00224 // resQuat = vecQuat * GetConj(); 00225 // resQuat = *this * resQuat; 00226 // Resp[0] = resQuat.x; 00227 // Resp[1] = resQuat.y; 00228 // Resp[2] = resQuat.z; 00229 00230 return Resp; 00231 } 00232 void Quadri::Prod(Quadri q){ 00233 double Uno = w*q.w - x*q.x - y*q.y - z*q.z; 00234 double Due = w*q.x + q.w*x + y*q.z - z*q.y; 00235 double Tre = w*q.y + q.w*y - x*q.z + z*q.x; 00236 double Qua = w*q.z + q.w*z + x*q.y - y*q.x; 00237 w = Uno; 00238 x = Due; 00239 y = Tre; 00240 z = Qua; 00241 } 00242 Quadri Quadri::Prod(Quadri p,Quadri q){ 00243 Quadri Resp; 00244 Resp.w = p.w*q.w - p.x*q.x - p.y*q.y - p.z*q.z; 00245 Resp.x = p.w*q.x + q.w*p.x + p.y*q.z - p.z*q.y; 00246 Resp.y = p.w*q.y + q.w*p.y - p.x*q.z + p.z*q.x; 00247 Resp.z = p.w*q.z + q.w*p.z + p.x*q.y - p.y*q.x; 00248 //return Quadri; 00249 } 00250 double Quadri::Sqr(){ 00251 return w*w + x*x + y*y * z*z; 00252 } 00253 void Quadri::Inv(){ 00254 Conj(); 00255 double Num = 1./Sqr(); 00256 w = w*Num; 00257 x = x*Num; 00258 y = y*Num; 00259 z = z*Num; 00260 } 00261 void Quadri::Matrix3x3(double *M){ 00262 // first row 00263 M[0] = 1. - 2.*x*x - 2.*z*z; 00264 M[1] = 2.*x*y + 2.*w*z; 00265 M[2] = 2.*x*z - 2.*w*y; 00266 // 00267 M[3] = 2.*x*y - 2.*w*z; 00268 M[4] = 1.-2.*x*x-2.*z*z; 00269 M[5] = 2.*x*y + 2.*w*x; 00270 // 00271 M[6] = 2.*x*z + 2.*w*y; 00272 M[7] = 2.*y*z - 2.*w*x; 00273 M[8] = 1.-2.*x*x-2.*y*y; 00274 } 00275 void Quadri::Matrix4x4(double *M){ 00276 // first row 00277 M[0] = 1. - 2.*x*x - 2.*z*z; 00278 M[1] = 2.*x*y + 2.*w*z; 00279 M[2] = 2.*x*z - 2.*w*y; 00280 M[3] = 0.; 00281 // 00282 M[4] = 2.*x*y - 2.*w*z; 00283 M[5] = 1.-2.*x*x-2.*z*z; 00284 M[6] = 2.*x*y + 2.*w*x; 00285 M[7] = 0.; 00286 // 00287 M[8] = 2.*x*z + 2.*w*y; 00288 M[9] = 2.*y*z - 2.*w*x; 00289 M[10] = 1.-2.*x*x-2.*y*y; 00290 M[11] = 0.; 00291 // 00292 M[12] = 0.; 00293 M[13] = 0.; 00294 M[14] = 0.; 00295 M[15] = 1.; 00296 } 00297 double *Quadri::Axis(){ 00298 double v[3]; 00299 double Den = Norm(); 00300 v[0] = x/Den; 00301 v[1] = y/Den; 00302 v[2] = z/Den; 00303 return v; 00304 } 00305 double Quadri::Angle(){ 00306 return 2.*acos(w); 00307 }