deQuaternionf.h

Go to the documentation of this file.
00001 /* Copyright (c) 2005 Arachi, Inc. and Stanford University.
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining
00004  * a copy of this software and associated documentation files (the
00005  * "Software"), to deal in the Software without restriction, including
00006  * without limitation the rights to use, copy, modify, merge, publish,
00007  * distribute, sublicense, and/or sell copies of the Software, and to
00008  * permit persons to whom the Software is furnished to do so, subject
00009  * to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00018  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00019  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00020  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #ifndef _deQuaternionf_h
00024 #define _deQuaternionf_h
00025 
00026 #ifdef __cplusplus
00027 extern "C" {
00028 #endif
00029 
00030 /* 
00031  * q = [w,v] = [cos(theta/2);, axis*sin(theta/2);] <--- axisAngle(axis,theta);
00032  * q = [vx,vy,vz,w] --> float[4];
00033  */
00034 
00035 extern void deColumnV3Q4S1(deFloat* res, const deFloat* q1, const int col);
00036 extern void deConsistentSignQ4Q4Q4(deFloat* res, const deFloat* q1, const deFloat* q2);
00037 extern void deSlerpQ4Q4Q4S2(deFloat* res, const deFloat* q1, const deFloat* q2, const deFloat t, const deFloat addedSpins);
00038 extern void deAxisAngleV3S1Q4(deFloat* axis, deFloat *angle, const deFloat* q1);
00039 extern void deSetQ4zyxV3(deFloat* res, const deFloat *v);
00040 
00041 /* inlines */
00042 
00043 DE_MATH_API void deSetQ4S4(deFloat* res, const deFloat x, const deFloat y, const deFloat z, const deFloat w)
00044 {
00045     res[0] = x; res[1] = y;     res[2] = z;     res[3] = w;
00046 }
00047 
00048 DE_MATH_API void deIdentityQ4(deFloat* res)
00049 {
00050         res[0] = res[1] = res[2] = 0;   res[3] = 1;
00051 }
00052 
00053 DE_MATH_API void deZeroQ4(deFloat* res)
00054 {
00055         res[0] = res[1] = res[2] = res[3] = 0;
00056 }
00057 
00058 DE_MATH_API void deNegateQ4Q4(deFloat* res, const deFloat* q1)
00059 {
00060         res[0] = -q1[0];
00061         res[1] = -q1[1];
00062         res[2] = -q1[2];
00063         res[3] = -q1[3];
00064 }
00065 
00066 DE_MATH_API void deInvertQ4Q4(deFloat* res, const deFloat* q1)
00067 {
00068         res[0] = -q1[0];
00069         res[1] = -q1[1];
00070         res[2] = -q1[2];
00071         res[3] =  q1[3];
00072 }
00073 
00074 DE_MATH_API void deSetQ4Q4(deFloat* res, const deFloat* q1)
00075 {
00076         res[0] = q1[0];
00077         res[1] = q1[1];
00078         res[2] = q1[2];
00079         res[3] = q1[3];
00080 }
00081 
00082 DE_MATH_API void deAddQ4Q4Q4(deFloat* res, const deFloat* q1, const deFloat* q2)
00083 {
00084         res[0] = q1[0] + q2[0];
00085         res[1] = q1[1] + q2[1];
00086         res[2] = q1[2] + q2[2];
00087         res[3] = q1[3] + q2[3];
00088 }
00089 
00090 DE_MATH_API void deSubQ4Q4Q4(deFloat* res, const deFloat* q1, const deFloat* q2)
00091 {
00092         res[0] = q1[0] - q2[0];
00093         res[1] = q1[1] - q2[1];
00094         res[2] = q1[2] - q2[2];
00095         res[3] = q1[3] - q2[3];
00096 }
00097 
00098 DE_MATH_API deFloat deDotQ4Q4(const deFloat* q1, const deFloat* q2)
00099 {
00100         return (q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3]);
00101 }
00102 
00103 /* res = (w1*w2 - v1.v2, v1*w2 + v2*w1 + v1xv2) */
00104 DE_MATH_API void deMulQ4Q4Q4(deFloat* res, const deFloat* q1, const deFloat* q2)
00105 {
00106         res[0] = q1[0] * q2[3] + q2[0] * q1[3] + (q1[1] * q2[2] - q1[2] * q2[1]);
00107         res[1] = q1[1] * q2[3] + q2[1] * q1[3] + (q1[2] * q2[0] - q1[0] * q2[2]);
00108         res[2] = q1[2] * q2[3] + q2[2] * q1[3] + (q1[0] * q2[1] - q1[1] * q2[0]);
00109         res[3] = q1[3] * q2[3] - (q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2]);
00110 }
00111 
00112 DE_MATH_API void deMulQ4Q4iQ4(deFloat* res, const deFloat* q1, const deFloat* q2)
00113 {
00114         /* w_ = w_, v_ = - v_ */
00115         res[0] = -q1[0] * q2[3] + q2[0] * q1[3] - (q1[1] * q2[2] - q1[2] * q2[1]);
00116         res[1] = -q1[1] * q2[3] + q2[1] * q1[3] - (q1[2] * q2[0] - q1[0] * q2[2]);
00117         res[2] = -q1[2] * q2[3] + q2[2] * q1[3] - (q1[0] * q2[1] - q1[1] * q2[0]);
00118         res[3] =  q1[3] * q2[3] + (q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2]);
00119 }
00120 
00121 DE_MATH_API void deMulQ4Q4Q4i(deFloat* res, const deFloat* q1, const deFloat* q2)
00122 {
00123         /* w_ = w_, v_ = - v_ */
00124         res[0] = q1[0] * q2[3] - q2[0] * q1[3] - (q1[1] * q2[2] - q1[2] * q2[1]);
00125         res[1] = q1[1] * q2[3] - q2[1] * q1[3] - (q1[2] * q2[0] - q1[0] * q2[2]);
00126         res[2] = q1[2] * q2[3] - q2[2] * q1[3] - (q1[0] * q2[1] - q1[1] * q2[0]);
00127         res[3] = q1[3] * q2[3] + (q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2]);
00128 }
00129 
00130 DE_MATH_API void deMulQ4S1(deFloat* res, const deFloat s)
00131 {
00132         res[0] *= s;
00133         res[1] *= s;
00134         res[2] *= s;
00135         res[3] *= s;
00136 }
00137 
00138 DE_MATH_API void deAddQ4Q4(deFloat* res, const deFloat* q1)
00139 {
00140         res[0] += q1[0];
00141         res[1] += q1[1];
00142         res[2] += q1[2];
00143         res[3] += q1[3];
00144 }
00145 
00146 DE_MATH_API void deSubQ4Q4(deFloat* res, const deFloat* q1)
00147 {
00148         res[0] -= q1[0];
00149         res[1] -= q1[1];
00150         res[2] -= q1[2];
00151         res[3] -= q1[3];
00152 }
00153 
00154 /*
00155  * [w,v'] = q * [0,v] * ~q  <==> v' = R v
00156  * = [w1,v1]*[0,v2]*[w1,-v1] = [ -v1.v2, w1v2+ v1 x v2]*[w1,-v1]
00157  * = [(-v1.v2)(w1)+(w1v2+ v1 x v2).v1,
00158  *    (v1.v2)v1 + w1(w1v2+ v1 x v2) + v1 x (w1v2+ v1 x v2)]
00159  * since A x (B + C) = A x B + A x C
00160  * = [w, (w1*w1)v2 + 2*w1(v1 x v2) + (v1.v2)v1 + v1 x (v1 x v2)]
00161  * since A x (B x C) = (A dot C)B - (A dot B)C
00162  * = [w, (w1*w1)v2 + 2*w1(v1 x v2) + (v1.v2)v1 + (v1.v2)v1 - (v1.v1)v2]
00163  * = [w, (w1*w1 - v1.v1)v2 + 2*w1(v1 x v2) + 2*(v1.v2)v1]
00164  * v' = [(w1*w1 - v1.v1)v2 + 2*w1(v1 x v2) + 2*(v1.v2)v1]
00165  */
00166 DE_MATH_API void deMulV3Q4V3(deFloat* res, const deFloat* q1, const deFloat* v2)
00167 {
00168         deFloat m11 = q1[3] * q1[3] - (q1[0] * q1[0] + q1[1] * q1[1] + q1[2] * q1[2]);
00169         deFloat m12 = 2 * (q1[0] * v2[0] + q1[1] * v2[1] + q1[2] * v2[2]);
00170         deFloat w2 = q1[3] + q1[3];
00171 
00172         res[0] = q1[0] * m12 + v2[0] * m11 + (q1[1] * v2[2] - q1[2] * v2[1]) * w2;
00173         res[1] = q1[1] * m12 + v2[1] * m11 + (q1[2] * v2[0] - q1[0] * v2[2]) * w2;
00174         res[2] = q1[2] * m12 + v2[2] * m11 + (q1[0] * v2[1] - q1[1] * v2[0]) * w2;
00175 }
00176 
00177 /* [w,v'] = ~q * [0,v] * q  <==> v' = R v
00178  * = [w1,-v1]*[0,v2]*[w1,v1] = [ v1.v2, w1v2 - v1 x v2]*[w1,v1]
00179  * v' = [(w1*w1 - v1.v1)v2 - 2*w1(v1 x v2) + 2*(v1.v2)v1]
00180  */
00181 DE_MATH_API void deMulV3Q4iV3(deFloat* res, const deFloat* q1, const deFloat* v2)
00182 {
00183   // w_ = w_, v_ = - v_
00184         deFloat m11 = q1[3] * q1[3] - (q1[0] * q1[0] + q1[1] * q1[1] + q1[2] * q1[2]);
00185         deFloat m12 = 2 * (q1[0] * v2[0] + q1[1] * v2[1] + q1[2] * v2[2]);
00186         deFloat w2 = -(q1[3] + q1[3]);
00187 
00188         res[0] = q1[0] * m12 + v2[0] * m11 + (q1[1] * v2[2] - q1[2] * v2[1]) * w2;
00189         res[1] = q1[1] * m12 + v2[1] * m11 + (q1[2] * v2[0] - q1[0] * v2[2]) * w2;
00190         res[2] = q1[2] * m12 + v2[2] * m11 + (q1[0] * v2[1] - q1[1] * v2[0]) * w2;
00191 }
00192 
00193 DE_MATH_API int deIsEqualQ4Q4(const deFloat* q1, const deFloat* q2)
00194 {
00195         deFloat mag2 = q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3];
00196     return (mag2 > DE_QUATERNION_COS_THRESHHOLD || mag2 < -DE_QUATERNION_COS_THRESHHOLD);
00197 }
00198 
00199 /* [w1,v1]*[w2,v2] = [(w1*w2 - v1 dot v2), (w1*v2+w2*v1+ v1 cross v2)] */
00200 DE_MATH_API void deNormalizeQ4(deFloat* res)
00201 {
00202         deFloat mag = 1 / deSqrt(res[0] * res[0] + res[1] * res[1] + res[2] * res[2] + res[3] * res[3]);
00203     res[0] *= mag;
00204     res[1] *= mag;
00205     res[2] *= mag;
00206     res[3] *= mag;
00207 }
00208 
00209 /* axis angle */
00210 DE_MATH_API void deSetQ4V3S1(deFloat* res, const deFloat* axis, const deFloat angle)
00211 {
00212         deFloat s = deSin(0.5 * angle);
00213         res[0] = axis[0] * s;
00214         res[1] = axis[1] * s;
00215         res[2] = axis[2] * s;
00216         res[3] = deCos(0.5 * angle);
00217 }
00218 
00219 /* axis angle */
00220 DE_MATH_API void deSetQ4S2(deFloat* res, const int axis, const deFloat angle)
00221 {
00222         /* also, see Intro. to Robotics by J. Craig: p. 51 */
00223         res[0] = res[1] = res[2] = 0;
00224         res[axis] = deSin(0.5 * angle);
00225         res[3] = deCos(0.5 * angle);
00226 }       
00227 
00228 /*
00229  * dPhi = Einv ( q - qd) = -2*q_tilde^T qd <-- since (q_tilde^T q) = 0
00230  * E = 0.5*q_tilde
00231  * Einv = (EtE)inv Et = 4Et = 2*qtilde^T <-- since (q_tilde^T q_tilde) = I
00232  *
00233  * q = [w x y z]
00234  * Khatib
00235  * q_tilde = [ -x -y -z
00236  *              w  z -y
00237  *             -z  w  x
00238  *               y -x  w ] 
00239  * q_tilde^T = [ -x  w -z  y
00240  *               -y  z  w -x
00241  *               -z -y  x  w ]         
00242  */
00243 DE_MATH_API void deAngularErrorV3Q4Q4(deFloat* res, const deFloat* q1, const deFloat* q2)
00244 {
00245   res[0] = -2 * ( q1[3] * q2[0] - q1[2] * q2[1] + q1[1] * q2[2] - q1[0] * q2[3]);
00246   res[1] = -2 * ( q1[2] * q2[0] + q1[3] * q2[1] - q1[0] * q2[2] - q1[1] * q2[3]);
00247   res[2] = -2 * (-q1[1] * q2[0] + q1[0] * q2[1] + q1[3] * q2[2] - q1[2] * q2[3]);
00248 }
00249 
00250 /* 
00251  * dq = E v2
00252  * dq = 0.5 q_tilde v2
00253  */
00254 DE_MATH_API void deVelocityQ4Q4V3(deFloat* res, const deFloat* q1, const deFloat* v2)
00255 {
00256   res[0] = (deFloat)0.5 * ( q1[3] * v2[0] + q1[2] * v2[1] - q1[1] * v2[2]);
00257   res[1] = (deFloat)0.5 * (-q1[2] * v2[0] + q1[3] * v2[1] + q1[0] * v2[2]);
00258   res[2] = (deFloat)0.5 * ( q1[1] * v2[0] - q1[0] * v2[1] + q1[3] * v2[2]);
00259   res[3] = (deFloat)0.5 * (-q1[0] * v2[0] - q1[1] * v2[1] - q1[2] * v2[2]);
00260 }
00261 
00262 /* 
00263  * res = q1 + t * (q2 - q1)
00264  */
00265 DE_MATH_API void deLerpQ4Q4Q4S1(deFloat* res, const deFloat* q1, const deFloat* q2, const deFloat t)
00266 {
00267   res[0] = q1[0] + t * (q2[0] - q1[0]);
00268   res[1] = q1[1] + t * (q2[1] - q1[1]);
00269   res[2] = q1[2] + t * (q2[2] - q1[2]);
00270   res[3] = q1[3] + t * (q2[3] - q1[3]);
00271 }
00272 
00273 /* 
00274  * res = [x, y, z] = Z-Y-X Euler angles
00275  */
00276 DE_MATH_API     void deSetV3Q4zyx(deFloat* res, const deFloat* q)
00277 {
00278     deFloat sqx = q[0] * q[0];
00279     deFloat sqy = q[1] * q[1];
00280     deFloat sqz = q[2] * q[2];
00281     deFloat sqw = q[3] * q[3];
00282 
00283         res[0] = deAtan2(2 * (q[1] * q[2] + q[0] * q[3]), (-sqx - sqy + sqz + sqw));
00284         res[1] = deAsin(-2 * (q[0] * q[2] - q[1] * q[3]));
00285         res[2] = deAtan2(2 * (q[0] * q[1] + q[2] * q[3]), (sqx - sqy - sqz + sqw));
00286 }
00287 
00288 #ifdef __cplusplus
00289 }
00290 #endif
00291 
00292 #endif /* _deQuaternion_h */

Generated on Sun Apr 9 22:12:42 2006 for TAO by  doxygen 1.4.6-NO