All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Quaternion.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_QUATERNION_H_
36 #define _BLAZE_MATH_QUATERNION_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <cmath>
44 #include <istream>
45 #include <ostream>
46 #include <blaze/math/Accuracy.h>
47 #include <blaze/math/Forward.h>
48 #include <blaze/math/shims/Equal.h>
50 #include <blaze/math/shims/IsNaN.h>
53 #include <blaze/system/Precision.h>
54 #include <blaze/util/Assert.h>
58 #include <blaze/util/Types.h>
59 
60 
61 namespace blaze {
62 
63 //=================================================================================================
64 //
65 // CLASS DEFINITION
66 //
67 //=================================================================================================
68 
69 //*************************************************************************************************
102 template< typename Type > // Data type of the quaternion
103 class Quaternion
104 {
105  public:
106  //**Type definitions****************************************************************************
107  typedef Type ElementType;
108  //**********************************************************************************************
109 
110  //**Constructors********************************************************************************
113  explicit inline Quaternion();
114 
115  explicit inline Quaternion( Type r, Type i, Type j, Type k );
116 
117  template< typename Axis >
118  explicit inline Quaternion( StaticVector<Axis,3UL,false> axis, Type angle );
119 
120  explicit inline Quaternion( Type xangle, Type yangle, Type zangle );
121 
122  template< typename Other >
123  explicit inline Quaternion( const StaticVector<Other,3UL,false>& euler );
124 
125  inline Quaternion( const Quaternion& q );
126 
127  template< typename Other >
128  inline Quaternion( const Quaternion<Other>& q );
130  //**********************************************************************************************
131 
132  //**Destructor**********************************************************************************
133  // No explicitly declared destructor.
134  //**********************************************************************************************
135 
136  //**Operators***********************************************************************************
139  inline Quaternion& operator= ( const Quaternion& rhs );
140  template< typename Other > inline Quaternion& operator= ( const Quaternion<Other>& rhs );
141  inline Type operator[]( size_t index ) const;
143  //**********************************************************************************************
144 
145  //**Utility functions***************************************************************************
148  inline Quaternion& set( Type r, Type i, Type j, Type k );
149  inline void reset();
150  inline Type length() const;
151  inline Quaternion& normalize();
152  inline const Quaternion getNormalized() const;
153  inline Quaternion& invert();
154  inline const RotationMatrix<Type> toRotationMatrix() const;
155  inline void rotateX( Type angle );
156  inline void rotateY( Type angle );
157  inline void rotateZ( Type angle );
158  inline void swap( Quaternion& q ) /* throw() */;
160  //**********************************************************************************************
161 
162  //**Math functions******************************************************************************
165  template< typename Other, bool TF >
167  rotate( const StaticVector<Other,3UL,TF>& v ) const;
168 
169  template< typename Other >
170  inline const StaticMatrix<typename MultTrait<Type,Other>::Type,3UL,3UL,false>
171  rotate( const StaticMatrix<Other,3UL,3UL,false>& m ) const;
172 
173  template< typename Other >
174  inline const StaticMatrix<typename MultTrait<Type,Other>::Type,3UL,3UL,false>
176 
177  template< typename Other >
178  inline typename MathTrait<Type,Other>::HighType
179  calcAngle( const StaticVector<Other,3UL,false>& axis ) const;
181  //**********************************************************************************************
182 
183  private:
184  //**Member variables****************************************************************************
187  Type v_[4];
188 
194  //**********************************************************************************************
195 
196  //**Compile time checks*************************************************************************
202  //**********************************************************************************************
203 };
204 //*************************************************************************************************
205 
206 
207 
208 
209 //=================================================================================================
210 //
211 // CONSTRUCTORS
212 //
213 //=================================================================================================
214 
215 //*************************************************************************************************
223 template< typename Type > // Data type of the quaternion
225 {
226  reset();
227 }
228 //*************************************************************************************************
229 
230 
231 //*************************************************************************************************
242 template< typename Type > // Data type of the quaternion
243 inline Quaternion<Type>::Quaternion( Type r, Type i, Type j, Type k )
244 {
245  v_[0] = r; v_[1] = i; v_[2] = j; v_[3] = k;
246  BLAZE_USER_ASSERT( std::fabs( r*r + i*i + j*j + k*k - Type(1) ) < Type(accuracy), "Invalid quaternion parameters" );
247 }
248 //*************************************************************************************************
249 
250 
251 //*************************************************************************************************
264 template< typename Type > // Data type of the quaternion
265 template< typename Axis > // Data type of the rotation axis
267 {
269 
270  if( std::fabs(angle) < real(1E-15) ) {
271  reset();
272  return;
273  }
274 
275  BLAZE_USER_ASSERT( axis.sqrLength() > Axis(0), "Invalid rotation axis" );
276 
277  const Type sina( std::sin( angle*Type(0.5) ) );
278  const Type cosa( std::cos( angle*Type(0.5) ) );
279 
280  axis.normalize();
281 
282  v_[0] = cosa;
283  v_[1] = sina * axis[0];
284  v_[2] = sina * axis[1];
285  v_[3] = sina * axis[2];
286 }
287 //*************************************************************************************************
288 
289 
290 //*************************************************************************************************
300 template< typename Type > // Data type of the quaternion
301 inline Quaternion<Type>::Quaternion( Type xangle, Type yangle, Type zangle )
302 {
303  reset();
304  rotateX( xangle );
305  rotateY( yangle );
306  rotateZ( zangle );
307 }
308 //*************************************************************************************************
309 
310 
311 //*************************************************************************************************
319 template< typename Type > // Data type of the quaternion
320 template< typename Other > // Data type of the Euler angle vector
322 {
323  reset();
324  rotateX( euler[0] );
325  rotateY( euler[1] );
326  rotateZ( euler[2] );
327 }
328 //*************************************************************************************************
329 
330 
331 //*************************************************************************************************
338 template< typename Type > // Data type of the quaternion
340 {
341  v_[0] = q.v_[0];
342  v_[1] = q.v_[1];
343  v_[2] = q.v_[2];
344  v_[3] = q.v_[3];
345 }
346 //*************************************************************************************************
347 
348 
349 //*************************************************************************************************
354 template< typename Type > // Data type of the quaternion
355 template< typename Other > // Data type of the foreign quaternion
357 {
358  v_[0] = q[0];
359  v_[1] = q[1];
360  v_[2] = q[2];
361  v_[3] = q[3];
362 }
363 //*************************************************************************************************
364 
365 
366 
367 
368 //=================================================================================================
369 //
370 // OPERATORS
371 //
372 //=================================================================================================
373 
374 //*************************************************************************************************
382 template< typename Type > // Data type of the quaternion
384 {
385  // This implementation is faster than the synthesized default copy assignment operator and
386  // faster than an implementation with the C library function 'memcpy' in combination with a
387  // protection against self-assignment. Additionally, this version goes without a protection
388  // against self-assignment.
389  v_[0] = rhs.v_[0];
390  v_[1] = rhs.v_[1];
391  v_[2] = rhs.v_[2];
392  v_[3] = rhs.v_[3];
393  return *this;
394 }
395 //*************************************************************************************************
396 
397 
398 //*************************************************************************************************
404 template< typename Type > // Data type of the quaternion
405 template< typename Other > // Data type of the foreign quaternion
407 {
408  // This implementation is faster than the synthesized default copy assignment operator and
409  // faster than an implementation with the C library function 'memcpy' in combination with a
410  // protection against self-assignment. Additionally, this version goes without a protection
411  // against self-assignment.
412  v_[0] = rhs[0];
413  v_[1] = rhs[1];
414  v_[2] = rhs[2];
415  v_[3] = rhs[3];
416  return *this;
417 }
418 //*************************************************************************************************
419 
420 
421 //*************************************************************************************************
429 template< typename Type > // Data type of the quaternion
430 inline Type Quaternion<Type>::operator[]( size_t index ) const
431 {
432  BLAZE_USER_ASSERT( index < 4, "Invalid quaternion access index" );
433  return v_[index];
434 }
435 //*************************************************************************************************
436 
437 
438 
439 
440 //=================================================================================================
441 //
442 // UTILITY FUNCTIONS
443 //
444 //=================================================================================================
445 
446 //*************************************************************************************************
454 template< typename Type > // Data type of the quaternion
455 inline Quaternion<Type>& Quaternion<Type>::set( Type r, Type i, Type j, Type k )
456 {
457  BLAZE_USER_ASSERT( std::fabs( r*r + i*i + j*j + k*k - Type(1) ) < Type(1E-8), "Invalid quaternion parameters" );
458  v_[0] = r;
459  v_[1] = i;
460  v_[2] = j;
461  v_[3] = k;
462  return *this;
463 }
464 //*************************************************************************************************
465 
466 
467 //*************************************************************************************************
479 template< typename Type > // Data type of the quaternion
481 {
482  v_[0] = Type(1);
483  v_[1] = v_[2] = v_[3] = Type(0);
484 }
485 //*************************************************************************************************
486 
487 
488 //*************************************************************************************************
493 template< typename Type > // Data type of the quaternion
494 inline Type Quaternion<Type>::length() const
495 {
496  // Although the length of the quaternion should always be exactly one, the function
497  // calculates the actual length to enable length checks.
498  return std::sqrt( v_[0]*v_[0] + v_[1]*v_[1] + v_[2]*v_[2] + v_[3]*v_[3] );
499 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
508 template< typename Type > // Data type of the quaternion
510 {
511  const Type len( std::sqrt( v_[0]*v_[0] + v_[1]*v_[1] + v_[2]*v_[2] + v_[3]*v_[3] ) );
512 
513  if( len == Type(0) )
514  return *this;
515 
516  const Type ilen( Type(1)/len );
517 
518  v_[0] *= ilen;
519  v_[1] *= ilen;
520  v_[2] *= ilen;
521  v_[3] *= ilen;
522 
523  return *this;
524 }
525 //*************************************************************************************************
526 
527 
528 //*************************************************************************************************
533 template< typename Type > // Data type of the quaternion
535 {
536  const Type len( std::sqrt( v_[0]*v_[0] + v_[1]*v_[1] + v_[2]*v_[2] + v_[3]*v_[3] ) );
537 
538  if( len == Type(0) )
539  return *this;
540 
541  const Type ilen( Type(1)/len );
542 
543  return Quaternion( ilen*v_[0], ilen*v_[1], ilen*v_[2], ilen*v_[3] );
544 }
545 //*************************************************************************************************
546 
547 
548 //*************************************************************************************************
553 template< typename Type > // Data type of the quaternion
555 {
556  v_[1] *= -Type(1);
557  v_[2] *= -Type(1);
558  v_[3] *= -Type(1);
559  return *this;
560 }
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
569 template< typename Type > // Data type of the quaternion
571 {
572  return RotationMatrix<Type>( Type(1) - Type(2)*v_[2]*v_[2] - Type(2)*v_[3]*v_[3],
573  Type(2)*( v_[1]*v_[2] - v_[0]*v_[3] ),
574  Type(2)*( v_[1]*v_[3] + v_[0]*v_[2] ),
575  Type(2)*( v_[1]*v_[2] + v_[0]*v_[3] ),
576  Type(1) - Type(2)*v_[1]*v_[1] - Type(2)*v_[3]*v_[3],
577  Type(2)*( v_[2]*v_[3] - v_[0]*v_[1] ),
578  Type(2)*( v_[1]*v_[3] - v_[0]*v_[2] ),
579  Type(2)*( v_[2]*v_[3] + v_[0]*v_[1] ),
580  Type(1) - Type(2)*v_[1]*v_[1] - Type(2)*v_[2]*v_[2] );
581 }
582 //*************************************************************************************************
583 
584 
585 //*************************************************************************************************
591 template< typename Type > // Data type of the quaternion
592 inline void Quaternion<Type>::rotateX( Type angle )
593 {
594  const Type sina( std::sin( angle*Type(0.5) ) );
595  const Type cosa( std::cos( angle*Type(0.5) ) );
596 
597  const Quaternion q( cosa*v_[0] - sina*v_[1],
598  cosa*v_[1] + sina*v_[0],
599  cosa*v_[2] - sina*v_[3],
600  cosa*v_[3] + sina*v_[2] );
601 
602  this->operator=( q );
603 }
604 //*************************************************************************************************
605 
606 
607 //*************************************************************************************************
613 template< typename Type > // Data type of the quaternion
614 inline void Quaternion<Type>::rotateY( Type angle )
615 {
616  const Type sina( std::sin( angle*Type(0.5) ) );
617  const Type cosa( std::cos( angle*Type(0.5) ) );
618 
619  const Quaternion q( cosa*v_[0] - sina*v_[2],
620  cosa*v_[1] + sina*v_[3],
621  cosa*v_[2] + sina*v_[0],
622  cosa*v_[3] - sina*v_[1] );
623 
624  this->operator=( q );
625 }
626 //*************************************************************************************************
627 
628 
629 //*************************************************************************************************
635 template< typename Type > // Data type of the quaternion
636 inline void Quaternion<Type>::rotateZ( Type angle )
637 {
638  const Type sina( std::sin( angle*Type(0.5) ) );
639  const Type cosa( std::cos( angle*Type(0.5) ) );
640 
641  const Quaternion q( cosa*v_[0] - sina*v_[3],
642  cosa*v_[1] - sina*v_[2],
643  cosa*v_[2] + sina*v_[1],
644  cosa*v_[3] + sina*v_[0] );
645 
646  this->operator=( q );
647 }
648 //*************************************************************************************************
649 
650 
651 //*************************************************************************************************
658 template< typename Type > // Data type of the quaternion
659 inline void Quaternion<Type>::swap( Quaternion& q ) /* throw() */
660 {
661  std::swap( v_[0], q.v_[0] );
662  std::swap( v_[1], q.v_[1] );
663  std::swap( v_[2], q.v_[2] );
664  std::swap( v_[3], q.v_[3] );
665 }
666 //*************************************************************************************************
667 
668 
669 
670 
671 //=================================================================================================
672 //
673 // MATH FUNCTIONS
674 //
675 //=================================================================================================
676 
677 //*************************************************************************************************
687 template< typename Type > // Data type of the quaternion
688 template< typename Other // Data type of the vector
689  , bool TF > // Transpose flag
692 {
693  typedef typename MultTrait<Type,Other>::Type MT;
694 
695  // Multiplication in two steps
696  const MT w( v_[1]*v[0] + v_[2]*v[1] + v_[3]*v[2] );
697  const MT x( v_[0]*v[0] - v_[3]*v[1] + v_[2]*v[2] );
698  const MT y( v_[0]*v[1] - v_[1]*v[2] + v_[3]*v[0] );
699  const MT z( v_[0]*v[2] - v_[2]*v[0] + v_[1]*v[1] );
700 
701  return StaticVector<MT,3UL,TF>( v_[0]*x + v_[1]*w + v_[2]*z - v_[3]*y,
702  v_[0]*y + v_[2]*w + v_[3]*x - v_[1]*z,
703  v_[0]*z + v_[3]*w + v_[1]*y - v_[2]*x );
704 
705  // Multiplication in one step
706  /*
707  const MT v0( v_[0] * v_[0] );
708  const MT v1( v_[1] * v_[1] );
709  const MT v2( v_[2] * v_[2] );
710  const MT v3( v_[3] * v_[3] );
711 
712  return StaticVector<MT,3UL,TF>( ( v[0]*( v0 + v1 - v2 - v3 ) + 2.0*v_[0]*( v_[2]*v[2] - v_[3]*v[1] ) + 2.0*v_[1]*( v_[2]*v[1] + v_[3]*v[2] ) ),
713  ( v[1]*( v0 - v1 + v2 - v3 ) + 2.0*v_[0]*( v_[3]*v[0] - v_[1]*v[2] ) + 2.0*v_[2]*( v_[1]*v[0] + v_[3]*v[2] ) ),
714  ( v[2]*( v0 - v1 - v2 + v3 ) + 2.0*v_[0]*( v_[1]*v[1] - v_[2]*v[0] ) + 2.0*v_[3]*( v_[1]*v[0] + v_[2]*v[1] ) ) );
715  */
716 }
717 //*************************************************************************************************
718 
719 
720 //*************************************************************************************************
730 template< typename Type > // Data type of the quaternion
731 template< typename Other > // Data type of the matrix
732 inline const StaticMatrix< typename MultTrait<Type,Other>::Type, 3UL, 3UL, false >
734 {
735  typedef typename MultTrait<Type,Other>::Type MT;
736  const RotationMatrix<MT> R( this->toRotationMatrix() );
737  return R.rotate( m );
738 }
739 //*************************************************************************************************
740 
741 
742 //*************************************************************************************************
754 template< typename Type > // Data type of the quaternion
755 template< typename Other > // Data type of the diagonal matrix
756 inline const StaticMatrix< typename MultTrait<Type,Other>::Type, 3UL, 3UL, false >
758 {
759  typedef typename MultTrait<Type,Other>::Type MT;
760  const RotationMatrix<MT> R( this->toRotationMatrix() );
761  return R.diagRotate( m );
762 }
763 //*************************************************************************************************
764 
765 
766 //*************************************************************************************************
772 template< typename Type > // Data type of the quaternion
773 template< typename Other > // Data type of the axis
774 inline typename MathTrait<Type,Other>::HighType
776 {
777  typedef typename MathTrait<Type,Other>::HighType High;
778 
779  const StaticVector<High,3UL,true> u( v_[1], v_[2], v_[3] );
780  const High y ( u.length() );
781  const High x ( v_[0] );
782  const High dot( u * axis );
783 
784  return High(2) * std::atan2( y, ( dot < real(0) )?( -x ):( x ) );
785 }
786 //*************************************************************************************************
787 
788 
789 
790 
791 //=================================================================================================
792 //
793 // GLOBAL OPERATORS
794 //
795 //=================================================================================================
796 
797 //*************************************************************************************************
800 template< typename T1, typename T2 >
801 inline bool operator==( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs );
802 
803 template< typename T1, typename T2 >
804 inline bool operator!=( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs );
805 
806 template< typename Type >
807 std::ostream& operator<<( std::ostream& os, const Quaternion<Type>& q );
808 
809 template< typename Type >
810 std::istream& operator>>( std::istream& is, Quaternion<Type>& q );
811 
812 template< typename Type >
813 inline bool isnan( const Quaternion<Type>& q );
814 
815 template< typename Type >
816 inline void reset( Quaternion<Type>& q );
817 
818 template< typename Type >
819 inline void clear( Quaternion<Type>& q );
820 
821 template< typename Type >
822 inline bool isDefault( const Quaternion<Type>& q );
823 
824 template< typename Type >
825 inline const Quaternion<Type> inv( const Quaternion<Type>& m );
826 
827 template< typename Type >
828 inline const Quaternion<Type> sq( const Quaternion<Type>& m );
829 
830 template< typename Type >
831 inline void swap( Quaternion<Type>& a, Quaternion<Type>& b ) /* throw() */;
833 //*************************************************************************************************
834 
835 
836 //*************************************************************************************************
844 template< typename T1 // Data type of the left-hand side quaternion
845  , typename T2 > // Data type of the right-hand side quaternion
846 inline bool operator==( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs )
847 {
848  // In order to compare the two quaternions, the data values of the lower-order data
849  // type are converted to the higher-order data type within the equal function.
850  if( !equal( lhs[0], rhs[0] ) ||
851  !equal( lhs[1], rhs[1] ) ||
852  !equal( lhs[2], rhs[2] ) ||
853  !equal( lhs[2], rhs[2] ) )
854  return false;
855  else return true;
856 }
857 //*************************************************************************************************
858 
859 
860 //*************************************************************************************************
868 template< typename T1 // Data type of the left-hand side quaternion
869  , typename T2 > // Data type of the right-hand side quaternion
870 inline bool operator!=( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs )
871 {
872  return !( lhs == rhs );
873 }
874 //*************************************************************************************************
875 
876 
877 //*************************************************************************************************
885 template< typename Type > // Data type of the quaternion
886 std::ostream& operator<<( std::ostream& os, const Quaternion<Type>& q )
887 {
888  return os << "<" << q[0] << "," << q[1] << "," << q[2] << "," << q[3] << ">";
889 }
890 //*************************************************************************************************
891 
892 
893 //*************************************************************************************************
901 template< typename Type > // Data type of the quaternion
902 std::istream& operator>>( std::istream& is, Quaternion<Type>& q )
903 {
904  if( !is ) return is;
905 
906  char bracket1, bracket2, comma1, comma2, comma3;
907  Type r(0), i(0), j(0), k(0);
908  const std::istream::pos_type pos( is.tellg() );
909  const std::istream::fmtflags oldFlags( is.flags() );
910 
911  // Setting the 'skip whitespaces' flag
912  is >> std::skipws;
913 
914  // Extracting the quaternion
915  if( !(is >> bracket1 >> r >> comma1 >> i >> comma2 >> j >> comma3 >> k >> bracket2) ||
916  bracket1 != '<' || comma1 != ',' || comma2 != ',' || comma3 != ',' || bracket2 != '>' ) {
917  is.clear();
918  is.seekg( pos );
919  is.setstate( std::istream::failbit );
920  is.flags( oldFlags );
921  return is;
922  }
923 
924  // Transfering the input to the quaternion values
925  q.set( r, i, j, k );
926 
927  // Resetting the flags
928  is.flags( oldFlags );
929 
930  return is;
931 }
932 //*************************************************************************************************
933 
934 
935 //*************************************************************************************************
942 template< typename Type > // Data type of the quaternion
943 inline bool isnan( const Quaternion<Type>& q )
944 {
945  if( isnan( q[0] ) || isnan( q[1] ) || isnan( q[2] ) || isnan( q[3] ) )
946  return true;
947  else return false;
948 }
949 //*************************************************************************************************
950 
951 
952 //*************************************************************************************************
959 template< typename Type > // Data type of the quaternion
960 inline void reset( Quaternion<Type>& q )
961 {
962  q.reset();
963 }
964 //*************************************************************************************************
965 
966 
967 //*************************************************************************************************
976 template< typename Type > // Data type of the quaternion
977 inline void clear( Quaternion<Type>& q )
978 {
979  q.reset();
980 }
981 //*************************************************************************************************
982 
983 
984 //*************************************************************************************************
998 template< typename Type > // Data type of the quaternion
999 inline bool isDefault( const Quaternion<Type>& q )
1000 {
1001  return ( q[0] == Type(1) ) && ( q[1] == Type(0) ) && ( q[2] == Type(0) ) && ( q[3] == Type(0) );
1002 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1015 template< typename Type > // Data type of the quaternion
1016 inline const Quaternion<Type> inv( const Quaternion<Type>& q )
1017 {
1018  return Quaternion<Type>( q[0], -q[1], -q[2], -q[3] );
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1033 template< typename Type > // Data type of the quaternion
1034 inline const Quaternion<Type> sq( const Quaternion<Type>& q )
1035 {
1036  return q * q;
1037 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1050 template< typename Type > // Data type of the quaternions
1051 inline void swap( Quaternion<Type>& a, Quaternion<Type>& b ) /* throw() */
1052 {
1053  a.swap( b );
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 
1059 
1060 //=================================================================================================
1061 //
1062 // GLOBAL ARITHMETIC OPERATORS
1063 //
1064 //=================================================================================================
1065 
1066 //*************************************************************************************************
1069 template< typename T1, typename T2 >
1070 inline const Quaternion< typename MultTrait<T1,T2>::Type >
1071  operator*( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs );
1073 //*************************************************************************************************
1074 
1075 
1076 //*************************************************************************************************
1085 template< typename T1 // Data type of the left-hand side quaternion
1086  , typename T2 > // Data type of the right-hand side quaternion
1087 inline const Quaternion< typename MultTrait<T1,T2>::Type >
1088  operator*( const Quaternion<T1>& lhs, const Quaternion<T2>& rhs )
1089 {
1090  typedef typename MultTrait<T1,T2>::Type MT;
1091 
1092  const MT r( lhs[0]*rhs[0] - lhs[1]*rhs[1] - lhs[2]*rhs[2] - lhs[3]*rhs[3] );
1093  const MT i( lhs[0]*rhs[1] + lhs[1]*rhs[0] + lhs[2]*rhs[3] - lhs[3]*rhs[2] );
1094  const MT j( lhs[0]*rhs[2] + lhs[2]*rhs[0] + lhs[3]*rhs[1] - lhs[1]*rhs[3] );
1095  const MT k( lhs[0]*rhs[3] + lhs[3]*rhs[0] + lhs[1]*rhs[2] - lhs[2]*rhs[1] );
1096 
1097  const MT len2( r*r + i*i + j*j + k*k );
1098 
1099  if( std::fabs( len2 - MT(1) ) < MT(1E-8) ) {
1100  return Quaternion<MT>( r, i, j, k );
1101  }
1102  else {
1103  const MT ilen( MT(1) / std::sqrt( len2 ) );
1104  return Quaternion<MT>( r*ilen, i*ilen, j*ilen, k*ilen );
1105  }
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 
1111 
1112 //=================================================================================================
1113 //
1114 // MULTTRAIT SPECIALIZATIONS
1115 //
1116 //=================================================================================================
1117 
1118 //*************************************************************************************************
1120 template< typename T1, typename T2 >
1121 struct MultTrait< Quaternion<T1>, Quaternion<T2> >
1122 {
1123  typedef Quaternion< typename MultTrait<T1,T2>::Type > MultType;
1124 };
1126 //*************************************************************************************************
1127 
1128 
1129 
1130 
1131 //=================================================================================================
1132 //
1133 // MATHTRAIT SPECIALIZATIONS
1134 //
1135 //=================================================================================================
1136 
1137 //*************************************************************************************************
1139 template< typename T1, typename T2 >
1140 struct MathTrait< Quaternion<T1>, Quaternion<T2> >
1141 {
1142  typedef Quaternion< typename MathTrait<T1,T2>::HighType > HighType;
1143  typedef Quaternion< typename MathTrait<T1,T2>::LowType > LowType;
1144 };
1146 //*************************************************************************************************
1147 
1148 
1149 
1150 
1151 //=================================================================================================
1152 //
1153 // TYPE DEFINITIONS
1154 //
1155 //=================================================================================================
1156 
1157 //*************************************************************************************************
1162 //*************************************************************************************************
1163 
1164 } // namespace blaze
1165 
1166 #endif
Header file for the isnan shim.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
Quaternion & normalize()
Normalization of the quaternion ( ).
Definition: Quaternion.h:509
Computation accuracy for floating point data types.
const StaticVector< typename MultTrait< Type, Other >::Type, 3UL, false > rotate(const StaticVector< Other, 3UL, TF > &v) const
Rotation of a vector v ( ).
Definition: Quaternion.h:691
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:4075
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4622
Efficient, generic implementation of a 3x3 rotation matrix.The RotationMatrix class is the representa...
Definition: Forward.h:57
const Quaternion< Type > sq(const Quaternion< Type > &m)
Squaring the given quaternion.
Definition: Quaternion.h:1034
Type v_[4]
The four statically allocated quaternion elements.
Definition: Quaternion.h:187
Type length() const
Calculation of the quaternion length .
Definition: Quaternion.h:494
Type ElementType
Type of the quaternion elements.
Definition: Quaternion.h:107
const StaticMatrix< typename MultTrait< Type, Other >::Type, 3UL, 3UL, false > diagRotate(const StaticMatrix< Other, 3UL, 3UL, false > &m) const
Rotation of a diagonal matrix M ( ).
Definition: RotationMatrix.h:808
const RotationMatrix< Type > toRotationMatrix() const
Conversion to a rotation matrix.
Definition: Quaternion.h:570
const StaticMatrix< Type, 3UL, 3UL, false > fabs(const RotationMatrix< Type > &m)
Returns a matrix containing the absolute values of each single element of m.
Definition: RotationMatrix.h:1102
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:116
bool isnan(const DenseMatrix< MT, SO > &dm)
Checks the given dense matrix for not-a-number elements.
Definition: DenseMatrix.h:637
void reset()
Reset to the default initial values.
Definition: Quaternion.h:480
void clear(DynamicMatrix< Type, SO > &m)
Clearing the given dense matrix.
Definition: DynamicMatrix.h:4595
Base template for the MathTrait class.
Definition: MathTrait.h:127
Efficient implementation of a fixed-sized vector.The StaticVector class template is the representatio...
Definition: Forward.h:51
void swap(Quaternion &q)
Swapping the contents of two quaternions.
Definition: Quaternion.h:659
Header file for the floating point precision of the Blaze library.
Header file for the multiplication trait.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two sparse matrices.
Definition: CompressedMatrix.h:4558
Header file for all forward declarations of the math module.
std::istream & operator>>(std::istream &is, Quaternion< Type > &q)
Global input operator for quaternions.
Definition: Quaternion.h:902
Efficient implementation of a fixed-sized matrix.The StaticMatrix class template is the representatio...
Definition: Forward.h:50
Quaternion & set(Type r, Type i, Type j, Type k)
Setting the value of the quaternion elements.
Definition: Quaternion.h:455
Constraint on the data type.
const Quaternion getNormalized() const
Calculation of the normalized quaternion ( ).
Definition: Quaternion.h:534
void rotateY(Type angle)
Rotating the quaternion around the global y-axis by angle degrees (radian measure).
Definition: Quaternion.h:614
MathTrait< Type, Other >::HighType calcAngle(const StaticVector< Other, 3UL, false > &axis) const
Returns the angle in radian measure between the quaterion and a given axis.
Definition: Quaternion.h:775
Quaternion & invert()
Inversion of the quaternion ( ).
Definition: Quaternion.h:554
Header file for the equal shim.
Type operator[](size_t index) const
Subscript operator for the direct access to the quaternion elements.
Definition: Quaternion.h:430
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
bool equal(const T1 &a, const T2 &b)
Generic equality check.
Definition: Equal.h:352
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b)
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:4651
Constraint on the data type.
Efficient implementation of a quaternion.Quaternions are a superior way to deal with rotations and or...
Definition: Forward.h:56
Constraint on the data type.
Header file for the isDefault shim.
Quaternion< real > Quat
Quaternion of real type.
Definition: Quaternion.h:1161
double real
Floating point data type of the Blaze library.This type definition offers the possibility to switch t...
Definition: Precision.h:47
Header file for the mathematical trait.
void rotateZ(Type angle)
Rotating the quaternion around the global z-axis by angle degrees (radian measure).
Definition: Quaternion.h:636
const Accuracy accuracy
Global Accuracy instance.The blaze::accuracy instance can be used wherever a floating point data type...
Definition: Accuracy.h:901
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
Header file for basic type definitions.
void rotateX(Type angle)
Rotating the quaternion around the global x-axis by angle degrees (radian measure).
Definition: Quaternion.h:592
Quaternion()
The default constructor for Quaternion.
Definition: Quaternion.h:224
const StaticMatrix< typename MultTrait< Type, Other >::Type, 3UL, 3UL, false > rotate(const StaticMatrix< Other, 3UL, 3UL, false > &m) const
Rotation of a matrix M ( ).
Definition: RotationMatrix.h:744
#define BLAZE_CONSTRAINT_MUST_BE_FLOATING_POINT_TYPE(T)
Constraint on the data type.In case the given data type T is not a floating point data type...
Definition: FloatingPoint.h:79
const StaticMatrix< typename MultTrait< Type, Other >::Type, 3UL, 3UL, false > diagRotate(const StaticMatrix< Other, 3UL, 3UL, false > &m) const
Rotation of a diagonal matrix.
Definition: Quaternion.h:757
const Quaternion< Type > inv(const Quaternion< Type > &m)
Inverting the given quaternion ( ).
Definition: Quaternion.h:1016