MAV'RIC
/home/travis/build/lis-epfl/MAVRIC_Library/util/quaternions.h
00001 /*******************************************************************************
00002  * Copyright (c) 2009-2016, MAV'RIC Development Team
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright notice,
00009  * this list of conditions and the following disclaimer.
00010  *
00011  * 2. Redistributions in binary form must reproduce the above copyright notice,
00012  * this list of conditions and the following disclaimer in the documentation
00013  * and/or other materials provided with the distribution.
00014  *
00015  * 3. Neither the name of the copyright holder nor the names of its contributors
00016  * may be used to endorse or promote products derived from this software without
00017  * specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00023  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00024  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00025  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00026  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00027  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00028  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00029  * POSSIBILITY OF SUCH DAMAGE.
00030  ******************************************************************************/
00031 
00032 /*******************************************************************************
00033  * \file quaternions.h
00034  *
00035  * \author MAV'RIC Team
00036  * \author Felix Schill
00037  * \author Geraud L'Eplattenier
00038  *
00039  * \brief Useful functions for quaternions
00040  *
00041  ******************************************************************************/
00042 
00043 
00044 #ifndef QUATERNIONS_H_
00045 #define QUATERNIONS_H_
00046 
00047 #include <stdint.h>
00048 #include "util/maths.h"
00049 #include "util/vectors.h"
00050 
00051 
00057 typedef struct
00058 {
00059     float s;            
00060     float v[3];         
00061 } quat_t;
00062 
00063 
00069 static inline quat_t quaternions_create(float s, float vx, float vy, float vz)
00070 {
00071     quat_t quat;
00072     quat.s    = s;
00073     quat.v[0] = vx;
00074     quat.v[1] = vy;
00075     quat.v[2] = vz;
00076 
00077     return quat;
00078 }
00079 
00087 #define QI(q, out) \
00088     out.s = q.s;\
00089     out.v[0] = -q.v[0];\
00090     out.v[1] = -q.v[1];\
00091     out.v[2] = -q.v[2];
00092 
00093 
00103 #define QUAT(q, s, v0, v1, v2) \
00104     q.s = s;\
00105     q.v[0] = v0;\
00106     q.v[1] = v1;\
00107     q.v[2] = v2;
00108 
00109 
00117 quat_t static inline quaternions_create_from_vector(float v[3])
00118 {
00119     quat_t q;
00120     q.s = 0;
00121     q.v[0] = v[0];
00122     q.v[1] = v[1];
00123     q.v[2] = v[2];
00124     return q;
00125 }
00126 
00127 
00135 #define QMUL(q1,q2,out) \
00136     tmp[0] = q1.v[1] * q2.v[2] - q1.v[2] * q2.v[1];\
00137     tmp[1] = q1.v[2] * q2.v[0] - q1.v[0] * q2.v[2];\
00138     tmp[2] = q1.v[0] * q2.v[1] - q1.v[1] * q2.v[0];\
00139     out.v[0] = q2.s* q1.v[0] + q1.s * q2.v[0] + tmp[0];\
00140     out.v[1] = q2.s* q1.v[1] + q1.s * q2.v[1] + tmp[1];\
00141     out.v[2] = q2.s* q1.v[2] + q1.s * q2.v[2] + tmp[2];\
00142     out.s= q1.s * q2.s - SCP(q1.v, q2.v);
00143 
00144 
00153 quat_t static inline quaternions_multiply(const quat_t q1, const quat_t q2)
00154 {
00155     float tmp[3];
00156     quat_t out;
00157 
00158     tmp[0] = q1.v[1] * q2.v[2] - q1.v[2] * q2.v[1];
00159     tmp[1] = q1.v[2] * q2.v[0] - q1.v[0] * q2.v[2];
00160     tmp[2] = q1.v[0] * q2.v[1] - q1.v[1] * q2.v[0];
00161 
00162     out.v[0] = q2.s * q1.v[0] + q1.s * q2.v[0] + tmp[0];
00163     out.v[1] = q2.s * q1.v[1] + q1.s * q2.v[1] + tmp[1];
00164     out.v[2] = q2.s * q1.v[2] + q1.s * q2.v[2] + tmp[2];
00165     out.s = q1.s * q2.s - vectors_scalar_product(q1.v, q2.v);
00166 
00167     return out;
00168 }
00169 
00170 
00177 quat_t static inline quaternions_inverse(const quat_t q)
00178 {
00179     quat_t qinv;
00180     qinv.s = q.s;
00181 
00182     for (int32_t  i = 0; i < 3; i++)
00183     {
00184         qinv.v[i] = -q.v[i];
00185     }
00186 
00187     return qinv;
00188 }
00189 
00190 
00199 quat_t static inline quaternions_rotate(const quat_t qi, const quat_t qrot)
00200 {
00201     quat_t qinv, qtmp;
00202 
00203     qinv = quaternions_inverse(qrot);
00204     qtmp = quaternions_multiply(qinv, qi);
00205     qtmp = quaternions_multiply(qtmp, qrot);
00206 
00207     return qtmp;
00208 }
00209 
00210 
00221 quat_t static inline quaternions_global_to_local(const quat_t qe, const quat_t qvect)
00222 {
00223     quat_t qinv, qtmp;
00224 
00225     qinv = quaternions_inverse(qe);
00226     qtmp = quaternions_multiply(qinv, qvect);
00227     qtmp = quaternions_multiply(qtmp, qe);
00228 
00229     return qtmp;
00230 }
00231 
00232 
00243 quat_t static inline quaternions_local_to_global(const quat_t qe, const quat_t qvect)
00244 {
00245     quat_t qinv, qtmp;
00246 
00247     qinv = quaternions_inverse(qe);
00248     qtmp = quaternions_multiply(qe, qvect);
00249     qtmp = quaternions_multiply(qtmp, qinv);
00250 
00251     return qtmp;
00252 }
00253 
00254 
00266 void static inline quaternions_rotate_vector(const quat_t q, const float u[3], float v[3])
00267 {
00268     float tmp1[3], tmp2[3];
00269 
00270     vectors_cross_product(q.v, u, tmp1);
00271     tmp1[0] = 2 * tmp1[0];
00272     tmp1[1] = 2 * tmp1[1];
00273     tmp1[2] = 2 * tmp1[2];
00274 
00275     vectors_cross_product(q.v, tmp1, tmp2);
00276 
00277     v[0] = u[0] + q.s * tmp1[0] + tmp2[0];
00278     v[1] = u[1] + q.s * tmp1[1] + tmp2[1];
00279     v[2] = u[2] + q.s * tmp1[2] + tmp2[2];
00280 }
00281 
00282 
00289 static inline quat_t quaternions_normalise(const quat_t q)
00290 {
00291     quat_t result;
00292 
00293     float snorm = SQR(q.s) + SQR(q.v[0]) + SQR(q.v[1]) + SQR(q.v[2]);
00294 
00295     if (snorm > 0.0000001f)
00296     {
00297         float norm = maths_fast_sqrt(snorm);
00298         result.s = q.s / norm;
00299         result.v[0] = q.v[0] / norm;
00300         result.v[1] = q.v[1] / norm;
00301         result.v[2] = q.v[2] / norm;
00302     }
00303     else
00304     {
00305         result.s = 1.0f;
00306         result.v[0] = 0.0f;
00307         result.v[1] = 0.0f;
00308         result.v[2] = 0.0f;
00309     }
00310 
00311     return result;
00312 }
00313 
00314 
00315 #endif /* QUATERNIONS_H_ */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines