Home | History | Annotate | Download | only in xcore
      1 /*
      2  * vec_mat.h - vector and matrix defination & calculation
      3  *
      4  *  Copyright (c) 2017 Intel Corporation
      5  *
      6  * Licensed under the Apache License, Version 2.0 (the "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  *
     18  * Author: Zong Wei <wei.zong (at) intel.com>
     19  */
     20 
     21 #ifndef XCAM_VECTOR_MATRIX_H
     22 #define XCAM_VECTOR_MATRIX_H
     23 
     24 #include <xcam_std.h>
     25 #include <cmath>
     26 
     27 
     28 namespace XCam {
     29 
     30 #ifndef PI
     31 #define PI 3.14159265358979323846
     32 #endif
     33 
     34 #ifndef FLT_EPSILON
     35 #define FLT_EPSILON 1.19209290e-07F // float
     36 #endif
     37 
     38 #ifndef DBL_EPSILON
     39 #define DBL_EPSILON 2.2204460492503131e-16 // double
     40 #endif
     41 
     42 #ifndef DEGREE_2_RADIANS
     43 #define DEGREE_2_RADIANS(x) (((x) * PI) / 180.0)
     44 #endif
     45 
     46 #ifndef RADIANS_2_DEGREE
     47 #define RADIANS_2_DEGREE(x) (((x) * 180.0) / PI)
     48 #endif
     49 
     50 #define XCAM_VECT2_OPERATOR_VECT2(op)                       \
     51     Vector2<T> operator op (const Vector2<T>& b) const {    \
     52         return Vector2<T>(x op b.x, y op b.y);              \
     53     }                                                       \
     54     Vector2<T> &operator op##= (const Vector2<T>& b) {      \
     55         x op##= b.x;  y op##= b.y; return *this;            \
     56     }
     57 
     58 #define XCAM_VECT2_OPERATOR_SCALER(op)                      \
     59     Vector2<T> operator op (const T& b) const {             \
     60         return Vector2<T>(x op b, y op b);                  \
     61     }                                                       \
     62     Vector2<T> &operator op##= (const T& b) {               \
     63         x op##= b;  y op##= b; return *this;                \
     64     }
     65 
     66 template<class T>
     67 class Vector2
     68 {
     69 public:
     70 
     71     T x;
     72     T y;
     73 
     74     Vector2 () : x(0), y(0) {};
     75     Vector2 (T _x, T _y) : x(_x), y(_y) {};
     76 
     77     template <typename New>
     78     Vector2<New> convert_to () const {
     79         Vector2<New> ret((New)(this->x), (New)(this->y));
     80         return ret;
     81     }
     82 
     83     Vector2<T>& operator = (const Vector2<T>& rhs)
     84     {
     85         x = rhs.x;
     86         y = rhs.y;
     87         return *this;
     88     }
     89 
     90     template <typename Other>
     91     Vector2<T>& operator = (const Vector2<Other>& rhs)
     92     {
     93         x = rhs.x;
     94         y = rhs.y;
     95         return *this;
     96     }
     97 
     98     Vector2<T> operator - () const {
     99         return Vector2<T>(-x, -y);
    100     }
    101 
    102     XCAM_VECT2_OPERATOR_VECT2 (+)
    103     XCAM_VECT2_OPERATOR_VECT2 (-)
    104     XCAM_VECT2_OPERATOR_VECT2 (*)
    105     XCAM_VECT2_OPERATOR_VECT2 ( / )
    106     XCAM_VECT2_OPERATOR_SCALER (+)
    107     XCAM_VECT2_OPERATOR_SCALER (-)
    108     XCAM_VECT2_OPERATOR_SCALER (*)
    109     XCAM_VECT2_OPERATOR_SCALER ( / )
    110 
    111     bool operator == (const Vector2<T>& rhs) const {
    112         return (x == rhs.x) && (y == rhs.y);
    113     }
    114 
    115     void reset () {
    116         this->x = (T) 0;
    117         this->y = (T) 0;
    118     }
    119 
    120     void set (T _x, T _y) {
    121         this->x = _x;
    122         this->y = _y;
    123     }
    124 
    125     T magnitude () const {
    126         return (T) sqrtf(x * x + y * y);
    127     }
    128 
    129     float distance (const Vector2<T>& vec) const {
    130         return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y));
    131     }
    132 
    133     T dot (const Vector2<T>& vec) const {
    134         return (x * vec.x + y * vec.y);
    135     }
    136 
    137     inline Vector2<T> lerp (T weight, const Vector2<T>& vec) const {
    138         return (*this) + (vec - (*this)) * weight;
    139     }
    140 
    141 };
    142 
    143 template<class T, uint32_t N>
    144 class VectorN
    145 {
    146 public:
    147 
    148     VectorN ();
    149     VectorN (T x);
    150     VectorN (T x, T y);
    151     VectorN (T x, T y, T z);
    152     VectorN (T x, T y, T z, T w);
    153     VectorN (VectorN<T, 3> vec3, T w);
    154 
    155     inline VectorN<T, N>& operator = (const VectorN<T, N>& rhs);
    156     inline VectorN<T, N> operator - () const;
    157     inline bool operator == (const VectorN<T, N>& rhs) const;
    158 
    159     inline T& operator [] (uint32_t index) {
    160         XCAM_ASSERT(index >= 0 && index < N);
    161         return data[index];
    162     }
    163     inline const T& operator [] (uint32_t index) const {
    164         XCAM_ASSERT(index >= 0 && index < N);
    165         return data[index];
    166     }
    167 
    168     inline VectorN<T, N> operator + (const T rhs) const;
    169     inline VectorN<T, N> operator - (const T rhs) const;
    170     inline VectorN<T, N> operator * (const T rhs) const;
    171     inline VectorN<T, N> operator / (const T rhs) const;
    172     inline VectorN<T, N> operator += (const T rhs);
    173     inline VectorN<T, N> operator -= (const T rhs);
    174     inline VectorN<T, N> operator *= (const T rhs);
    175     inline VectorN<T, N> operator /= (const T rhs);
    176 
    177     inline VectorN<T, N> operator + (const VectorN<T, N>& rhs) const;
    178     inline VectorN<T, N> operator - (const VectorN<T, N>& rhs) const;
    179     inline VectorN<T, N> operator * (const VectorN<T, N>& rhs) const;
    180     inline VectorN<T, N> operator / (const VectorN<T, N>& rhs) const;
    181     inline VectorN<T, N> operator += (const VectorN<T, N>& rhs);
    182     inline VectorN<T, N> operator -= (const VectorN<T, N>& rhs);
    183     inline VectorN<T, N> operator *= (const VectorN<T, N>& rhs);
    184     inline VectorN<T, N> operator /= (const VectorN<T, N>& rhs);
    185 
    186     template <typename NEW> inline
    187     VectorN<NEW, N> convert_to () const;
    188 
    189     inline void zeros ();
    190     inline void set (T x, T y);
    191     inline void set (T x, T y, T z);
    192     inline void set (T x, T y, T z, T w);
    193     inline T magnitude () const;
    194     inline float distance (const VectorN<T, N>& vec) const;
    195     inline T dot (const VectorN<T, N>& vec) const;
    196     inline VectorN<T, N> lerp (T weight, const VectorN<T, N>& vec) const;
    197 
    198 private:
    199     T data[N];
    200 
    201 };
    202 
    203 
    204 template<class T, uint32_t N> inline
    205 VectorN<T, N>::VectorN ()
    206 {
    207     for (uint32_t i = 0; i < N; i++) {
    208         data[i] = 0;
    209     }
    210 }
    211 
    212 template<class T, uint32_t N> inline
    213 VectorN<T, N>::VectorN (T x) {
    214     data[0] = x;
    215 }
    216 
    217 template<class T, uint32_t N> inline
    218 VectorN<T, N>::VectorN (T x, T y) {
    219     if (N >= 2) {
    220         data[0] = x;
    221         data[1] = y;
    222     }
    223 }
    224 
    225 template<class T, uint32_t N> inline
    226 VectorN<T, N>::VectorN (T x, T y, T z) {
    227     if (N >= 3) {
    228         data[0] = x;
    229         data[1] = y;
    230         data[2] = z;
    231     }
    232 }
    233 
    234 template<class T, uint32_t N> inline
    235 VectorN<T, N>::VectorN (T x, T y, T z, T w) {
    236     if (N >= 4) {
    237         data[0] = x;
    238         data[1] = y;
    239         data[2] = z;
    240         data[3] = w;
    241     }
    242 }
    243 
    244 template<class T, uint32_t N> inline
    245 VectorN<T, N>::VectorN (VectorN<T, 3> vec3, T w) {
    246     if (N >= 4) {
    247         data[0] = vec3.data[0];
    248         data[1] = vec3.data[1];
    249         data[2] = vec3.data[2];
    250         data[3] = w;
    251     }
    252 }
    253 
    254 template<class T, uint32_t N> inline
    255 VectorN<T, N>& VectorN<T, N>::operator = (const VectorN<T, N>& rhs) {
    256     for (uint32_t i = 0; i < N; i++) {
    257         data[i] = rhs.data[i];
    258     }
    259 
    260     return *this;
    261 }
    262 
    263 template<class T, uint32_t N> inline
    264 VectorN<T, N> VectorN<T, N>::operator - () const {
    265     for (uint32_t i = 0; i < N; i++) {
    266         data[i] = -data[i];
    267     }
    268 
    269     return *this;
    270 }
    271 
    272 template<class T, uint32_t N> inline
    273 VectorN<T, N> VectorN<T, N>::operator + (const T rhs) const {
    274     VectorN<T, N> result;
    275 
    276     for (uint32_t i = 0; i < N; i++) {
    277         result.data[i] = data[i] + rhs;
    278     }
    279     return result;
    280 }
    281 
    282 template<class T, uint32_t N> inline
    283 VectorN<T, N> VectorN<T, N>::operator - (const T rhs) const {
    284     VectorN<T, N> result;
    285 
    286     for (uint32_t i = 0; i < N; i++) {
    287         result.data[i] = data[i] - rhs;
    288     }
    289     return result;
    290 }
    291 
    292 template<class T, uint32_t N> inline
    293 VectorN<T, N> VectorN<T, N>::operator * (const T rhs) const {
    294     VectorN<T, N> result;
    295 
    296     for (uint32_t i = 0; i < N; i++) {
    297         result.data[i] = data[i] * rhs;
    298     }
    299     return result;
    300 }
    301 
    302 template<class T, uint32_t N> inline
    303 VectorN<T, N> VectorN<T, N>::operator / (const T rhs) const {
    304     VectorN<T, N> result;
    305 
    306     for (uint32_t i = 0; i < N; i++) {
    307         result.data[i] = data[i] / rhs;
    308     }
    309     return result;
    310 }
    311 
    312 template<class T, uint32_t N> inline
    313 VectorN<T, N> VectorN<T, N>::operator += (const T rhs) {
    314     for (uint32_t i = 0; i < N; i++) {
    315         data[i] += rhs;
    316     }
    317     return *this;
    318 }
    319 
    320 template<class T, uint32_t N> inline
    321 VectorN<T, N> VectorN<T, N>::operator -= (const T rhs) {
    322     for (uint32_t i = 0; i < N; i++) {
    323         data[i] -= rhs;
    324     }
    325     return *this;
    326 }
    327 
    328 template<class T, uint32_t N> inline
    329 VectorN<T, N> VectorN<T, N>::operator *= (const T rhs) {
    330     for (uint32_t i = 0; i < N; i++) {
    331         data[i] *= rhs;
    332     }
    333     return *this;
    334 }
    335 
    336 template<class T, uint32_t N> inline
    337 VectorN<T, N> VectorN<T, N>::operator /= (const T rhs) {
    338     for (uint32_t i = 0; i < N; i++) {
    339         data[i] /= rhs;
    340     }
    341     return *this;
    342 }
    343 
    344 template<class T, uint32_t N> inline
    345 VectorN<T, N> VectorN<T, N>::operator + (const VectorN<T, N>& rhs) const {
    346     VectorN<T, N> result;
    347 
    348     for (uint32_t i = 0; i < N; i++) {
    349         result.data[i] = data[i] + rhs.data[i];
    350     }
    351     return result;
    352 }
    353 
    354 template<class T, uint32_t N> inline
    355 VectorN<T, N> VectorN<T, N>::operator - (const VectorN<T, N>& rhs) const {
    356     VectorN<T, N> result;
    357 
    358     for (uint32_t i = 0; i < N; i++) {
    359         result.data[i] = data[i] - rhs.data[i];
    360     }
    361     return result;
    362 }
    363 
    364 template<class T, uint32_t N> inline
    365 VectorN<T, N> VectorN<T, N>::operator * (const VectorN<T, N>& rhs) const {
    366     VectorN<T, N> result;
    367 
    368     for (uint32_t i = 0; i < N; i++) {
    369         result.data[i] = data[i] * rhs.data[i];
    370     }
    371     return result;
    372 }
    373 
    374 template<class T, uint32_t N> inline
    375 VectorN<T, N> VectorN<T, N>::operator / (const VectorN<T, N>& rhs) const {
    376     VectorN<T, N> result;
    377 
    378     for (uint32_t i = 0; i < N; i++) {
    379         result.data[i] = data[i] / rhs.data[i];
    380     }
    381     return result;
    382 }
    383 
    384 template<class T, uint32_t N> inline
    385 VectorN<T, N> VectorN<T, N>::operator += (const VectorN<T, N>& rhs) {
    386 
    387     for (uint32_t i = 0; i < N; i++) {
    388         data[i] += rhs.data[i];
    389     }
    390     return *this;
    391 }
    392 
    393 template<class T, uint32_t N> inline
    394 VectorN<T, N> VectorN<T, N>::operator -= (const VectorN<T, N>& rhs) {
    395 
    396     for (uint32_t i = 0; i < N; i++) {
    397         data[i] -= rhs.data[i];
    398     }
    399     return *this;
    400 }
    401 
    402 template<class T, uint32_t N> inline
    403 VectorN<T, N> VectorN<T, N>::operator *= (const VectorN<T, N>& rhs) {
    404 
    405     for (uint32_t i = 0; i < N; i++) {
    406         data[i] *= rhs.data[i];
    407     }
    408     return *this;
    409 }
    410 
    411 template<class T, uint32_t N> inline
    412 VectorN<T, N> VectorN<T, N>::operator /= (const VectorN<T, N>& rhs) {
    413 
    414     for (uint32_t i = 0; i < N; i++) {
    415         data[i] /= rhs.data[i];
    416     }
    417     return *this;
    418 }
    419 
    420 template<class T, uint32_t N> inline
    421 bool VectorN<T, N>::operator == (const VectorN<T, N>& rhs) const {
    422     for (uint32_t i = 0; i < N; i++) {
    423         if (data[i] != rhs[i]) {
    424             return false;
    425         }
    426     }
    427     return true;
    428 }
    429 
    430 template <class T, uint32_t N>
    431 template <typename NEW>
    432 VectorN<NEW, N> VectorN<T, N>::convert_to () const {
    433     VectorN<NEW, N> result;
    434 
    435     for (uint32_t i = 0; i < N; i++) {
    436         result[i] = (NEW)(this->data[i]);
    437     }
    438     return result;
    439 }
    440 
    441 template <class T, uint32_t N> inline
    442 void VectorN<T, N>::zeros () {
    443     for (uint32_t i = 0; i < N; i++) {
    444         data[i] = (T)(0);
    445     }
    446 }
    447 
    448 template<class T, uint32_t N> inline
    449 void VectorN<T, N>::set (T x, T y) {
    450     if (N >= 2) {
    451         data[0] = x;
    452         data[1] = y;
    453     }
    454 }
    455 
    456 template<class T, uint32_t N> inline
    457 void VectorN<T, N>::set (T x, T y, T z) {
    458     if (N >= 3) {
    459         data[0] = x;
    460         data[1] = y;
    461         data[2] = z;
    462     }
    463 }
    464 
    465 template<class T, uint32_t N> inline
    466 void VectorN<T, N>::set (T x, T y, T z, T w) {
    467     if (N >= 4) {
    468         data[0] - x;
    469         data[1] = y;
    470         data[2] = z;
    471         data[3] = w;
    472     }
    473 }
    474 
    475 template<class T, uint32_t N> inline
    476 T VectorN<T, N>::magnitude () const {
    477     T result = 0;
    478 
    479     for (uint32_t i = 0; i < N; i++) {
    480         result += (data[i] * data[i]);
    481     }
    482     return (T) sqrtf(result);
    483 }
    484 
    485 template<class T, uint32_t N> inline
    486 float VectorN<T, N>::distance (const VectorN<T, N>& vec) const {
    487     T result = 0;
    488 
    489     for (uint32_t i = 0; i < N; i++) {
    490         result += (vec.data[i] - data[i]) * (vec.data[i] - data[i]);
    491     }
    492     return sqrtf(result);
    493 }
    494 
    495 template<class T, uint32_t N> inline
    496 T VectorN<T, N>::dot (const VectorN<T, N>& vec) const {
    497     T result = 0;
    498 
    499     for (uint32_t i = 0; i < N; i++) {
    500         result += (vec.data[i] * data[i]);
    501     }
    502     return result;
    503 }
    504 
    505 template<class T, uint32_t N> inline
    506 VectorN<T, N> VectorN<T, N>::lerp (T weight, const VectorN<T, N>& vec) const {
    507     return (*this) + (vec - (*this)) * weight;
    508 }
    509 
    510 // NxN matrix in row major order
    511 template<class T, uint32_t N>
    512 class MatrixN
    513 {
    514 public:
    515     MatrixN ();
    516     MatrixN (VectorN<T, 2> a, VectorN<T, 2> b);
    517     MatrixN (VectorN<T, 3> a, VectorN<T, 3> b, VectorN<T, 3> c);
    518     MatrixN (VectorN<T, 4> a, VectorN<T, 4> b, VectorN<T, 4> c, VectorN<T, 4> d);
    519 
    520     inline void zeros ();
    521     inline void eye ();
    522 
    523     inline T& at (uint32_t row, uint32_t col) {
    524         XCAM_ASSERT(row >= 0 && row < N);
    525         XCAM_ASSERT(col >= 0 && col < N);
    526 
    527         return data[row * N + col];
    528     };
    529     inline const T& at (uint32_t row, uint32_t col) const {
    530         XCAM_ASSERT(row >= 0 && row < N);
    531         XCAM_ASSERT(col >= 0 && col < N);
    532 
    533         return data[row * N + col];
    534     };
    535 
    536     inline T& operator () (uint32_t row, uint32_t col) {
    537         return at (row, col);
    538     };
    539     inline const T& operator () (uint32_t row, uint32_t col) const {
    540         return at (row, col);
    541     };
    542 
    543     inline MatrixN<T, N>& operator = (const MatrixN<T, N>& rhs);
    544     inline MatrixN<T, N> operator - () const;
    545     inline MatrixN<T, N> operator + (const MatrixN<T, N>& rhs) const;
    546     inline MatrixN<T, N> operator - (const MatrixN<T, N>& rhs) const;
    547     inline MatrixN<T, N> operator * (const T a) const;
    548     inline MatrixN<T, N> operator / (const T a) const;
    549     inline VectorN<T, N> operator * (const VectorN<T, N>& rhs) const;
    550     inline MatrixN<T, N> operator * (const MatrixN<T, N>& rhs) const;
    551     inline MatrixN<T, N> transpose ();
    552     inline MatrixN<T, N> inverse ();
    553     inline T trace ();
    554 
    555 private:
    556     inline MatrixN<T, 2> inverse (const MatrixN<T, 2>& mat);
    557     inline MatrixN<T, 3> inverse (const MatrixN<T, 3>& mat);
    558     inline MatrixN<T, 4> inverse (const MatrixN<T, 4>& mat);
    559 
    560 private:
    561     T data[N * N];
    562 
    563 };
    564 
    565 // NxN matrix in row major order
    566 template<class T, uint32_t N>
    567 MatrixN<T, N>::MatrixN () {
    568     eye ();
    569 }
    570 
    571 template<class T, uint32_t N>
    572 MatrixN<T, N>::MatrixN (VectorN<T, 2> a, VectorN<T, 2> b) {
    573     if (N == 2) {
    574         data[0] = a[0];
    575         data[1] = a[1];
    576         data[2] = b[0];
    577         data[3] = b[1];
    578     } else {
    579         eye ();
    580     }
    581 }
    582 
    583 template<class T, uint32_t N>
    584 MatrixN<T, N>::MatrixN (VectorN<T, 3> a, VectorN<T, 3> b, VectorN<T, 3> c) {
    585     if (N == 3) {
    586         data[0]  = a[0];
    587         data[1] = a[1];
    588         data[2] = a[2];
    589         data[3]  = b[0];
    590         data[4] = b[1];
    591         data[5] = b[2];
    592         data[6]  = c[0];
    593         data[7] = c[1];
    594         data[8] = c[2];
    595     } else {
    596         eye ();
    597     }
    598 }
    599 
    600 template<class T, uint32_t N>
    601 MatrixN<T, N>::MatrixN (VectorN<T, 4> a, VectorN<T, 4> b, VectorN<T, 4> c, VectorN<T, 4> d) {
    602     if (N == 4) {
    603         data[0]  = a[0];
    604         data[1]  = a[1];
    605         data[2]  = a[2];
    606         data[3]  = a[3];
    607         data[4]  = b[0];
    608         data[5]  = b[1];
    609         data[6]  = b[2];
    610         data[7]  = b[3];
    611         data[8]  = c[0];
    612         data[9]  = c[1];
    613         data[10] = c[2];
    614         data[11] = c[3];
    615         data[12] = d[0];
    616         data[13] = d[1];
    617         data[14] = d[2];
    618         data[15] = d[3];
    619     } else {
    620         eye ();
    621     }
    622 }
    623 
    624 template<class T, uint32_t N> inline
    625 void MatrixN<T, N>::zeros () {
    626     for (uint32_t i = 0; i < N * N; i++) {
    627         data[i] = 0;
    628     }
    629 }
    630 
    631 template<class T, uint32_t N> inline
    632 void MatrixN<T, N>::eye () {
    633     zeros ();
    634     for (uint32_t i = 0; i < N; i++) {
    635         data[i * N + i] = 1;
    636     }
    637 }
    638 
    639 template<class T, uint32_t N> inline
    640 MatrixN<T, N>& MatrixN<T, N>::operator = (const MatrixN<T, N>& rhs) {
    641     for (uint32_t i = 0; i < N * N; i++) {
    642         data[i] = rhs.data[i];
    643     }
    644     return *this;
    645 }
    646 
    647 template<class T, uint32_t N> inline
    648 MatrixN<T, N> MatrixN<T, N>::operator - () const {
    649     MatrixN<T, N> result;
    650     for (uint32_t i = 0; i < N * N; i++) {
    651         result.data[i] = -data[i];
    652     }
    653     return result;
    654 }
    655 
    656 template<class T, uint32_t N> inline
    657 MatrixN<T, N> MatrixN<T, N>::operator + (const MatrixN<T, N>& rhs) const {
    658     MatrixN<T, N> result;
    659     for (uint32_t i = 0; i < N * N; i++) {
    660         result.data[i] = data[i] + rhs.data[i];
    661     }
    662     return result;
    663 }
    664 
    665 template<class T, uint32_t N> inline
    666 MatrixN<T, N> MatrixN<T, N>::operator - (const MatrixN<T, N>& rhs) const {
    667     MatrixN<T, N> result;
    668     for (uint32_t i = 0; i < N * N; i++) {
    669         result.data[i] = data[i] - rhs.data[i];
    670     }
    671     return result;
    672 }
    673 
    674 template<class T, uint32_t N> inline
    675 MatrixN<T, N> MatrixN<T, N>::operator * (const T a) const {
    676     MatrixN<T, N> result;
    677     for (uint32_t i = 0; i < N * N; i++) {
    678         result.data[i] = data[i] * a;
    679     }
    680     return result;
    681 }
    682 
    683 template<class T, uint32_t N> inline
    684 MatrixN<T, N> MatrixN<T, N>::operator / (const T a) const {
    685     MatrixN<T, N> result;
    686     for (uint32_t i = 0; i < N * N; i++) {
    687         result.data[i] = data[i] / a;
    688     }
    689     return result;
    690 }
    691 
    692 template<class T, uint32_t N> inline
    693 MatrixN<T, N> MatrixN<T, N>::operator * (const MatrixN<T, N>& rhs) const {
    694     MatrixN<T, N> result;
    695     result.zeros ();
    696 
    697     for (uint32_t i = 0; i < N; i++) {
    698         for (uint32_t j = 0; j < N; j++) {
    699             T element = 0;
    700             for (uint32_t k = 0; k < N; k++) {
    701                 element += at(i, k) * rhs(k, j);
    702             }
    703             result(i, j) = element;
    704         }
    705     }
    706     return result;
    707 }
    708 
    709 template<class T, uint32_t N> inline
    710 VectorN<T, N> MatrixN<T, N>::operator * (const VectorN<T, N>& rhs) const {
    711     VectorN<T, N> result;
    712     for (uint32_t i = 0; i < N; i++) {  // row
    713         for (uint32_t j = 0; j < N; j++) {  // col
    714             result.data[i] = data[i * N + j] * rhs.data[j];
    715         }
    716     }
    717     return result;
    718 }
    719 
    720 template<class T, uint32_t N> inline
    721 MatrixN<T, N> MatrixN<T, N>::transpose () {
    722     MatrixN<T, N> result;
    723     for (uint32_t i = 0; i < N; i++) {
    724         for (uint32_t j = 0; j <= N; j++) {
    725             result.data[i * N + j] = data[j * N + i];
    726         }
    727     }
    728     return result;
    729 }
    730 
    731 // if the matrix is non-invertible, return identity matrix
    732 template<class T, uint32_t N> inline
    733 MatrixN<T, N> MatrixN<T, N>::inverse () {
    734     MatrixN<T, N> result;
    735 
    736     result = inverse (*this);
    737     return result;
    738 }
    739 
    740 template<class T, uint32_t N> inline
    741 T MatrixN<T, N>::trace () {
    742     T t = 0;
    743     for ( uint32_t i = 0; i < N; i++ ) {
    744         t += data(i, i);
    745     }
    746     return t;
    747 }
    748 
    749 template<class T, uint32_t N> inline
    750 MatrixN<T, 2> MatrixN<T, N>::inverse (const MatrixN<T, 2>& mat)
    751 {
    752     MatrixN<T, 2> result;
    753 
    754     T det = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
    755 
    756     if (det == (T)0) {
    757         return result;
    758     }
    759 
    760     result(0, 0) = mat(1, 1);
    761     result(0, 1) = -mat(0, 1);
    762     result(1, 0) = -mat(1, 0);
    763     result(1, 1) = mat(0, 0);
    764 
    765     return result * (1.0f / det);
    766 }
    767 
    768 template<class T, uint32_t N> inline
    769 MatrixN<T, 3> MatrixN<T, N>::inverse (const MatrixN<T, 3>& mat)
    770 {
    771     MatrixN<T, 3> result;
    772 
    773     T det = mat(0, 0) * mat(1, 1) * mat(2, 2) +
    774             mat(1, 0) * mat(2, 1) * mat(0, 2) +
    775             mat(2, 0) * mat(0, 1) * mat(1, 2) -
    776             mat(0, 0) * mat(2, 1) * mat(1, 2) -
    777             mat(1, 0) * mat(0, 1) * mat(2, 2) -
    778             mat(2, 0) * mat(1, 1) * mat(0, 2);
    779 
    780     if (det == (T)0) {
    781         return result;
    782     }
    783 
    784     result(0, 0) = mat(1, 1) * mat(2, 2) - mat(1, 2) * mat(2, 1);
    785     result(1, 0) = mat(1, 2) * mat(2, 0) - mat(1, 0) * mat(2, 2);
    786     result(2, 0) = mat(1, 0) * mat(2, 1) - mat(1, 1) * mat(2, 0);
    787     result(0, 1) = mat(0, 2) * mat(2, 1) - mat(0, 1) * mat(2, 2);
    788     result(1, 1) = mat(0, 0) * mat(2, 2) - mat(0, 2) * mat(2, 0);
    789     result(2, 1) = mat(0, 1) * mat(2, 0) - mat(0, 0) * mat(2, 1);
    790     result(0, 2) = mat(0, 1) * mat(1, 2) - mat(0, 2) * mat(1, 1);
    791     result(1, 2) = mat(0, 2) * mat(1, 0) - mat(0, 0) * mat(1, 2);
    792     result(2, 2) = mat(0, 0) * mat(1, 1) - mat(0, 1) * mat(1, 0);
    793 
    794     return result * (1.0f / det);
    795 }
    796 
    797 template<class T, uint32_t N> inline
    798 MatrixN<T, 4> MatrixN<T, N>::inverse (const MatrixN<T, 4>& mat)
    799 {
    800     MatrixN<T, 4> result;
    801 
    802     T det =  mat(0, 3) * mat(1, 2) * mat(2, 1) * mat(3, 1) -
    803              mat(0, 2) * mat(1, 3) * mat(2, 1) * mat(3, 1) -
    804              mat(0, 3) * mat(1, 1) * mat(2, 2) * mat(3, 1) +
    805              mat(0, 1) * mat(1, 3) * mat(2, 2) * mat(3, 1) +
    806              mat(0, 2) * mat(1, 1) * mat(2, 3) * mat(3, 1) -
    807              mat(0, 1) * mat(1, 2) * mat(2, 3) * mat(3, 1) -
    808              mat(0, 3) * mat(1, 2) * mat(2, 0) * mat(3, 1) +
    809              mat(0, 2) * mat(1, 3) * mat(2, 0) * mat(3, 1) +
    810              mat(0, 3) * mat(1, 0) * mat(2, 2) * mat(3, 1) -
    811              mat(0, 0) * mat(1, 3) * mat(2, 2) * mat(3, 1) -
    812              mat(0, 2) * mat(1, 0) * mat(2, 3) * mat(3, 1) +
    813              mat(0, 0) * mat(1, 2) * mat(2, 3) * mat(3, 1) +
    814              mat(0, 3) * mat(1, 1) * mat(2, 0) * mat(3, 2) -
    815              mat(0, 1) * mat(1, 3) * mat(2, 0) * mat(3, 2) -
    816              mat(0, 3) * mat(1, 0) * mat(2, 1) * mat(3, 2) +
    817              mat(0, 0) * mat(1, 3) * mat(2, 1) * mat(3, 2) +
    818              mat(0, 1) * mat(1, 0) * mat(2, 3) * mat(3, 2) -
    819              mat(0, 0) * mat(1, 1) * mat(2, 3) * mat(3, 2) -
    820              mat(0, 2) * mat(1, 1) * mat(2, 0) * mat(3, 3) +
    821              mat(0, 1) * mat(1, 2) * mat(2, 0) * mat(3, 3) +
    822              mat(0, 2) * mat(1, 0) * mat(2, 1) * mat(3, 3) -
    823              mat(0, 0) * mat(1, 2) * mat(2, 1) * mat(3, 3) -
    824              mat(0, 1) * mat(1, 0) * mat(2, 2) * mat(3, 3) +
    825              mat(0, 0) * mat(1, 1) * mat(2, 2) * mat(3, 3);
    826 
    827     if (det == (T)0) {
    828         return result;
    829     }
    830 
    831     result(0, 0) = mat(1, 2) * mat(2, 3) * mat(3, 1) -
    832                    mat(1, 3) * mat(2, 2) * mat(3, 1) +
    833                    mat(1, 3) * mat(2, 1) * mat(3, 2) -
    834                    mat(1, 1) * mat(2, 3) * mat(3, 2) -
    835                    mat(1, 2) * mat(2, 1) * mat(3, 3) +
    836                    mat(1, 1) * mat(2, 2) * mat(3, 3);
    837 
    838     result(0, 1) = mat(0, 3) * mat(2, 2) * mat(3, 1) -
    839                    mat(0, 2) * mat(2, 3) * mat(3, 1) -
    840                    mat(0, 3) * mat(2, 1) * mat(3, 2) +
    841                    mat(0, 1) * mat(2, 3) * mat(3, 2) +
    842                    mat(0, 2) * mat(2, 1) * mat(3, 3) -
    843                    mat(0, 1) * mat(2, 2) * mat(3, 3);
    844 
    845     result(0, 2) = mat(0, 2) * mat(1, 3) * mat(3, 1) -
    846                    mat(0, 3) * mat(1, 2) * mat(3, 1) +
    847                    mat(0, 3) * mat(1, 1) * mat(3, 2) -
    848                    mat(0, 1) * mat(1, 3) * mat(3, 2) -
    849                    mat(0, 2) * mat(1, 1) * mat(3, 3) +
    850                    mat(0, 1) * mat(1, 2) * mat(3, 3);
    851 
    852     result(0, 3) = mat(0, 3) * mat(1, 2) * mat(2, 1) -
    853                    mat(0, 2) * mat(1, 3) * mat(2, 1) -
    854                    mat(0, 3) * mat(1, 1) * mat(2, 2) +
    855                    mat(0, 1) * mat(1, 3) * mat(2, 2) +
    856                    mat(0, 2) * mat(1, 1) * mat(2, 3) -
    857                    mat(0, 1) * mat(1, 2) * mat(2, 3);
    858 
    859     result(1, 0) = mat(1, 3) * mat(2, 2) * mat(3, 0) -
    860                    mat(1, 2) * mat(2, 3) * mat(3, 0) -
    861                    mat(1, 3) * mat(2, 0) * mat(3, 2) +
    862                    mat(1, 0) * mat(2, 3) * mat(3, 2) +
    863                    mat(1, 2) * mat(2, 0) * mat(3, 3) -
    864                    mat(1, 0) * mat(2, 2) * mat(3, 3);
    865 
    866     result(1, 1) = mat(0, 2) * mat(2, 3) * mat(3, 0) -
    867                    mat(0, 3) * mat(2, 2) * mat(3, 0) +
    868                    mat(0, 3) * mat(2, 0) * mat(3, 2) -
    869                    mat(0, 0) * mat(2, 3) * mat(3, 2) -
    870                    mat(0, 2) * mat(2, 0) * mat(3, 3) +
    871                    mat(0, 0) * mat(2, 2) * mat(3, 3);
    872 
    873     result(1, 2) = mat(0, 3) * mat(1, 2) * mat(3, 0) -
    874                    mat(0, 2) * mat(1, 3) * mat(3, 0) -
    875                    mat(0, 3) * mat(1, 0) * mat(3, 2) +
    876                    mat(0, 0) * mat(1, 3) * mat(3, 2) +
    877                    mat(0, 2) * mat(1, 0) * mat(3, 3) -
    878                    mat(0, 0) * mat(1, 2) * mat(3, 3);
    879 
    880     result(1, 3) = mat(0, 2) * mat(1, 3) * mat(2, 0) -
    881                    mat(0, 3) * mat(1, 2) * mat(2, 0) +
    882                    mat(0, 3) * mat(1, 0) * mat(2, 2) -
    883                    mat(0, 0) * mat(1, 3) * mat(2, 2) -
    884                    mat(0, 2) * mat(1, 0) * mat(2, 3) +
    885                    mat(0, 0) * mat(1, 2) * mat(2, 3);
    886 
    887     result(2, 0) = mat(1, 1) * mat(2, 3) * mat(3, 0) -
    888                    mat(1, 3) * mat(2, 1) * mat(3, 0) +
    889                    mat(1, 3) * mat(2, 0) * mat(3, 1) -
    890                    mat(1, 0) * mat(2, 3) * mat(3, 1) -
    891                    mat(1, 1) * mat(2, 0) * mat(3, 3) +
    892                    mat(1, 0) * mat(2, 1) * mat(3, 3);
    893 
    894     result(2, 1) = mat(0, 3) * mat(2, 1) * mat(3, 0) -
    895                    mat(0, 1) * mat(2, 3) * mat(3, 0) -
    896                    mat(0, 3) * mat(2, 0) * mat(3, 1) +
    897                    mat(0, 0) * mat(2, 3) * mat(3, 1) +
    898                    mat(0, 1) * mat(2, 0) * mat(3, 3) -
    899                    mat(0, 0) * mat(2, 1) * mat(3, 3);
    900 
    901     result(2, 2) = mat(0, 1) * mat(1, 3) * mat(3, 0) -
    902                    mat(0, 3) * mat(1, 1) * mat(3, 0) +
    903                    mat(0, 3) * mat(1, 0) * mat(3, 1) -
    904                    mat(0, 0) * mat(1, 3) * mat(3, 1) -
    905                    mat(0, 1) * mat(1, 0) * mat(3, 3) +
    906                    mat(0, 0) * mat(1, 1) * mat(3, 3);
    907 
    908     result(2, 3) = mat(0, 3) * mat(1, 1) * mat(2, 0) -
    909                    mat(0, 1) * mat(1, 3) * mat(2, 0) -
    910                    mat(0, 3) * mat(1, 0) * mat(2, 1) +
    911                    mat(0, 0) * mat(1, 3) * mat(2, 1) +
    912                    mat(0, 1) * mat(1, 0) * mat(2, 3) -
    913                    mat(0, 0) * mat(1, 1) * mat(2, 3);
    914 
    915     result(3, 0) = mat(1, 2) * mat(2, 1) * mat(3, 0) -
    916                    mat(1, 1) * mat(2, 2) * mat(3, 0) -
    917                    mat(1, 2) * mat(2, 0) * mat(3, 1) +
    918                    mat(1, 0) * mat(2, 2) * mat(3, 1) +
    919                    mat(1, 1) * mat(2, 0) * mat(3, 2) -
    920                    mat(1, 0) * mat(2, 1) * mat(3, 2);
    921 
    922     result(3, 1) = mat(1, 1) * mat(2, 2) * mat(3, 0) -
    923                    mat(1, 2) * mat(2, 1) * mat(3, 0) +
    924                    mat(1, 2) * mat(2, 0) * mat(3, 1) -
    925                    mat(1, 0) * mat(2, 2) * mat(3, 1) -
    926                    mat(1, 1) * mat(2, 0) * mat(3, 2) +
    927                    mat(1, 0) * mat(2, 1) * mat(3, 2);
    928 
    929     result(3, 2) = mat(0, 2) * mat(1, 1) * mat(3, 0) -
    930                    mat(0, 1) * mat(1, 2) * mat(3, 0) -
    931                    mat(0, 2) * mat(1, 0) * mat(3, 1) +
    932                    mat(0, 0) * mat(1, 2) * mat(3, 1) +
    933                    mat(0, 1) * mat(1, 0) * mat(3, 2) -
    934                    mat(0, 0) * mat(1, 1) * mat(3, 2);
    935 
    936     result(3, 3) = mat(0, 1) * mat(1, 2) * mat(2, 0) -
    937                    mat(0, 2) * mat(1, 1) * mat(2, 0) +
    938                    mat(0, 2) * mat(1, 0) * mat(2, 1) -
    939                    mat(0, 0) * mat(1, 2) * mat(2, 1) -
    940                    mat(0, 1) * mat(1, 0) * mat(2, 2) +
    941                    mat(0, 0) * mat(1, 1) * mat(2, 2);
    942 
    943     return result * (1.0f / det);
    944 }
    945 
    946 typedef VectorN<double, 2> Vec2d;
    947 typedef VectorN<double, 3> Vec3d;
    948 typedef VectorN<double, 4> Vec4d;
    949 typedef MatrixN<double, 2> Mat2d;
    950 typedef MatrixN<double, 3> Mat3d;
    951 typedef MatrixN<double, 4> Mat4d;
    952 
    953 typedef VectorN<float, 2> Vec2f;
    954 typedef VectorN<float, 3> Vec3f;
    955 typedef VectorN<float, 4> Vec4f;
    956 typedef MatrixN<float, 3> Mat3f;
    957 typedef MatrixN<float, 4> Mat4f;
    958 
    959 template<class T>
    960 class Quaternion
    961 {
    962 public:
    963 
    964     Vec3d v;
    965     T w;
    966 
    967     Quaternion () : v(0, 0, 0), w(0) {};
    968     Quaternion (const Quaternion<T>& q) : v(q.v), w(q.w) {};
    969 
    970     Quaternion (const Vec3d& vec, T _w) : v(vec), w(_w) {};
    971     Quaternion (const Vec4d& vec)  : v(vec[0], vec[1], vec[2]), w(vec[3]) {};
    972     Quaternion (T _x, T _y, T _z, T _w) : v(_x, _y, _z), w(_w) {};
    973 
    974     inline void reset () {
    975         v.zeros();
    976         w = (T) 0;
    977     }
    978 
    979     inline Quaternion<T>& operator = (const Quaternion<T>& rhs) {
    980         v = rhs.v;
    981         w = rhs.w;
    982         return *this;
    983     }
    984 
    985     inline Quaternion<T> operator + (const Quaternion<T>& rhs) const {
    986         const Quaternion<T>& lhs = *this;
    987         return Quaternion<T>(lhs.v + rhs.v, lhs.w + rhs.w);
    988     }
    989 
    990     inline Quaternion<T> operator - (const Quaternion<T>& rhs) const {
    991         const Quaternion<T>& lhs = *this;
    992         return Quaternion<T>(lhs.v - rhs.v, lhs.w - rhs.w);
    993     }
    994 
    995     inline Quaternion<T> operator * (T rhs) const {
    996         return Quaternion<T>(v * rhs, w * rhs);
    997     }
    998 
    999     inline Quaternion<T> operator * (const Quaternion<T>& rhs) const {
   1000         const Quaternion<T>& lhs = *this;
   1001         return Quaternion<T>(lhs.w * rhs.v[0] + lhs.v[0] * rhs.w + lhs.v[1] * rhs.v[2] - lhs.v[2] * rhs.v[1],
   1002                              lhs.w * rhs.v[1] - lhs.v[0] * rhs.v[2] + lhs.v[1] * rhs.w + lhs.v[2] * rhs.v[0],
   1003                              lhs.w * rhs.v[2] + lhs.v[0] * rhs.v[1] - lhs.v[1] * rhs.v[0] + lhs.v[2] * rhs.w,
   1004                              lhs.w * rhs.w - lhs.v[0] * rhs.v[0] - lhs.v[1] * rhs.v[1] - lhs.v[2] * rhs.v[2]);
   1005     }
   1006 
   1007     /*
   1008                    --------
   1009                   /    --
   1010         |Qr| =  \/  Qr.Qr
   1011     */
   1012     inline T magnitude () const {
   1013         return (T) sqrtf(w * w + v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
   1014     }
   1015 
   1016     inline void normalize ()
   1017     {
   1018         T length = magnitude ();
   1019         w = w / length;
   1020         v = v / length;
   1021     }
   1022 
   1023     inline Quaternion<T> conjugate (const Quaternion<T>& quat) const {
   1024         return Quaternion<T>(-quat.v, quat.w);
   1025     }
   1026 
   1027     inline Quaternion<T> inverse (const Quaternion<T>& quat) const {
   1028         return conjugate(quat) * ( 1.0f / magnitude(quat));
   1029     }
   1030 
   1031     inline Quaternion<T> lerp (T weight, const Quaternion<T>& quat) const {
   1032         return Quaternion<T>(v.lerp(weight, quat.v), (1 - weight) * w + weight * quat.w);
   1033     }
   1034 
   1035     inline Quaternion<T> slerp(T r, const Quaternion<T>& quat) const {
   1036         Quaternion<T> ret;
   1037         T cos_theta = w * quat.w + v[0] * quat.v[0] + v[1] * quat.v[1] + v[2] * quat.v[2];
   1038         T theta = (T) acos(cos_theta);
   1039         if (fabs(theta) < FLT_EPSILON)
   1040         {
   1041             ret = *this;
   1042         }
   1043         else
   1044         {
   1045             T sin_theta = (T) sqrt(1.0 - cos_theta * cos_theta);
   1046             if (fabs(sin_theta) < FLT_EPSILON)
   1047             {
   1048                 ret.w = 0.5 * w + 0.5 * quat.w;
   1049                 ret.v = v.lerp(0.5, quat.v);
   1050             }
   1051             else
   1052             {
   1053                 T r0 = (T) sin((1.0 - r) * theta) / sin_theta;
   1054                 T r1 = (T) sin(r * theta) / sin_theta;
   1055 
   1056                 ret.w = w * r0 + quat.w * r1;
   1057                 ret.v[0] = v[0] * r0 + quat.v[0] * r1;
   1058                 ret.v[1] = v[1] * r0 + quat.v[1] * r1;
   1059                 ret.v[2] = v[2] * r0 + quat.v[2] * r1;
   1060             }
   1061         }
   1062         return ret;
   1063     }
   1064 
   1065     static Quaternion<T> create_quaternion (Vec3d axis, T angle_rad) {
   1066         T theta_over_two = angle_rad / (T) 2.0;
   1067         T sin_theta_over_two = std::sin(theta_over_two);
   1068         T cos_theta_over_two = std::cos(theta_over_two);
   1069         return Quaternion<T>(axis * sin_theta_over_two, cos_theta_over_two);
   1070     }
   1071 
   1072     static Quaternion<T> create_quaternion (Vec3d euler) {
   1073         return create_quaternion(Vec3d(1, 0, 0), euler[0]) *
   1074                create_quaternion(Vec3d(0, 1, 0), euler[1]) *
   1075                create_quaternion(Vec3d(0, 0, 1), euler[2]);
   1076     }
   1077 
   1078     static Quaternion<T> create_quaternion (const Mat3d& mat) {
   1079         Quaternion<T> q;
   1080 
   1081         T trace, s;
   1082         T diag1 = mat(0, 0);
   1083         T diag2 = mat(1, 1);
   1084         T diag3 = mat(2, 2);
   1085 
   1086         trace = diag1 + diag2 + diag3;
   1087 
   1088         if (trace >= FLT_EPSILON)
   1089         {
   1090             s = 2.0 * (T) sqrt(trace + 1.0);
   1091             q.w = 0.25 * s;
   1092             q.v[0] = (mat(2, 1) - mat(1, 2)) / s;
   1093             q.v[1] = (mat(0, 2) - mat(2, 0)) / s;
   1094             q.v[2] = (mat(1, 0) - mat(0, 1)) / s;
   1095         }
   1096         else
   1097         {
   1098             char max_diag = (diag1 > diag2) ? ((diag1 > diag3) ? 1 : 3) : ((diag2 > diag3) ? 2 : 3);
   1099 
   1100             if (max_diag == 1)
   1101             {
   1102                 s = 2.0 * (T) sqrt(1.0 + mat(0, 0) - mat(1, 1) - mat(2, 2));
   1103                 q.w = (mat(2, 1) - mat(1, 2)) / s;
   1104                 q.v[0] = 0.25 * s;
   1105                 q.v[1] = (mat(0, 1) + mat(1, 0)) / s;
   1106                 q.v[2] = (mat(0, 2) + mat(2, 0)) / s;
   1107             }
   1108             else if (max_diag == 2)
   1109             {
   1110                 s = 2.0 * (T) sqrt(1.0 + mat(1, 1) - mat(0, 0) - mat(2, 2));
   1111                 q.w = (mat(0, 2) - mat(2, 0)) / s;
   1112                 q.v[0] = (mat(0, 1) + mat(1, 0)) / s;
   1113                 q.v[1] = 0.25 * s;
   1114                 q.v[2] = (mat(1, 2) + mat(2, 1)) / s;
   1115             }
   1116             else
   1117             {
   1118                 s = 2.0 * (T) sqrt(1.0 + mat(2, 2) - mat(0, 0) - mat(1, 1));
   1119                 q.w = (mat(1, 0) - mat(0, 1)) / s;
   1120                 q.v[0] = (mat(0, 2) + mat(2, 0)) / s;
   1121                 q.v[1] = (mat(1, 2) + mat(2, 1)) / s;
   1122                 q.v[2] = 0.25 * s;
   1123             }
   1124         }
   1125 
   1126         return q;
   1127     }
   1128 
   1129     inline Vec4d rotation_axis () {
   1130         Vec4d rot_axis;
   1131 
   1132         T cos_theta_over_two = w;
   1133         rot_axis[4] = (T) std::acos( cos_theta_over_two ) * 2.0f;
   1134 
   1135         T sin_theta_over_two = (T) sqrt( 1.0 - cos_theta_over_two * cos_theta_over_two );
   1136         if ( fabs( sin_theta_over_two ) < 0.0005 ) sin_theta_over_two = 1;
   1137         rot_axis[0] = v[0] / sin_theta_over_two;
   1138         rot_axis[1] = v[1] / sin_theta_over_two;
   1139         rot_axis[2] = v[2] / sin_theta_over_two;
   1140 
   1141         return rot_axis;
   1142     }
   1143 
   1144     /*
   1145         psi=atan2(2.*(Q(:,1).*Q(:,4)-Q(:,2).*Q(:,3)),(Q(:,4).^2-Q(:,1).^2-Q(:,2).^2+Q(:,3).^2));
   1146         theta=asin(2.*(Q(:,1).*Q(:,3)+Q(:,2).*Q(:,4)));
   1147         phi=atan2(2.*(Q(:,3).*Q(:,4)-Q(:,1).*Q(:,2)),(Q(:,4).^2+Q(:,1).^2-Q(:,2).^2-Q(:,3).^2));
   1148     */
   1149     inline Vec3d euler_angles () {
   1150         Vec3d euler;
   1151 
   1152         // atan2(2*(qx*qw-qy*qz) , qw2-qx2-qy2+qz2)
   1153         euler[0] = atan2(2 * (v[0] * w - v[1] * v[2]),
   1154                          w * w - v[0] * v[0] - v[1] * v[1] + v[2] * v[2]);
   1155 
   1156         // asin(2*(qx*qz + qy*qw)
   1157         euler[1] = asin(2 * (v[0] * v[2] + v[1] * w));
   1158 
   1159         // atan2(2*(qz*qw- qx*qy) , qw2 + qx2 - qy2 - qz2)
   1160         euler[2] = atan2(2 * (v[2] * w - v[0] * v[1]),
   1161                          w * w + v[0] * v[0] - v[1] * v[1] - v[2] * v[2]);
   1162 
   1163         return euler;
   1164     }
   1165 
   1166     inline Mat3d rotation_matrix () {
   1167         Mat3d mat;
   1168 
   1169         T xx = v[0] * v[0];
   1170         T xy = v[0] * v[1];
   1171         T xz = v[0] * v[2];
   1172         T xw = v[0] * w;
   1173 
   1174         T yy = v[1] * v[1];
   1175         T yz = v[1] * v[2];
   1176         T yw = v[1] * w;
   1177 
   1178         T zz = v[2] * v[2];
   1179         T zw = v[2] * w;
   1180 
   1181         mat(0, 0) = 1 - 2 * (yy + zz);
   1182         mat(0, 1) = 2 * (xy - zw);
   1183         mat(0, 2) = 2 * (xz + yw);
   1184         mat(1, 0) = 2 * (xy + zw);
   1185         mat(1, 1) = 1 - 2 * (xx + zz);
   1186         mat(1, 2) = 2 * (yz - xw);
   1187         mat(2, 0) = 2 * (xz - yw);
   1188         mat(2, 1) = 2 * (yz + xw);
   1189         mat(2, 2) = 1 - 2 * (xx + yy);
   1190 
   1191         return mat;
   1192     }
   1193 };
   1194 
   1195 
   1196 typedef Quaternion<double> Quaternd;
   1197 
   1198 }
   1199 
   1200 #endif //XCAM_VECTOR_MATRIX_H
   1201