1 #ifndef BOOST_QVM_MAT_OPERATIONS_HPP_INCLUDED
2 #define BOOST_QVM_MAT_OPERATIONS_HPP_INCLUDED
4 // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
5 // Copyright 2019 agate-pris
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
10 #include <boost/qvm/detail/mat_assign.hpp>
11 #include <boost/qvm/mat_operations2.hpp>
12 #include <boost/qvm/mat_operations3.hpp>
13 #include <boost/qvm/mat_operations4.hpp>
14 #include <boost/qvm/math.hpp>
15 #include <boost/qvm/detail/determinant_impl.hpp>
16 #include <boost/qvm/detail/cofactor_impl.hpp>
17 #include <boost/qvm/detail/transp_impl.hpp>
18 #include <boost/qvm/scalar_traits.hpp>
21 namespace boost { namespace qvm {
26 BOOST_QVM_INLINE_CRITICAL
28 get_valid_ptr_mat_operations()
30 static int const obj=0;
35 ////////////////////////////////////////////////
41 std::string to_string( T const & x );
47 template <int R,int C>
51 static bool const value=false;
54 template <int I,int SizeMinusOne>
56 to_string_matrix_elements
63 using namespace qvm_to_string_detail;
65 ( (I%mat_traits<A>::cols)==0 ? '(' : ',' ) +
66 to_string(mat_traits<A>::template read_element<I/mat_traits<A>::cols,I%mat_traits<A>::cols>(a)) +
67 ( (I%mat_traits<A>::cols)==mat_traits<A>::cols-1 ? ")" : "" ) +
68 to_string_matrix_elements<I+1,SizeMinusOne>::f(a);
72 template <int SizeMinusOne>
74 to_string_matrix_elements<SizeMinusOne,SizeMinusOne>
81 using namespace qvm_to_string_detail;
83 ( (SizeMinusOne%mat_traits<A>::cols)==0 ? '(' : ',' ) +
84 to_string(mat_traits<A>::template read_element<SizeMinusOne/mat_traits<A>::cols,SizeMinusOne%mat_traits<A>::cols>(a)) +
94 !qvm_detail::to_string_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
96 to_string( A const & a )
98 return "("+qvm_detail::to_string_matrix_elements<0,mat_traits<A>::rows*mat_traits<A>::cols-1>::f(a)+')';
101 ////////////////////////////////////////////////
103 template <class A,class B,class Cmp>
104 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
105 typename enable_if_c<
106 is_mat<A>::value && is_mat<B>::value &&
107 mat_traits<A>::rows==mat_traits<B>::rows &&
108 mat_traits<A>::cols==mat_traits<B>::cols,
110 cmp( A const & a, B const & b, Cmp f )
112 for( int i=0; i!=mat_traits<A>::rows; ++i )
113 for( int j=0; j!=mat_traits<A>::cols; ++j )
115 mat_traits<A>::read_element_idx(i, j, a),
116 mat_traits<B>::read_element_idx(i, j, b)) )
121 ////////////////////////////////////////////////
126 template <int M,int N>
130 static bool const value=false;
134 template <class R,class A>
135 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
136 typename enable_if_c<
137 is_mat<R>::value && is_mat<A>::value &&
138 mat_traits<R>::rows==mat_traits<A>::rows &&
139 mat_traits<R>::cols==mat_traits<A>::cols &&
140 !qvm_detail::convert_to_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
142 convert_to( A const & a )
148 ////////////////////////////////////////////////
157 static bool const value=false;
162 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
163 typename enable_if_c<
165 mat_traits<A>::rows==mat_traits<A>::cols &&
166 !qvm_detail::determinant_defined<mat_traits<A>::rows>::value,
167 typename mat_traits<A>::scalar_type>::type
168 determinant( A const & a )
170 return qvm_detail::determinant_impl(a);
173 ////////////////////////////////////////////////
178 template <class T,int Dim>
182 identity_mat_( identity_mat_ const & );
183 identity_mat_ & operator=( identity_mat_ const & );
189 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
199 template <class T,int Dim>
201 mat_traits< qvm_detail::identity_mat_<T,Dim> >
203 typedef qvm_detail::identity_mat_<T,Dim> this_matrix;
204 typedef T scalar_type;
205 static int const rows=Dim;
206 static int const cols=Dim;
208 template <int Row,int Col>
210 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
212 read_element( this_matrix const & /*x*/ )
214 BOOST_QVM_STATIC_ASSERT(Row>=0);
215 BOOST_QVM_STATIC_ASSERT(Row<Dim);
216 BOOST_QVM_STATIC_ASSERT(Col>=0);
217 BOOST_QVM_STATIC_ASSERT(Col<Dim);
218 return scalar_traits<scalar_type>::value(Row==Col);
222 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
224 read_element_idx( int row, int col, this_matrix const & /*x*/ )
226 BOOST_QVM_ASSERT(row>=0);
227 BOOST_QVM_ASSERT(row<Dim);
228 BOOST_QVM_ASSERT(col>=0);
229 BOOST_QVM_ASSERT(col<Dim);
230 return scalar_traits<scalar_type>::value(row==col);
234 template <class T,int Dim>
235 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
236 qvm_detail::identity_mat_<T,Dim> const &
239 return *(qvm_detail::identity_mat_<T,Dim> const *)qvm_detail::get_valid_ptr_mat_operations();
243 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
244 typename enable_if_c<
246 mat_traits<A>::rows==mat_traits<A>::cols,
248 set_identity( A & a )
250 assign(a,identity_mat<typename mat_traits<A>::scalar_type,mat_traits<A>::rows>());
253 ////////////////////////////////////////////////
268 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
269 projection_( T _00, T _11, T _22, T _23, T _32 ):
279 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
288 template <int Row,int Col>
294 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
296 get( projection_<T> const & )
298 return scalar_traits<T>::value(0);
302 template <> struct projection_get<0,0> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._00; } };
303 template <> struct projection_get<1,1> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._11; } };
304 template <> struct projection_get<2,2> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._22; } };
305 template <> struct projection_get<2,3> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._23; } };
306 template <> struct projection_get<3,2> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._32; } };
311 mat_traits< qvm_detail::projection_<T> >
313 typedef qvm_detail::projection_<T> this_matrix;
314 typedef T scalar_type;
315 static int const rows=4;
316 static int const cols=4;
318 template <int Row,int Col>
320 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
322 read_element( this_matrix const & x )
324 BOOST_QVM_STATIC_ASSERT(Row>=0);
325 BOOST_QVM_STATIC_ASSERT(Row<rows);
326 BOOST_QVM_STATIC_ASSERT(Col>=0);
327 BOOST_QVM_STATIC_ASSERT(Col<cols);
328 return qvm_detail::projection_get<Row,Col>::get(x);
333 qvm_detail::projection_<T>
334 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
335 perspective_lh( T fov_y, T aspect_ratio, T z_near, T z_far )
337 T const one = scalar_traits<T>::value(1);
338 T const ys = one/tan(fov_y/scalar_traits<T>::value(2));
339 T const xs = ys/aspect_ratio;
340 T const zd = z_far-z_near;
341 T const z1 = z_far/zd;
342 T const z2 = -z_near*z1;
343 return qvm_detail::projection_<T>(xs,ys,z1,z2,one);
347 qvm_detail::projection_<T>
348 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
349 perspective_rh( T fov_y, T aspect_ratio, T z_near, T z_far )
351 T const one = scalar_traits<T>::value(1);
352 T const ys = one/tan(fov_y/scalar_traits<T>::value(2));
353 T const xs = ys/aspect_ratio;
354 T const zd = z_near-z_far;
355 T const z1 = z_far/zd;
356 T const z2 = z_near*z1;
357 return qvm_detail::projection_<T>(xs,ys,z1,z2,-one);
360 ////////////////////////////////////////////////
365 template <class OriginalType,class Scalar>
369 matrix_scalar_cast_( matrix_scalar_cast_ const & );
370 matrix_scalar_cast_ & operator=( matrix_scalar_cast_ const & );
371 ~matrix_scalar_cast_();
376 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
377 matrix_scalar_cast_ &
378 operator=( T const & x )
385 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
394 template <bool> struct scalar_cast_matrix_filter { };
395 template <> struct scalar_cast_matrix_filter<true> { typedef int type; };
398 template <class OriginalType,class Scalar>
400 mat_traits< qvm_detail::matrix_scalar_cast_<OriginalType,Scalar> >
402 typedef Scalar scalar_type;
403 typedef qvm_detail::matrix_scalar_cast_<OriginalType,Scalar> this_matrix;
404 static int const rows=mat_traits<OriginalType>::rows;
405 static int const cols=mat_traits<OriginalType>::cols;
407 template <int Row,int Col>
409 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
411 read_element( this_matrix const & x )
413 BOOST_QVM_STATIC_ASSERT(Row>=0);
414 BOOST_QVM_STATIC_ASSERT(Row<rows);
415 BOOST_QVM_STATIC_ASSERT(Col>=0);
416 BOOST_QVM_STATIC_ASSERT(Col<cols);
417 return scalar_type(mat_traits<OriginalType>::template read_element<Row,Col>(reinterpret_cast<OriginalType const &>(x)));
421 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
423 read_element_idx( int row, int col, this_matrix const & x )
425 BOOST_QVM_ASSERT(row>=0);
426 BOOST_QVM_ASSERT(row<rows);
427 BOOST_QVM_ASSERT(col>=0);
428 BOOST_QVM_ASSERT(col<cols);
429 return scalar_type(mat_traits<OriginalType>::read_element_idx(col,row,reinterpret_cast<OriginalType const &>(x)));
433 template <class OriginalType,class Scalar,int R,int C>
435 deduce_mat<qvm_detail::matrix_scalar_cast_<OriginalType,Scalar>,R,C>
437 typedef mat<Scalar,R,C> type;
440 template <class Scalar,class T>
441 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
442 qvm_detail::matrix_scalar_cast_<T,Scalar> const &
443 scalar_cast( T const & x, typename qvm_detail::scalar_cast_matrix_filter<is_mat<T>::value>::type=0 )
445 return reinterpret_cast<qvm_detail::matrix_scalar_cast_<T,Scalar> const &>(x);
448 ////////////////////////////////////////////////
453 template <int M,int N>
457 static bool const value=false;
461 template <class A,class B>
462 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
463 typename enable_if_c<
464 is_mat<A>::value && is_scalar<B>::value &&
465 !qvm_detail::div_eq_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
467 operator/=( A & a, B b )
469 for( int i=0; i!=mat_traits<A>::rows; ++i )
470 for( int j=0; j!=mat_traits<A>::cols; ++j )
471 mat_traits<A>::write_element_idx(i,j,a)/=b;
475 ////////////////////////////////////////////////
480 template <int M,int N>
484 static bool const value=false;
488 template <class A,class B>
489 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
490 typename lazy_enable_if_c<
491 is_mat<A>::value && is_scalar<B>::value &&
492 !qvm_detail::div_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
493 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
494 operator/( A const & a, B b )
496 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
498 for( int i=0; i!=mat_traits<A>::rows; ++i )
499 for( int j=0; j!=mat_traits<A>::cols; ++j )
500 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)/b;
504 ////////////////////////////////////////////////
509 template <int M,int N>
513 static bool const value=false;
517 template <class A,class B>
518 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
519 typename enable_if_c<
520 is_mat<A>::value && is_mat<B>::value &&
521 mat_traits<A>::rows==mat_traits<B>::rows &&
522 mat_traits<A>::cols==mat_traits<B>::cols &&
523 !qvm_detail::eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
525 operator==( A const & a, B const & b )
527 for( int i=0; i!=mat_traits<A>::rows; ++i )
528 for( int j=0; j!=mat_traits<A>::cols; ++j )
529 if( mat_traits<A>::read_element_idx(i,j,a)!=mat_traits<B>::read_element_idx(i,j,b) )
534 ////////////////////////////////////////////////
539 template <int M,int N>
543 static bool const value=false;
547 template <class A,class B>
548 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
549 typename enable_if_c<
550 is_mat<A>::value && is_mat<B>::value &&
551 mat_traits<A>::rows==mat_traits<B>::rows &&
552 mat_traits<A>::cols==mat_traits<B>::cols &&
553 !qvm_detail::minus_eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
555 operator-=( A & a, B const & b )
557 for( int i=0; i!=mat_traits<A>::rows; ++i )
558 for( int j=0; j!=mat_traits<A>::cols; ++j )
559 mat_traits<A>::write_element_idx(i,j,a)-=mat_traits<B>::read_element_idx(i,j,b);
563 ////////////////////////////////////////////////
568 template <int M,int N>
572 static bool const value=false;
577 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
578 typename lazy_enable_if_c<
580 !qvm_detail::minus_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
581 deduce_mat<A> >::type
582 operator-( A const & a )
584 typedef typename deduce_mat<A>::type R;
586 for( int i=0; i!=mat_traits<A>::rows; ++i )
587 for( int j=0; j!=mat_traits<A>::cols; ++j )
588 mat_traits<R>::write_element_idx(i,j,r)=-mat_traits<A>::read_element_idx(i,j,a);
592 ////////////////////////////////////////////////
597 template <int M,int N>
601 static bool const value=false;
605 template <class A,class B>
606 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
607 typename lazy_enable_if_c<
608 is_mat<A>::value && is_mat<B>::value &&
609 mat_traits<A>::rows==mat_traits<B>::rows &&
610 mat_traits<A>::cols==mat_traits<B>::cols &&
611 !qvm_detail::minus_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
612 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
613 operator-( A const & a, B const & b )
615 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
617 for( int i=0; i!=mat_traits<A>::rows; ++i )
618 for( int j=0; j!=mat_traits<A>::cols; ++j )
619 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)-mat_traits<B>::read_element_idx(i,j,b);
623 ////////////////////////////////////////////////
632 static bool const value=false;
636 template <class A,class B>
637 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
638 typename enable_if_c<
641 mat_traits<A>::rows==mat_traits<A>::cols &&
642 mat_traits<A>::rows==mat_traits<B>::rows &&
643 mat_traits<A>::cols==mat_traits<B>::cols &&
644 !qvm_detail::mul_eq_mm_defined<mat_traits<A>::rows>::value,
646 operator*=( A & r, B const & b )
648 typedef typename mat_traits<A>::scalar_type Ta;
649 Ta a[mat_traits<A>::rows][mat_traits<A>::cols];
650 for( int i=0; i<mat_traits<A>::rows; ++i )
651 for( int j=0; j<mat_traits<B>::cols; ++j )
652 a[i][j]=mat_traits<A>::read_element_idx(i,j,r);
653 for( int i=0; i<mat_traits<A>::rows; ++i )
654 for( int j=0; j<mat_traits<B>::cols; ++j )
656 Ta x(scalar_traits<Ta>::value(0));
657 for( int k=0; k<mat_traits<A>::cols; ++k )
658 x += a[i][k]*mat_traits<B>::read_element_idx(k,j,b);
659 mat_traits<A>::write_element_idx(i,j,r) = x;
664 ////////////////////////////////////////////////
669 template <int M,int N>
673 static bool const value=false;
677 template <class A,class B>
678 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
679 typename enable_if_c<
680 is_mat<A>::value && is_scalar<B>::value &&
681 !qvm_detail::mul_eq_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
683 operator*=( A & a, B b )
685 for( int i=0; i!=mat_traits<A>::rows; ++i )
686 for( int j=0; j!=mat_traits<A>::cols; ++j )
687 mat_traits<A>::write_element_idx(i,j,a)*=b;
691 ////////////////////////////////////////////////
696 template <int R,int /*CR*/,int C>
700 static bool const value=false;
704 template <class A,class B>
705 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
706 typename lazy_enable_if_c<
707 is_mat<A>::value && is_mat<B>::value &&
708 mat_traits<A>::cols==mat_traits<B>::rows &&
709 !qvm_detail::mul_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols,mat_traits<B>::cols>::value,
710 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<B>::cols> >::type
711 operator*( A const & a, B const & b )
713 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<B>::cols>::type R;
715 for( int i=0; i<mat_traits<A>::rows; ++i )
716 for( int j=0; j<mat_traits<B>::cols; ++j )
718 typedef typename mat_traits<A>::scalar_type Ta;
719 Ta x(scalar_traits<Ta>::value(0));
720 for( int k=0; k<mat_traits<A>::cols; ++k )
721 x += mat_traits<A>::read_element_idx(i,k,a)*mat_traits<B>::read_element_idx(k,j,b);
722 mat_traits<R>::write_element_idx(i,j,r) = x;
727 ////////////////////////////////////////////////
732 template <int M,int N>
736 static bool const value=false;
740 template <class A,class B>
741 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
742 typename lazy_enable_if_c<
743 is_mat<A>::value && is_scalar<B>::value &&
744 !qvm_detail::mul_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
745 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
746 operator*( A const & a, B b )
748 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
750 for( int i=0; i!=mat_traits<A>::rows; ++i )
751 for( int j=0; j!=mat_traits<A>::cols; ++j )
752 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)*b;
756 ////////////////////////////////////////////////
761 template <int M,int N>
765 static bool const value=false;
769 template <class A,class B>
770 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
771 typename lazy_enable_if_c<
772 is_scalar<A>::value && is_mat<B>::value &&
773 !qvm_detail::mul_sm_defined<mat_traits<B>::rows,mat_traits<B>::cols>::value,
774 deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols> >::type
775 operator*( A a, B const & b )
777 typedef typename deduce_mat2<A,B,mat_traits<B>::rows,mat_traits<B>::cols>::type R;
779 for( int i=0; i!=mat_traits<B>::rows; ++i )
780 for( int j=0; j!=mat_traits<B>::cols; ++j )
781 mat_traits<R>::write_element_idx(i,j,r)=a*mat_traits<B>::read_element_idx(i,j,b);
785 ////////////////////////////////////////////////
790 template <int M,int N>
794 static bool const value=false;
798 template <class A,class B>
799 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
800 typename enable_if_c<
801 is_mat<A>::value && is_mat<B>::value &&
802 mat_traits<A>::rows==mat_traits<B>::rows &&
803 mat_traits<A>::cols==mat_traits<B>::cols &&
804 !qvm_detail::neq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
806 operator!=( A const & a, B const & b )
808 for( int i=0; i!=mat_traits<A>::rows; ++i )
809 for( int j=0; j!=mat_traits<A>::cols; ++j )
810 if( mat_traits<A>::read_element_idx(i,j,a)!=mat_traits<B>::read_element_idx(i,j,b) )
815 ////////////////////////////////////////////////
820 template <int M,int N>
824 static bool const value=false;
828 template <class A,class B>
829 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
830 typename enable_if_c<
831 is_mat<A>::value && is_mat<B>::value &&
832 mat_traits<A>::rows==mat_traits<B>::rows &&
833 mat_traits<A>::cols==mat_traits<B>::cols &&
834 !qvm_detail::plus_eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
836 operator+=( A & a, B const & b )
838 for( int i=0; i!=mat_traits<A>::rows; ++i )
839 for( int j=0; j!=mat_traits<A>::cols; ++j )
840 mat_traits<A>::write_element_idx(i,j,a)+=mat_traits<B>::read_element_idx(i,j,b);
844 ////////////////////////////////////////////////
849 template <int M,int N>
853 static bool const value=false;
857 template <class A,class B>
858 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
859 typename lazy_enable_if_c<
860 is_mat<A>::value && is_mat<B>::value &&
861 mat_traits<A>::rows==mat_traits<B>::rows &&
862 mat_traits<A>::cols==mat_traits<B>::cols &&
863 !qvm_detail::plus_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
864 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
865 operator+( A const & a, B const & b )
867 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;
869 for( int i=0; i!=mat_traits<A>::rows; ++i )
870 for( int j=0; j!=mat_traits<A>::cols; ++j )
871 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)+mat_traits<B>::read_element_idx(i,j,b);
875 ////////////////////////////////////////////////
884 mref_( mref_ const & );
885 mref_ & operator=( mref_ const & );
891 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
893 operator=( R const & x )
900 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
912 mat_traits< qvm_detail::mref_<M> >
914 typedef typename mat_traits<M>::scalar_type scalar_type;
915 typedef qvm_detail::mref_<M> this_matrix;
916 static int const rows=mat_traits<M>::rows;
917 static int const cols=mat_traits<M>::cols;
919 template <int Row,int Col>
921 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
923 read_element( this_matrix const & x )
925 BOOST_QVM_STATIC_ASSERT(Row>=0);
926 BOOST_QVM_STATIC_ASSERT(Row<rows);
927 BOOST_QVM_STATIC_ASSERT(Col>=0);
928 BOOST_QVM_STATIC_ASSERT(Col<cols);
929 return mat_traits<M>::template read_element<Row,Col>(reinterpret_cast<M const &>(x));
932 template <int Row,int Col>
934 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
936 write_element( this_matrix & x )
938 BOOST_QVM_STATIC_ASSERT(Row>=0);
939 BOOST_QVM_STATIC_ASSERT(Row<rows);
940 BOOST_QVM_STATIC_ASSERT(Col>=0);
941 BOOST_QVM_STATIC_ASSERT(Col<cols);
942 return mat_traits<M>::template write_element<Row,Col>(reinterpret_cast<M &>(x));
946 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
948 read_element_idx( int row, int col, this_matrix const & x )
950 BOOST_QVM_ASSERT(row>=0);
951 BOOST_QVM_ASSERT(row<rows);
952 BOOST_QVM_ASSERT(col>=0);
953 BOOST_QVM_ASSERT(col<cols);
954 return mat_traits<M>::read_element_idx(row,col,reinterpret_cast<M const &>(x));
958 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
960 write_element_idx( int row, int col, this_matrix & x )
962 BOOST_QVM_ASSERT(row>=0);
963 BOOST_QVM_ASSERT(row<rows);
964 BOOST_QVM_ASSERT(col>=0);
965 BOOST_QVM_ASSERT(col<cols);
966 return mat_traits<M>::write_element_idx(row,col,reinterpret_cast<M &>(x));
970 template <class M,int R,int C>
972 deduce_mat<qvm_detail::mref_<M>,R,C>
974 typedef mat<typename mat_traits<M>::scalar_type,R,C> type;
978 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
979 typename enable_if_c<
981 qvm_detail::mref_<M> const &>::type
984 return reinterpret_cast<qvm_detail::mref_<M> const &>(a);
988 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
989 typename enable_if_c<
991 qvm_detail::mref_<M> &>::type
994 return reinterpret_cast<qvm_detail::mref_<M> &>(a);
997 ////////////////////////////////////////////////
1002 template <class T,int Rows,int Cols>
1006 zero_mat_( zero_mat_ const & );
1007 zero_mat_ & operator=( zero_mat_ const & );
1013 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1023 template <class T,int Rows,int Cols>
1025 mat_traits< qvm_detail::zero_mat_<T,Rows,Cols> >
1027 typedef qvm_detail::zero_mat_<T,Rows,Cols> this_matrix;
1028 typedef T scalar_type;
1029 static int const rows=Rows;
1030 static int const cols=Cols;
1032 template <int Row,int Col>
1034 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1036 read_element( this_matrix const & )
1038 BOOST_QVM_STATIC_ASSERT(Row>=0);
1039 BOOST_QVM_STATIC_ASSERT(Row<Rows);
1040 BOOST_QVM_STATIC_ASSERT(Col>=0);
1041 BOOST_QVM_STATIC_ASSERT(Col<Cols);
1042 return scalar_traits<scalar_type>::value(0);
1046 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1048 read_element_idx( int row, int col, this_matrix const & )
1050 BOOST_QVM_ASSERT(row>=0);
1051 BOOST_QVM_ASSERT(row<rows);
1052 BOOST_QVM_ASSERT(col>=0);
1053 BOOST_QVM_ASSERT(col<cols);
1054 return scalar_traits<scalar_type>::value(0);
1058 template <class T,int Rows,int Cols,int R,int C>
1060 deduce_mat<qvm_detail::zero_mat_<T,Rows,Cols>,R,C>
1062 typedef mat<T,R,C> type;
1065 template <class T,int Rows,int Cols>
1066 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1067 qvm_detail::zero_mat_<T,Rows,Cols> const &
1070 return *(qvm_detail::zero_mat_<T,Rows,Cols> const *)qvm_detail::get_valid_ptr_mat_operations();
1073 template <class T,int Dim>
1074 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1075 qvm_detail::zero_mat_<T,Dim,Dim> const &
1078 return *(qvm_detail::zero_mat_<T,Dim,Dim> const *)qvm_detail::get_valid_ptr_mat_operations();
1082 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1083 typename enable_if_c<
1088 assign(a,zero_mat<typename mat_traits<A>::scalar_type,mat_traits<A>::rows,mat_traits<A>::cols>());
1091 ////////////////////////////////////////////////
1096 template <int D,class S>
1100 typedef S scalar_type;
1101 scalar_type a[3][3];
1103 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1105 scalar_type a00, scalar_type a01, scalar_type a02,
1106 scalar_type a10, scalar_type a11, scalar_type a12,
1107 scalar_type a20, scalar_type a21, scalar_type a22 )
1121 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1130 template <int Row,int Col>
1136 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1138 get( T const (&)[3][3] )
1140 return scalar_traits<T>::value(Row==Col);
1144 template <> struct rot_m_get<0,0> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][0]; } };
1145 template <> struct rot_m_get<0,1> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][1]; } };
1146 template <> struct rot_m_get<0,2> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][2]; } };
1147 template <> struct rot_m_get<1,0> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][0]; } };
1148 template <> struct rot_m_get<1,1> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][1]; } };
1149 template <> struct rot_m_get<1,2> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][2]; } };
1150 template <> struct rot_m_get<2,0> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][0]; } };
1151 template <> struct rot_m_get<2,1> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][1]; } };
1152 template <> struct rot_m_get<2,2> { template <class T> static BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][2]; } };
1158 template <int D,class S>
1160 mat_traits< qvm_detail::rot_mat_<D,S> >
1162 typedef qvm_detail::rot_mat_<D,S> this_matrix;
1163 typedef typename this_matrix::scalar_type scalar_type;
1164 static int const rows=D;
1165 static int const cols=D;
1167 template <int Row,int Col>
1169 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1171 read_element( this_matrix const & x )
1173 BOOST_QVM_STATIC_ASSERT(Row>=0);
1174 BOOST_QVM_STATIC_ASSERT(Row<D);
1175 BOOST_QVM_STATIC_ASSERT(Col>=0);
1176 BOOST_QVM_STATIC_ASSERT(Col<D);
1177 return qvm_detail::rot_m_get<Row,Col>::get(x.a);
1181 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1183 read_element_idx( int row, int col, this_matrix const & x )
1185 BOOST_QVM_ASSERT(row>=0);
1186 BOOST_QVM_ASSERT(row<D);
1187 BOOST_QVM_ASSERT(col>=0);
1188 BOOST_QVM_ASSERT(col<D);
1189 return row<3 && col<3?
1191 scalar_traits<scalar_type>::value(row==col);
1195 template <int Dim,class V,class Angle>
1196 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1197 typename enable_if_c<
1198 is_vec<V>::value && vec_traits<V>::dim==3,
1199 qvm_detail::rot_mat_<Dim,Angle> >::type
1200 rot_mat( V const & axis, Angle angle )
1202 typedef Angle scalar_type;
1203 scalar_type const x=vec_traits<V>::template read_element<0>(axis);
1204 scalar_type const y=vec_traits<V>::template read_element<1>(axis);
1205 scalar_type const z=vec_traits<V>::template read_element<2>(axis);
1206 scalar_type const m2=x*x+y*y+z*z;
1207 if( m2==scalar_traits<scalar_type>::value(0) )
1208 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
1209 scalar_type const s = sin(angle);
1210 scalar_type const c = cos(angle);
1211 scalar_type const x2 = x*x;
1212 scalar_type const y2 = y*y;
1213 scalar_type const z2 = z*z;
1214 scalar_type const xy = x*y;
1215 scalar_type const xz = x*z;
1216 scalar_type const yz = y*z;
1217 scalar_type const xs = x*s;
1218 scalar_type const ys = y*s;
1219 scalar_type const zs = z*s;
1220 scalar_type const one = scalar_traits<scalar_type>::value(1);
1221 scalar_type const c1 = one-c;
1222 return qvm_detail::rot_mat_<Dim,Angle>(
1223 x2+(one-x2)*c, xy*c1-zs, xz*(one-c)+ys,
1224 xy*c1+zs, y2+(one-y2)*c, yz*c1-xs,
1225 xz*c1-ys, yz*c1+xs, z2+(one-z2)*c );
1228 template <class A,class B,class Angle>
1229 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1230 typename enable_if_c<
1232 mat_traits<A>::rows==mat_traits<A>::cols &&
1233 mat_traits<A>::rows>=3 &&
1234 is_vec<B>::value && vec_traits<B>::dim==3,
1236 set_rot( A & a, B const & axis, Angle angle )
1238 assign(a,rot_mat<mat_traits<A>::rows>(axis,angle));
1241 template <class A,class B,class Angle>
1242 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1243 typename enable_if_c<
1245 mat_traits<A>::rows==mat_traits<A>::cols &&
1246 mat_traits<A>::rows>=3 &&
1247 is_vec<B>::value && vec_traits<B>::dim==3,
1249 rotate( A & a, B const & axis, Angle angle )
1251 a *= rot_mat<mat_traits<A>::rows>(axis,angle);
1254 ////////////////////////////////////////////////
1256 template <int Dim,class Angle>
1257 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1258 qvm_detail::rot_mat_<Dim,Angle>
1259 rot_mat_xzy( Angle x1, Angle z2, Angle y3 )
1261 typedef Angle scalar_type;
1262 scalar_type const c1 = cos(x1);
1263 scalar_type const s1 = sin(x1);
1264 scalar_type const c2 = cos(z2);
1265 scalar_type const s2 = sin(z2);
1266 scalar_type const c3 = cos(y3);
1267 scalar_type const s3 = sin(y3);
1268 return qvm_detail::rot_mat_<Dim,Angle>(
1270 s1*s3 + c1*c3*s2, c1*c2, c1*s2*s3 - c3*s1,
1271 c3*s1*s2 - c1*s3, c2*s1, c1*c3 + s1*s2*s3 );
1274 template <class A,class Angle>
1275 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1276 typename enable_if_c<
1278 mat_traits<A>::rows==mat_traits<A>::cols &&
1279 mat_traits<A>::rows>=3,
1281 set_rot_xzy( A & a, Angle x1, Angle z2, Angle y3 )
1283 assign(a,rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3));
1286 template <class A,class Angle>
1287 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1288 typename enable_if_c<
1290 mat_traits<A>::rows==mat_traits<A>::cols &&
1291 mat_traits<A>::rows>=3,
1293 rotate_xzy( A & a, Angle x1, Angle z2, Angle y3 )
1295 a *= rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3);
1298 ////////////////////////////////////////////////
1300 template <int Dim,class Angle>
1301 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1302 qvm_detail::rot_mat_<Dim,Angle>
1303 rot_mat_xyz( Angle x1, Angle y2, Angle z3 )
1305 typedef Angle scalar_type;
1306 scalar_type const c1 = cos(x1);
1307 scalar_type const s1 = sin(x1);
1308 scalar_type const c2 = cos(y2);
1309 scalar_type const s2 = sin(y2);
1310 scalar_type const c3 = cos(z3);
1311 scalar_type const s3 = sin(z3);
1312 return qvm_detail::rot_mat_<Dim,Angle>(
1314 c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3, -c2*s1,
1315 s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3, c1*c2 );
1318 template <class A,class Angle>
1319 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1320 typename enable_if_c<
1322 mat_traits<A>::rows==mat_traits<A>::cols &&
1323 mat_traits<A>::rows>=3,
1325 set_rot_xyz( A & a, Angle x1, Angle y2, Angle z3 )
1327 assign(a,rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3));
1330 template <class A,class Angle>
1331 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1332 typename enable_if_c<
1334 mat_traits<A>::rows==mat_traits<A>::cols &&
1335 mat_traits<A>::rows>=3,
1337 rotate_xyz( A & a, Angle x1, Angle y2, Angle z3 )
1339 a *= rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3);
1342 ////////////////////////////////////////////////
1344 template <int Dim,class Angle>
1345 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1346 qvm_detail::rot_mat_<Dim,Angle>
1347 rot_mat_yxz( Angle y1, Angle x2, Angle z3 )
1349 typedef Angle scalar_type;
1350 scalar_type const c1 = cos(y1);
1351 scalar_type const s1 = sin(y1);
1352 scalar_type const c2 = cos(x2);
1353 scalar_type const s2 = sin(x2);
1354 scalar_type const c3 = cos(z3);
1355 scalar_type const s3 = sin(z3);
1356 return qvm_detail::rot_mat_<Dim,Angle>(
1357 c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3, c2*s1,
1359 c1*s2*s3 - c3*s1, c1*c3*s2 + s1*s3, c1*c2 );
1362 template <class A,class Angle>
1363 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1364 typename enable_if_c<
1366 mat_traits<A>::rows==mat_traits<A>::cols &&
1367 mat_traits<A>::rows>=3,
1369 set_rot_yxz( A & a, Angle y1, Angle x2, Angle z3 )
1371 assign(a,rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3));
1374 template <class A,class Angle>
1375 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1376 typename enable_if_c<
1378 mat_traits<A>::rows==mat_traits<A>::cols &&
1379 mat_traits<A>::rows>=3,
1381 rotate_yxz( A & a, Angle y1, Angle x2, Angle z3 )
1383 a *= rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3);
1386 ////////////////////////////////////////////////
1388 template <int Dim,class Angle>
1389 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1390 qvm_detail::rot_mat_<Dim,Angle>
1391 rot_mat_yzx( Angle y1, Angle z2, Angle x3 )
1393 typedef Angle scalar_type;
1394 scalar_type const c1 = cos(y1);
1395 scalar_type const s1 = sin(y1);
1396 scalar_type const c2 = cos(z2);
1397 scalar_type const s2 = sin(z2);
1398 scalar_type const c3 = cos(x3);
1399 scalar_type const s3 = sin(x3);
1400 return qvm_detail::rot_mat_<Dim,Angle>(
1401 c1*c2, s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3,
1403 -c2*s1, c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3 );
1406 template <class A,class Angle>
1407 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1408 typename enable_if_c<
1410 mat_traits<A>::rows==mat_traits<A>::cols &&
1411 mat_traits<A>::rows>=3,
1413 set_rot_yzx( A & a, Angle y1, Angle z2, Angle x3 )
1415 assign(a,rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3));
1418 template <class A,class Angle>
1419 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1420 typename enable_if_c<
1422 mat_traits<A>::rows==mat_traits<A>::cols &&
1423 mat_traits<A>::rows>=3,
1425 rotate_yzx( A & a, Angle y1, Angle z2, Angle x3 )
1427 a *= rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3);
1430 ////////////////////////////////////////////////
1432 template <int Dim,class Angle>
1433 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1434 qvm_detail::rot_mat_<Dim,Angle>
1435 rot_mat_zyx( Angle z1, Angle y2, Angle x3 )
1437 typedef Angle scalar_type;
1438 scalar_type const c1 = cos(z1);
1439 scalar_type const s1 = sin(z1);
1440 scalar_type const c2 = cos(y2);
1441 scalar_type const s2 = sin(y2);
1442 scalar_type const c3 = cos(x3);
1443 scalar_type const s3 = sin(x3);
1444 return qvm_detail::rot_mat_<Dim,Angle>(
1445 c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2,
1446 c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3,
1447 -s2, c2*s3, c2*c3 );
1450 template <class A,class Angle>
1451 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1452 typename enable_if_c<
1454 mat_traits<A>::rows==mat_traits<A>::cols &&
1455 mat_traits<A>::rows>=3,
1457 set_rot_zyx( A & a, Angle z1, Angle y2, Angle x3 )
1459 assign(a,rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3));
1462 template <class A,class Angle>
1463 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1464 typename enable_if_c<
1466 mat_traits<A>::rows==mat_traits<A>::cols &&
1467 mat_traits<A>::rows>=3,
1469 rotate_zyx( A & a, Angle z1, Angle y2, Angle x3 )
1471 a *= rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3);
1474 ////////////////////////////////////////////////
1476 template <int Dim,class Angle>
1477 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1478 qvm_detail::rot_mat_<Dim,Angle>
1479 rot_mat_zxy( Angle z1, Angle x2, Angle y3 )
1481 typedef Angle scalar_type;
1482 scalar_type const c1 = cos(z1);
1483 scalar_type const s1 = sin(z1);
1484 scalar_type const c2 = cos(x2);
1485 scalar_type const s2 = sin(x2);
1486 scalar_type const c3 = cos(y3);
1487 scalar_type const s3 = sin(y3);
1488 return qvm_detail::rot_mat_<Dim,Angle>(
1489 c1*c3 - s1*s2*s3, -c2*s1, c1*s3 + c3*s1*s2,
1490 c3*s1 + c1*s2*s3, c1*c2, s1*s3 - c1*c3*s2,
1491 -c2*s3, s2, c2*c3 );
1494 template <class A,class Angle>
1495 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1496 typename enable_if_c<
1498 mat_traits<A>::rows==mat_traits<A>::cols &&
1499 mat_traits<A>::rows>=3,
1501 set_rot_zxy( A & a, Angle z1, Angle x2, Angle y3 )
1503 assign(a,rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3));
1506 template <class A,class Angle>
1507 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1508 typename enable_if_c<
1510 mat_traits<A>::rows==mat_traits<A>::cols &&
1511 mat_traits<A>::rows>=3,
1513 rotate_zxy( A & a, Angle z1, Angle x2, Angle y3 )
1515 a *= rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3);
1518 ////////////////////////////////////////////////
1520 template <int Dim,class Angle>
1521 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1522 qvm_detail::rot_mat_<Dim,Angle>
1523 rot_mat_xzx( Angle x1, Angle z2, Angle x3 )
1525 typedef Angle scalar_type;
1526 scalar_type const c1 = cos(x1);
1527 scalar_type const s1 = sin(x1);
1528 scalar_type const c2 = cos(z2);
1529 scalar_type const s2 = sin(z2);
1530 scalar_type const c3 = cos(x3);
1531 scalar_type const s3 = sin(x3);
1532 return qvm_detail::rot_mat_<Dim,Angle>(
1534 c1*s2, c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3,
1535 s1*s2, c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3 );
1538 template <class A,class Angle>
1539 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1540 typename enable_if_c<
1542 mat_traits<A>::rows==mat_traits<A>::cols &&
1543 mat_traits<A>::rows>=3,
1545 set_rot_xzx( A & a, Angle x1, Angle z2, Angle x3 )
1547 assign(a,rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3));
1550 template <class A,class Angle>
1551 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1552 typename enable_if_c<
1554 mat_traits<A>::rows==mat_traits<A>::cols &&
1555 mat_traits<A>::rows>=3,
1557 rotate_xzx( A & a, Angle x1, Angle z2, Angle x3 )
1559 a *= rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3);
1562 ////////////////////////////////////////////////
1564 template <int Dim,class Angle>
1565 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1566 qvm_detail::rot_mat_<Dim,Angle>
1567 rot_mat_xyx( Angle x1, Angle y2, Angle x3 )
1569 typedef Angle scalar_type;
1570 scalar_type const c1 = cos(x1);
1571 scalar_type const s1 = sin(x1);
1572 scalar_type const c2 = cos(y2);
1573 scalar_type const s2 = sin(y2);
1574 scalar_type const c3 = cos(x3);
1575 scalar_type const s3 = sin(x3);
1576 return qvm_detail::rot_mat_<Dim,Angle>(
1578 s1*s2, c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1,
1579 -c1*s2, c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3 );
1582 template <class A,class Angle>
1583 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1584 typename enable_if_c<
1586 mat_traits<A>::rows==mat_traits<A>::cols &&
1587 mat_traits<A>::rows>=3,
1589 set_rot_xyx( A & a, Angle x1, Angle y2, Angle x3 )
1591 assign(a,rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3));
1594 template <class A,class Angle>
1595 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1596 typename enable_if_c<
1598 mat_traits<A>::rows==mat_traits<A>::cols &&
1599 mat_traits<A>::rows>=3,
1601 rotate_xyx( A & a, Angle x1, Angle y2, Angle x3 )
1603 a *= rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3);
1606 ////////////////////////////////////////////////
1608 template <int Dim,class Angle>
1609 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1610 qvm_detail::rot_mat_<Dim,Angle>
1611 rot_mat_yxy( Angle y1, Angle x2, Angle y3 )
1613 typedef Angle scalar_type;
1614 scalar_type const c1 = cos(y1);
1615 scalar_type const s1 = sin(y1);
1616 scalar_type const c2 = cos(x2);
1617 scalar_type const s2 = sin(x2);
1618 scalar_type const c3 = cos(y3);
1619 scalar_type const s3 = sin(y3);
1620 return qvm_detail::rot_mat_<Dim,Angle>(
1621 c1*c3 - c2*s1*s3, s1*s2, c1*s3 + c2*c3*s1,
1623 -c3*s1 - c1*c2*s3, c1*s2, c1*c2*c3 - s1*s3 );
1626 template <class A,class Angle>
1627 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1628 typename enable_if_c<
1630 mat_traits<A>::rows==mat_traits<A>::cols &&
1631 mat_traits<A>::rows>=3,
1633 set_rot_yxy( A & a, Angle y1, Angle x2, Angle y3 )
1635 assign(a,rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3));
1638 template <class A,class Angle>
1639 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1640 typename enable_if_c<
1642 mat_traits<A>::rows==mat_traits<A>::cols &&
1643 mat_traits<A>::rows>=3,
1645 rotate_yxy( A & a, Angle y1, Angle x2, Angle y3 )
1647 a *= rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3);
1650 ////////////////////////////////////////////////
1652 template <int Dim,class Angle>
1653 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1654 qvm_detail::rot_mat_<Dim,Angle>
1655 rot_mat_yzy( Angle y1, Angle z2, Angle y3 )
1657 typedef Angle scalar_type;
1658 scalar_type const c1 = cos(y1);
1659 scalar_type const s1 = sin(y1);
1660 scalar_type const c2 = cos(z2);
1661 scalar_type const s2 = sin(z2);
1662 scalar_type const c3 = cos(y3);
1663 scalar_type const s3 = sin(y3);
1664 return qvm_detail::rot_mat_<Dim,Angle>(
1665 c1*c2*c3 - s1*s3, -c1*s2, c3*s1 + c1*c2*s3,
1667 -c1*s3 - c2*c3*s1, s1*s2, c1*c3 - c2*s1*s3 );
1670 template <class A,class Angle>
1671 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1672 typename enable_if_c<
1674 mat_traits<A>::rows==mat_traits<A>::cols &&
1675 mat_traits<A>::rows>=3,
1677 set_rot_yzy( A & a, Angle y1, Angle z2, Angle y3 )
1679 assign(a,rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3));
1682 template <class A,class Angle>
1683 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1684 typename enable_if_c<
1686 mat_traits<A>::rows==mat_traits<A>::cols &&
1687 mat_traits<A>::rows>=3,
1689 rotate_yzy( A & a, Angle y1, Angle z2, Angle y3 )
1691 a *= rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3);
1694 ////////////////////////////////////////////////
1696 template <int Dim,class Angle>
1697 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1698 qvm_detail::rot_mat_<Dim,Angle>
1699 rot_mat_zyz( Angle z1, Angle y2, Angle z3 )
1701 typedef Angle scalar_type;
1702 scalar_type const c1 = cos(z1);
1703 scalar_type const s1 = sin(z1);
1704 scalar_type const c2 = cos(y2);
1705 scalar_type const s2 = sin(y2);
1706 scalar_type const c3 = cos(z3);
1707 scalar_type const s3 = sin(z3);
1708 return qvm_detail::rot_mat_<Dim,Angle>(
1709 c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3, c1*s2,
1710 c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3, s1*s2,
1711 -c3*s2, s2*s3, c2 );
1714 template <class A,class Angle>
1715 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1716 typename enable_if_c<
1718 mat_traits<A>::rows==mat_traits<A>::cols &&
1719 mat_traits<A>::rows>=3,
1721 set_rot_zyz( A & a, Angle z1, Angle y2, Angle z3 )
1723 assign(a,rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3));
1726 template <class A,class Angle>
1727 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1728 typename enable_if_c<
1730 mat_traits<A>::rows==mat_traits<A>::cols &&
1731 mat_traits<A>::rows>=3,
1733 rotate_zyz( A & a, Angle z1, Angle y2, Angle z3 )
1735 a *= rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3);
1738 ////////////////////////////////////////////////
1740 template <int Dim,class Angle>
1741 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE
1742 qvm_detail::rot_mat_<Dim,Angle>
1743 rot_mat_zxz( Angle z1, Angle x2, Angle z3 )
1745 typedef Angle scalar_type;
1746 scalar_type const c1 = cos(z1);
1747 scalar_type const s1 = sin(z1);
1748 scalar_type const c2 = cos(x2);
1749 scalar_type const s2 = sin(x2);
1750 scalar_type const c3 = cos(z3);
1751 scalar_type const s3 = sin(z3);
1752 return qvm_detail::rot_mat_<Dim,Angle>(
1753 c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1, s1*s2,
1754 c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3, -c1*s2,
1758 template <class A,class Angle>
1759 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1760 typename enable_if_c<
1762 mat_traits<A>::rows==mat_traits<A>::cols &&
1763 mat_traits<A>::rows>=3,
1765 set_rot_zxz( A & a, Angle z1, Angle x2, Angle z3 )
1767 assign(a,rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3));
1770 template <class A,class Angle>
1771 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1772 typename enable_if_c<
1774 mat_traits<A>::rows==mat_traits<A>::cols &&
1775 mat_traits<A>::rows>=3,
1777 rotate_zxz( A & a, Angle z1, Angle x2, Angle z3 )
1779 a *= rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3);
1782 ////////////////////////////////////////////////
1787 template <int Dim,class Angle>
1791 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1797 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1807 rotx_mat_( rotx_mat_ const & );
1808 rotx_mat_ & operator=( rotx_mat_ const & );
1812 template <int Row,int Col>
1818 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1822 return scalar_traits<T>::value(Row==Col);
1832 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1834 get( T const & angle )
1846 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1848 get( T const & angle )
1860 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1862 get( T const & angle )
1874 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1876 get( T const & angle )
1883 template <int Dim,class Angle>
1885 mat_traits< qvm_detail::rotx_mat_<Dim,Angle> >
1887 typedef qvm_detail::rotx_mat_<Dim,Angle> this_matrix;
1888 typedef Angle scalar_type;
1889 static int const rows=Dim;
1890 static int const cols=Dim;
1892 template <int Row,int Col>
1894 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1896 read_element( this_matrix const & x )
1898 BOOST_QVM_STATIC_ASSERT(Row>=0);
1899 BOOST_QVM_STATIC_ASSERT(Col>=0);
1900 BOOST_QVM_STATIC_ASSERT(Row<Dim);
1901 BOOST_QVM_STATIC_ASSERT(Col<Dim);
1902 return qvm_detail::rotx_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));
1906 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
1908 read_element_idx( int row, int col, this_matrix const & x )
1910 BOOST_QVM_ASSERT(row>=0);
1911 BOOST_QVM_ASSERT(col>=0);
1912 BOOST_QVM_ASSERT(row<Dim);
1913 BOOST_QVM_ASSERT(col<Dim);
1914 Angle const & a=reinterpret_cast<Angle const &>(x);
1929 return scalar_traits<scalar_type>::value(row==col);
1933 template <int Dim,class Angle>
1935 deduce_mat<qvm_detail::rotx_mat_<Dim,Angle>,Dim,Dim>
1937 typedef mat<Angle,Dim,Dim> type;
1940 template <int Dim,class Angle>
1942 deduce_mat2<qvm_detail::rotx_mat_<Dim,Angle>,qvm_detail::rotx_mat_<Dim,Angle>,Dim,Dim>
1944 typedef mat<Angle,Dim,Dim> type;
1947 template <int Dim,class Angle>
1948 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1949 qvm_detail::rotx_mat_<Dim,Angle> const &
1950 rotx_mat( Angle const & angle )
1952 BOOST_QVM_STATIC_ASSERT(Dim>=3);
1953 return reinterpret_cast<qvm_detail::rotx_mat_<Dim,Angle> const &>(angle);
1956 template <class A,class Angle>
1957 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1958 typename enable_if_c<
1960 mat_traits<A>::rows>=3 &&
1961 mat_traits<A>::rows==mat_traits<A>::cols,
1963 set_rotx( A & a, Angle angle )
1965 assign(a,rotx_mat<mat_traits<A>::rows>(angle));
1968 template <class A,class Angle>
1969 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
1970 typename enable_if_c<
1972 mat_traits<A>::rows>=3 &&
1973 mat_traits<A>::rows==mat_traits<A>::cols,
1975 rotate_x( A & a, Angle angle )
1977 a *= rotx_mat<mat_traits<A>::rows>(angle);
1980 ////////////////////////////////////////////////
1985 template <int Dim,class Angle>
1989 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
1995 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2005 roty_mat_( roty_mat_ const & );
2006 roty_mat_ & operator=( roty_mat_ const & );
2010 template <int Row,int Col>
2016 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2020 return scalar_traits<T>::value(Row==Col);
2030 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2032 get( T const & angle )
2044 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2046 get( T const & angle )
2058 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2060 get( T const & angle )
2072 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2074 get( T const & angle )
2081 template <int Dim,class Angle>
2083 mat_traits< qvm_detail::roty_mat_<Dim,Angle> >
2085 typedef qvm_detail::roty_mat_<Dim,Angle> this_matrix;
2086 typedef Angle scalar_type;
2087 static int const rows=Dim;
2088 static int const cols=Dim;
2090 template <int Row,int Col>
2092 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2094 read_element( this_matrix const & x )
2096 BOOST_QVM_STATIC_ASSERT(Row>=0);
2097 BOOST_QVM_STATIC_ASSERT(Col>=0);
2098 BOOST_QVM_STATIC_ASSERT(Row<Dim);
2099 BOOST_QVM_STATIC_ASSERT(Col<Dim);
2100 return qvm_detail::roty_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));
2104 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2106 read_element_idx( int row, int col, this_matrix const & x )
2108 BOOST_QVM_ASSERT(row>=0);
2109 BOOST_QVM_ASSERT(col>=0);
2110 BOOST_QVM_ASSERT(row<Dim);
2111 BOOST_QVM_ASSERT(col<Dim);
2112 Angle const & a=reinterpret_cast<Angle const &>(x);
2127 return scalar_traits<scalar_type>::value(row==col);
2131 template <int Dim,class Angle>
2133 deduce_mat<qvm_detail::roty_mat_<Dim,Angle>,Dim,Dim>
2135 typedef mat<Angle,Dim,Dim> type;
2138 template <int Dim,class Angle>
2140 deduce_mat2<qvm_detail::roty_mat_<Dim,Angle>,qvm_detail::roty_mat_<Dim,Angle>,Dim,Dim>
2142 typedef mat<Angle,Dim,Dim> type;
2145 template <int Dim,class Angle>
2146 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2147 qvm_detail::roty_mat_<Dim,Angle> const &
2148 roty_mat( Angle const & angle )
2150 BOOST_QVM_STATIC_ASSERT(Dim>=3);
2151 return reinterpret_cast<qvm_detail::roty_mat_<Dim,Angle> const &>(angle);
2154 template <class A,class Angle>
2155 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2156 typename enable_if_c<
2158 mat_traits<A>::rows>=2 &&
2159 mat_traits<A>::rows==mat_traits<A>::cols,
2161 set_roty( A & a, Angle angle )
2163 assign(a,roty_mat<mat_traits<A>::rows>(angle));
2166 template <class A,class Angle>
2167 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2168 typename enable_if_c<
2170 mat_traits<A>::rows>=3 &&
2171 mat_traits<A>::rows==mat_traits<A>::cols,
2173 rotate_y( A & a, Angle angle )
2175 a *= roty_mat<mat_traits<A>::rows>(angle);
2178 ////////////////////////////////////////////////
2183 template <int Dim,class Angle>
2187 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2193 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2203 rotz_mat_( rotz_mat_ const & );
2204 rotz_mat_ & operator=( rotz_mat_ const & );
2208 template <int Row,int Col>
2214 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2218 return scalar_traits<T>::value(Row==Col);
2228 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2230 get( T const & angle )
2242 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2244 get( T const & angle )
2256 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2258 get( T const & angle )
2270 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2272 get( T const & angle )
2279 template <int Dim,class Angle>
2281 mat_traits< qvm_detail::rotz_mat_<Dim,Angle> >
2283 typedef qvm_detail::rotz_mat_<Dim,Angle> this_matrix;
2284 typedef Angle scalar_type;
2285 static int const rows=Dim;
2286 static int const cols=Dim;
2288 template <int Row,int Col>
2290 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2292 read_element( this_matrix const & x )
2294 BOOST_QVM_STATIC_ASSERT(Row>=0);
2295 BOOST_QVM_STATIC_ASSERT(Col>=0);
2296 BOOST_QVM_STATIC_ASSERT(Row<Dim);
2297 BOOST_QVM_STATIC_ASSERT(Col<Dim);
2298 return qvm_detail::rotz_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));
2302 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
2304 read_element_idx( int row, int col, this_matrix const & x )
2306 BOOST_QVM_ASSERT(row>=0);
2307 BOOST_QVM_ASSERT(col>=0);
2308 BOOST_QVM_ASSERT(row<Dim);
2309 BOOST_QVM_ASSERT(col<Dim);
2310 Angle const & a=reinterpret_cast<Angle const &>(x);
2325 return scalar_traits<scalar_type>::value(row==col);
2329 template <int Dim,class Angle>
2331 deduce_mat<qvm_detail::rotz_mat_<Dim,Angle>,Dim,Dim>
2333 typedef mat<Angle,Dim,Dim> type;
2336 template <int Dim,class Angle,int R,int C>
2338 deduce_mat2<qvm_detail::rotz_mat_<Dim,Angle>,qvm_detail::rotz_mat_<Dim,Angle>,R,C>
2340 typedef mat<Angle,R,C> type;
2343 template <int Dim,class Angle>
2344 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2345 qvm_detail::rotz_mat_<Dim,Angle> const &
2346 rotz_mat( Angle const & angle )
2348 BOOST_QVM_STATIC_ASSERT(Dim>=2);
2349 return reinterpret_cast<qvm_detail::rotz_mat_<Dim,Angle> const &>(angle);
2352 template <class A,class Angle>
2353 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2354 typename enable_if_c<
2356 mat_traits<A>::rows>=2 &&
2357 mat_traits<A>::rows==mat_traits<A>::cols,
2359 set_rotz( A & a, Angle angle )
2361 assign(a,rotz_mat<mat_traits<A>::rows>(angle));
2364 template <class A,class Angle>
2365 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
2366 typename enable_if_c<
2368 mat_traits<A>::rows>=2 &&
2369 mat_traits<A>::rows==mat_traits<A>::cols,
2371 rotate_z( A & a, Angle angle )
2373 a *= rotz_mat<mat_traits<A>::rows>(angle);
2376 ////////////////////////////////////////////////
2385 static bool const value=false;
2389 template <class A,class B>
2390 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2391 typename lazy_enable_if_c<
2392 is_mat<A>::value && is_scalar<B>::value &&
2393 mat_traits<A>::rows==mat_traits<A>::cols &&
2394 !qvm_detail::inverse_m_defined<mat_traits<A>::rows>::value,
2395 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type
2396 inverse( A const & a, B det )
2398 typedef typename mat_traits<A>::scalar_type T;
2399 BOOST_QVM_ASSERT(det!=scalar_traits<T>::value(0));
2400 T f=scalar_traits<T>::value(1)/det;
2401 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type cofactor_return_type;
2402 cofactor_return_type c=qvm_detail::cofactor_impl(a);
2403 return reinterpret_cast<qvm_detail::transposed_<cofactor_return_type> const &>(c) * f;
2407 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
2408 typename lazy_enable_if_c<
2410 mat_traits<A>::rows==mat_traits<A>::cols &&
2411 !qvm_detail::inverse_m_defined<mat_traits<A>::rows>::value,
2412 deduce_mat<A> >::type
2413 inverse( A const & a )
2415 typedef typename mat_traits<A>::scalar_type T;
2416 T det=determinant(a);
2417 if( det==scalar_traits<T>::value(0) )
2418 BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());
2419 return inverse(a,det);
2422 ////////////////////////////////////////////////
2427 using ::boost::qvm::to_string;
2428 using ::boost::qvm::assign;
2429 using ::boost::qvm::determinant;
2430 using ::boost::qvm::cmp;
2431 using ::boost::qvm::convert_to;
2432 using ::boost::qvm::set_identity;
2433 using ::boost::qvm::set_zero;
2434 using ::boost::qvm::scalar_cast;
2435 using ::boost::qvm::operator/=;
2436 using ::boost::qvm::operator/;
2437 using ::boost::qvm::operator==;
2438 using ::boost::qvm::operator-=;
2439 using ::boost::qvm::operator-;
2440 using ::boost::qvm::operator*=;
2441 using ::boost::qvm::operator*;
2442 using ::boost::qvm::operator!=;
2443 using ::boost::qvm::operator+=;
2444 using ::boost::qvm::operator+;
2445 using ::boost::qvm::mref;
2446 using ::boost::qvm::rot_mat;
2447 using ::boost::qvm::set_rot;
2448 using ::boost::qvm::rotate;
2449 using ::boost::qvm::set_rotx;
2450 using ::boost::qvm::rotate_x;
2451 using ::boost::qvm::set_roty;
2452 using ::boost::qvm::rotate_y;
2453 using ::boost::qvm::set_rotz;
2454 using ::boost::qvm::rotate_z;
2455 using ::boost::qvm::inverse;