summaryrefslogtreecommitdiff
path: root/boost/qvm/mat_operations.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/qvm/mat_operations.hpp')
-rw-r--r--boost/qvm/mat_operations.hpp614
1 files changed, 574 insertions, 40 deletions
diff --git a/boost/qvm/mat_operations.hpp b/boost/qvm/mat_operations.hpp
index ccd3612922..0cf35154d4 100644
--- a/boost/qvm/mat_operations.hpp
+++ b/boost/qvm/mat_operations.hpp
@@ -1101,45 +1101,28 @@ boost
namespace
qvm_detail
{
- template <int D,class V>
+ template <int D,class S>
struct
rot_mat_
{
- typedef typename vec_traits<V>::scalar_type scalar_type;
+ typedef S scalar_type;
scalar_type a[3][3];
- template <class Angle>
BOOST_QVM_INLINE
- rot_mat_( V const & axis, Angle angle )
+ rot_mat_(
+ scalar_type a00, scalar_type a01, scalar_type a02,
+ scalar_type a10, scalar_type a11, scalar_type a12,
+ scalar_type a20, scalar_type a21, scalar_type a22 )
{
- scalar_type const x=vec_traits<V>::template read_element<0>(axis);
- scalar_type const y=vec_traits<V>::template read_element<1>(axis);
- scalar_type const z=vec_traits<V>::template read_element<2>(axis);
- scalar_type const m2=x*x+y*y+z*z;
- if( m2==scalar_traits<scalar_type>::value(0) )
- BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
- scalar_type const s = sin<Angle>(angle);
- scalar_type const c = cos<Angle>(angle);
- scalar_type const x2 = x*x;
- scalar_type const y2 = y*y;
- scalar_type const z2 = z*z;
- scalar_type const xy = x*y;
- scalar_type const xz = x*z;
- scalar_type const yz = y*z;
- scalar_type const xs = x*s;
- scalar_type const ys = y*s;
- scalar_type const zs = z*s;
- scalar_type const one = scalar_traits<scalar_type>::value(1);
- scalar_type const c1 = one-c;
- a[0][0] = x2+(one-x2)*c;
- a[0][1] = xy*c1-zs;
- a[0][2] = xz*(one-c)+ys;
- a[1][0] = xy*c1+zs;
- a[1][1] = y2+(one-y2)*c;
- a[1][2] = yz*c1-xs;
- a[2][0] = xz*c1-ys;
- a[2][1] = yz*c1+xs;
- a[2][2] = z2+(one-z2)*c;
+ a[0][0] = a00;
+ a[0][1] = a01;
+ a[0][2] = a02;
+ a[1][0] = a10;
+ a[1][1] = a11;
+ a[1][2] = a12;
+ a[2][0] = a20;
+ a[2][1] = a21;
+ a[2][2] = a22;
}
template <class R>
@@ -1180,11 +1163,11 @@ boost
template <class M>
struct mat_traits;
- template <int D,class V>
+ template <int D,class S>
struct
- mat_traits< qvm_detail::rot_mat_<D,V> >
+ mat_traits< qvm_detail::rot_mat_<D,S> >
{
- typedef qvm_detail::rot_mat_<D,V> this_matrix;
+ typedef qvm_detail::rot_mat_<D,S> this_matrix;
typedef typename this_matrix::scalar_type scalar_type;
static int const rows=D;
static int const cols=D;
@@ -1217,14 +1200,37 @@ boost
}
};
- template <int Dim,class A,class Angle>
+ template <int Dim,class V,class Angle>
BOOST_QVM_INLINE
typename enable_if_c<
- is_vec<A>::value && vec_traits<A>::dim==3,
- qvm_detail::rot_mat_<Dim,A> >::type
- rot_mat( A const & axis, Angle angle )
+ is_vec<V>::value && vec_traits<V>::dim==3,
+ qvm_detail::rot_mat_<Dim,Angle> >::type
+ rot_mat( V const & axis, Angle angle )
{
- return qvm_detail::rot_mat_<Dim,A>(axis,angle);
+ typedef Angle scalar_type;
+ scalar_type const x=vec_traits<V>::template read_element<0>(axis);
+ scalar_type const y=vec_traits<V>::template read_element<1>(axis);
+ scalar_type const z=vec_traits<V>::template read_element<2>(axis);
+ scalar_type const m2=x*x+y*y+z*z;
+ if( m2==scalar_traits<scalar_type>::value(0) )
+ BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());
+ scalar_type const s = sin<scalar_type>(angle);
+ scalar_type const c = cos<scalar_type>(angle);
+ scalar_type const x2 = x*x;
+ scalar_type const y2 = y*y;
+ scalar_type const z2 = z*z;
+ scalar_type const xy = x*y;
+ scalar_type const xz = x*z;
+ scalar_type const yz = y*z;
+ scalar_type const xs = x*s;
+ scalar_type const ys = y*s;
+ scalar_type const zs = z*s;
+ scalar_type const one = scalar_traits<scalar_type>::value(1);
+ scalar_type const c1 = one-c;
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ x2+(one-x2)*c, xy*c1-zs, xz*(one-c)+ys,
+ xy*c1+zs, y2+(one-y2)*c, yz*c1-xs,
+ xz*c1-ys, yz*c1+xs, z2+(one-z2)*c );
}
template <class A,class B,class Angle>
@@ -1255,6 +1261,534 @@ boost
////////////////////////////////////////////////
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_xzy( Angle x1, Angle z2, Angle y3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(x1);
+ scalar_type const s1 = sin<scalar_type>(x1);
+ scalar_type const c2 = cos<scalar_type>(z2);
+ scalar_type const s2 = sin<scalar_type>(z2);
+ scalar_type const c3 = cos<scalar_type>(y3);
+ scalar_type const s3 = sin<scalar_type>(y3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c2*c3, -s2, c2*s3,
+ s1*s3 + c1*c3*s2, c1*c2, c1*s2*s3 - c3*s1,
+ c3*s1*s2 - c1*s3, c2*s1, c1*c3 + s1*s2*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_xzy( A & a, Angle x1, Angle z2, Angle y3 )
+ {
+ assign(a,rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_xzy( A & a, Angle x1, Angle z2, Angle y3 )
+ {
+ a *= rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_xyz( Angle x1, Angle y2, Angle z3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(x1);
+ scalar_type const s1 = sin<scalar_type>(x1);
+ scalar_type const c2 = cos<scalar_type>(y2);
+ scalar_type const s2 = sin<scalar_type>(y2);
+ scalar_type const c3 = cos<scalar_type>(z3);
+ scalar_type const s3 = sin<scalar_type>(z3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c2*c3, -c2*s3, s2,
+ c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3, -c2*s1,
+ s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3, c1*c2 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_xyz( A & a, Angle x1, Angle y2, Angle z3 )
+ {
+ assign(a,rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_xyz( A & a, Angle x1, Angle y2, Angle z3 )
+ {
+ a *= rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_yxz( Angle y1, Angle x2, Angle z3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(y1);
+ scalar_type const s1 = sin<scalar_type>(y1);
+ scalar_type const c2 = cos<scalar_type>(x2);
+ scalar_type const s2 = sin<scalar_type>(x2);
+ scalar_type const c3 = cos<scalar_type>(z3);
+ scalar_type const s3 = sin<scalar_type>(z3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3, c2*s1,
+ c2*s3, c2*c3, -s2,
+ c1*s2*s3 - c3*s1, c1*c3*s2 + s1*s3, c1*c2 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_yxz( A & a, Angle y1, Angle x2, Angle z3 )
+ {
+ assign(a,rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_yxz( A & a, Angle y1, Angle x2, Angle z3 )
+ {
+ a *= rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_yzx( Angle y1, Angle z2, Angle x3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(y1);
+ scalar_type const s1 = sin<scalar_type>(y1);
+ scalar_type const c2 = cos<scalar_type>(z2);
+ scalar_type const s2 = sin<scalar_type>(z2);
+ scalar_type const c3 = cos<scalar_type>(x3);
+ scalar_type const s3 = sin<scalar_type>(x3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c2, s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3,
+ s2, c2*c3, -c2*s3,
+ -c2*s1, c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_yzx( A & a, Angle y1, Angle z2, Angle x3 )
+ {
+ assign(a,rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_yzx( A & a, Angle y1, Angle z2, Angle x3 )
+ {
+ a *= rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_zyx( Angle z1, Angle y2, Angle x3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(z1);
+ scalar_type const s1 = sin<scalar_type>(z1);
+ scalar_type const c2 = cos<scalar_type>(y2);
+ scalar_type const s2 = sin<scalar_type>(y2);
+ scalar_type const c3 = cos<scalar_type>(x3);
+ scalar_type const s3 = sin<scalar_type>(x3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2,
+ c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3,
+ -s2, c2*s3, c2*c3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_zyx( A & a, Angle z1, Angle y2, Angle x3 )
+ {
+ assign(a,rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_zyx( A & a, Angle z1, Angle y2, Angle x3 )
+ {
+ a *= rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_zxy( Angle z1, Angle x2, Angle y3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(z1);
+ scalar_type const s1 = sin<scalar_type>(z1);
+ scalar_type const c2 = cos<scalar_type>(x2);
+ scalar_type const s2 = sin<scalar_type>(x2);
+ scalar_type const c3 = cos<scalar_type>(y3);
+ scalar_type const s3 = sin<scalar_type>(y3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c3 - s1*s2*s3, -c2*s1, c1*s3 + c3*s1*s2,
+ c3*s1 + c1*s2*s3, c1*c2, s1*s3 - c1*c3*s2,
+ -c2*s3, s2, c2*c3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_zxy( A & a, Angle z1, Angle x2, Angle y3 )
+ {
+ assign(a,rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_zxy( A & a, Angle z1, Angle x2, Angle y3 )
+ {
+ a *= rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_xzx( Angle x1, Angle z2, Angle x3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(x1);
+ scalar_type const s1 = sin<scalar_type>(x1);
+ scalar_type const c2 = cos<scalar_type>(z2);
+ scalar_type const s2 = sin<scalar_type>(z2);
+ scalar_type const c3 = cos<scalar_type>(x3);
+ scalar_type const s3 = sin<scalar_type>(x3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c2, -c3*s2, s2*s3,
+ c1*s2, c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3,
+ s1*s2, c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_xzx( A & a, Angle x1, Angle z2, Angle x3 )
+ {
+ assign(a,rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_xzx( A & a, Angle x1, Angle z2, Angle x3 )
+ {
+ a *= rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_xyx( Angle x1, Angle y2, Angle x3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(x1);
+ scalar_type const s1 = sin<scalar_type>(x1);
+ scalar_type const c2 = cos<scalar_type>(y2);
+ scalar_type const s2 = sin<scalar_type>(y2);
+ scalar_type const c3 = cos<scalar_type>(x3);
+ scalar_type const s3 = sin<scalar_type>(x3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c2, s2*s3, c3*s2,
+ s1*s2, c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1,
+ -c1*s2, c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_xyx( A & a, Angle x1, Angle y2, Angle x3 )
+ {
+ assign(a,rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_xyx( A & a, Angle x1, Angle y2, Angle x3 )
+ {
+ a *= rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_yxy( Angle y1, Angle x2, Angle y3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(y1);
+ scalar_type const s1 = sin<scalar_type>(y1);
+ scalar_type const c2 = cos<scalar_type>(x2);
+ scalar_type const s2 = sin<scalar_type>(x2);
+ scalar_type const c3 = cos<scalar_type>(y3);
+ scalar_type const s3 = sin<scalar_type>(y3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c3 - c2*s1*s3, s1*s2, c1*s3 + c2*c3*s1,
+ s2*s3, c2, -c3*s2,
+ -c3*s1 - c1*c2*s3, c1*s2, c1*c2*c3 - s1*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_yxy( A & a, Angle y1, Angle x2, Angle y3 )
+ {
+ assign(a,rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_yxy( A & a, Angle y1, Angle x2, Angle y3 )
+ {
+ a *= rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_yzy( Angle y1, Angle z2, Angle y3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(y1);
+ scalar_type const s1 = sin<scalar_type>(y1);
+ scalar_type const c2 = cos<scalar_type>(z2);
+ scalar_type const s2 = sin<scalar_type>(z2);
+ scalar_type const c3 = cos<scalar_type>(y3);
+ scalar_type const s3 = sin<scalar_type>(y3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c2*c3 - s1*s3, -c1*s2, c3*s1 + c1*c2*s3,
+ c3*s2, c2, s2*s3,
+ -c1*s3 - c2*c3*s1, s1*s2, c1*c3 - c2*s1*s3 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_yzy( A & a, Angle y1, Angle z2, Angle y3 )
+ {
+ assign(a,rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_yzy( A & a, Angle y1, Angle z2, Angle y3 )
+ {
+ a *= rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_zyz( Angle z1, Angle y2, Angle z3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(z1);
+ scalar_type const s1 = sin<scalar_type>(z1);
+ scalar_type const c2 = cos<scalar_type>(y2);
+ scalar_type const s2 = sin<scalar_type>(y2);
+ scalar_type const c3 = cos<scalar_type>(z3);
+ scalar_type const s3 = sin<scalar_type>(z3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3, c1*s2,
+ c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3, s1*s2,
+ -c3*s2, s2*s3, c2 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_zyz( A & a, Angle z1, Angle y2, Angle z3 )
+ {
+ assign(a,rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_zyz( A & a, Angle z1, Angle y2, Angle z3 )
+ {
+ a *= rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3);
+ }
+
+ ////////////////////////////////////////////////
+
+ template <int Dim,class Angle>
+ BOOST_QVM_INLINE
+ qvm_detail::rot_mat_<Dim,Angle>
+ rot_mat_zxz( Angle z1, Angle x2, Angle z3 )
+ {
+ typedef Angle scalar_type;
+ scalar_type const c1 = cos<scalar_type>(z1);
+ scalar_type const s1 = sin<scalar_type>(z1);
+ scalar_type const c2 = cos<scalar_type>(x2);
+ scalar_type const s2 = sin<scalar_type>(x2);
+ scalar_type const c3 = cos<scalar_type>(z3);
+ scalar_type const s3 = sin<scalar_type>(z3);
+ return qvm_detail::rot_mat_<Dim,Angle>(
+ c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1, s1*s2,
+ c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3, -c1*s2,
+ s2*s3, c3*s2, c2 );
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ set_rot_zxz( A & a, Angle z1, Angle x2, Angle z3 )
+ {
+ assign(a,rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3));
+ }
+
+ template <class A,class Angle>
+ BOOST_QVM_INLINE_OPERATIONS
+ typename enable_if_c<
+ is_mat<A>::value &&
+ mat_traits<A>::rows==mat_traits<A>::cols &&
+ mat_traits<A>::rows>=3,
+ void>::type
+ rotate_zxz( A & a, Angle z1, Angle x2, Angle z3 )
+ {
+ a *= rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3);
+ }
+
+ ////////////////////////////////////////////////
+
namespace
qvm_detail
{