Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84561 - in trunk/boost/geometry/extensions/algebra: . algorithms core geometries geometries/concepts
From: adam.wulkiewicz_at_[hidden]
Date: 2013-05-30 15:24:47


Author: awulkiew
Date: 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
New Revision: 84561
URL: http://svn.boost.org/trac/boost/changeset/84561

Log:
index extensions: added rotation matrix, for now rotation() implemented only for 3d.
Added:
   trunk/boost/geometry/extensions/algebra/algorithms/detail.hpp (contents, props changed)
   trunk/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp (contents, props changed)
   trunk/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp (contents, props changed)
   trunk/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp (contents, props changed)
Removed:
   trunk/boost/geometry/extensions/algebra/algorithms/transform.hpp
Text files modified:
   trunk/boost/geometry/extensions/algebra/algebra.hpp | 4
   trunk/boost/geometry/extensions/algebra/algorithms/assign.hpp | 1
   trunk/boost/geometry/extensions/algebra/algorithms/rotation.hpp | 161 ++++++++++++++++++++++++++++-----------
   trunk/boost/geometry/extensions/algebra/core/access.hpp | 10 ++
   trunk/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp | 5 +
   trunk/boost/geometry/extensions/algebra/core/coordinate_system.hpp | 8 +
   trunk/boost/geometry/extensions/algebra/core/coordinate_type.hpp | 8 +
   trunk/boost/geometry/extensions/algebra/core/tags.hpp | 1
   trunk/boost/geometry/extensions/algebra/core/topological_dimension.hpp | 3
   trunk/boost/geometry/extensions/algebra/geometries/concepts/check.hpp | 10 ++
   10 files changed, 162 insertions(+), 49 deletions(-)

Modified: trunk/boost/geometry/extensions/algebra/algebra.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/algebra.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/algebra.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -24,10 +24,12 @@
 
 #include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
 #include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
 #include <boost/geometry/extensions/algebra/geometries/concepts/check.hpp>
 
 #include <boost/geometry/extensions/algebra/geometries/vector.hpp>
 #include <boost/geometry/extensions/algebra/geometries/rotation_quaternion.hpp>
+#include <boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp>
 
 #include <boost/geometry/extensions/algebra/algorithms/assign.hpp>
 #include <boost/geometry/extensions/algebra/algorithms/clear.hpp>
@@ -35,6 +37,6 @@
 
 #include <boost/geometry/extensions/algebra/algorithms/translation.hpp>
 #include <boost/geometry/extensions/algebra/algorithms/rotation.hpp>
-#include <boost/geometry/extensions/algebra/algorithms/transform.hpp>
+#include <boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp>
 
 #endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGEBRA_HPP

Modified: trunk/boost/geometry/extensions/algebra/algorithms/assign.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/algorithms/assign.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/algorithms/assign.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -24,7 +24,6 @@
 namespace boost { namespace geometry
 {
 
-
 #ifndef DOXYGEN_NO_DISPATCH
 namespace dispatch
 {

Added: trunk/boost/geometry/extensions/algebra/algorithms/detail.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algebra/algorithms/detail.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -0,0 +1,156 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
+
+namespace boost { namespace geometry
+{
+
+namespace detail { namespace algebra {
+
+template <std::size_t IS1, std::size_t IS2, std::size_t ID, typename S1, typename S2, typename D>
+inline void cross(S1 const& s1, S2 const& s2, D & d)
+{
+ set<ID+0>(d, get<IS1+1>(s1)*get<IS2+2>(s2) - get<IS1+2>(s1)*get<IS2+1>(s2));
+ set<ID+1>(d, get<IS1+2>(s1)*get<IS2+0>(s2) - get<IS1+0>(s1)*get<IS2+2>(s2));
+ set<ID+2>(d, get<IS1+0>(s1)*get<IS2+1>(s2) - get<IS1+1>(s1)*get<IS2+0>(s2));
+}
+
+template <typename S1, typename S2, std::size_t IS1, std::size_t IS2, std::size_t N>
+struct dot_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+ >::type coordinate_type;
+
+ static inline coordinate_type apply(S1 const& s1, S2 const& s2)
+ {
+ return get<IS1>(s1)*get<IS2>(s2) + dot_impl<S1, S2, IS1+1, IS2+1, N-1>::apply(s1, s2);
+ }
+};
+
+template <typename S1, typename S2, std::size_t IS1, std::size_t IS2>
+struct dot_impl<S1, S2, IS1, IS2, 1>
+{
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+ >::type coordinate_type;
+
+ static inline coordinate_type apply(S1 const& s1, S2 const& s2)
+ {
+ return get<IS1>(s1)*get<IS2>(s2);
+ }
+};
+
+template <std::size_t IS1, std::size_t IS2, std::size_t N, typename S1, typename S2>
+inline static
+typename geometry::select_most_precise<
+ typename traits::coordinate_type<S1>::type,
+ typename traits::coordinate_type<S2>::type
+>::type
+dot(S1 const& s1, S2 const& s2)
+{
+ return dot_impl<S1, S2, IS1, IS2, N>::apply(s1, s2);
+}
+
+template <typename S, typename T, std::size_t IS, std::size_t I, std::size_t N>
+struct mul_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ static inline void apply(S & s, T const& v)
+ {
+ set<IS>(s, get<IS>(s) * v);
+ mul_impl<S, T, IS+1, I+1, N>::apply(s, v);
+ }
+};
+
+template <typename S, typename T, std::size_t IS, std::size_t N>
+struct mul_impl<S, T, IS, N, N>
+{
+ static inline void apply(S &, T const&) {}
+};
+
+template <std::size_t IS, std::size_t N, typename S, typename T>
+inline static void mul(S & s, T const& v)
+{
+ return mul_impl<S, T, IS, 0, N>::apply(s, v);
+}
+
+template <std::size_t I, std::size_t N, typename S>
+inline static void normalize(S & s)
+{
+ typedef typename traits::coordinate_type<S>::type T;
+
+ T lsqr = dot<I, I, N>(s, s);
+ if ( std::numeric_limits<T>::epsilon() < lsqr )
+ mul<I, N>(s, 1.0f / ::sqrt(lsqr));
+}
+
+template <typename M, typename V, typename VD, std::size_t I, std::size_t N>
+struct matrix_mul_row_impl
+{
+ BOOST_STATIC_ASSERT(0 < N);
+
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ static inline
+ typename traits::coordinate_type<VD>::type
+ apply(M const& m, V const& v)
+ {
+ return matrix_mul_row_impl<M, V, VD, I, N-1>::apply(m, v) + get<I, N-1>(m) * get<N-1>(v);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t I>
+struct matrix_mul_row_impl<M, V, VD, I, 1>
+{
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ static inline
+ typename traits::coordinate_type<VD>::type
+ apply(M const& m, V const& v)
+ {
+ return get<I, 0>(m) * get<0>(v);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t I, std::size_t N>
+struct matrix_mul_impl
+{
+ static inline void apply(M const& m, V const& v, VD & vd)
+ {
+ set<I>(vd, matrix_mul_row_impl<M, V, VD, I, N>::apply(m, v));
+ matrix_mul_impl<M, V, VD, I+1, N>::apply(m, v, vd);
+ }
+};
+
+template <typename M, typename V, typename VD, std::size_t N>
+struct matrix_mul_impl<M, V, VD, N, N>
+{
+ static inline void apply(M const&, V const&, VD &) {}
+};
+
+template <typename M, typename V, typename VD>
+inline static void matrix_mul(M const& m, V const& v, VD & vd)
+{
+ static const std::size_t dimension = traits::dimension<M>::value;
+
+ matrix_mul_impl<M, V, VD, 0, dimension>::apply(m, v, vd);
+}
+
+}} // namespace detail::algebra
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP

Modified: trunk/boost/geometry/extensions/algebra/algorithms/rotation.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/algorithms/rotation.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/algorithms/rotation.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -9,25 +9,116 @@
 #ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ROTATION_HPP
 #define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_ROTATION_HPP
 
+#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
+
 #include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
 
-namespace boost { namespace geometry
+namespace boost { namespace geometry {
+
+namespace detail { namespace rotation {
+
+template <typename V1, typename V2, typename Rotation, typename Tag1, typename Tag2, std::size_t Dimension>
+struct matrix
 {
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_DIMENSION, (Rotation));
+};
+
+template <typename V1, typename V2, typename Rotation>
+struct matrix<V1, V2, Rotation, vector_tag, vector_tag, 3>
+{
+ static const bool cs_check =
+ ::boost::is_same<typename traits::coordinate_system<V1>::type, cs::cartesian>::value &&
+ ::boost::is_same<typename traits::coordinate_system<V2>::type, cs::cartesian>::value;
+
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THOSE_SYSTEMS, (V1, V2));
+
+ typedef typename geometry::select_most_precise<
+ typename traits::coordinate_type<V1>::type,
+ typename traits::coordinate_type<V2>::type
+ >::type cv_type;
+
+ typedef typename geometry::select_most_precise<
+ cv_type,
+ typename traits::coordinate_type<Rotation>::type
+ >::type cr_type;
+
+ typedef model::vector<cv_type, 3> vector_type;
+
+ inline static void apply(V1 const& v1, V2 const& v2, Rotation & r)
+ {
+ namespace da = detail::algebra;
+
+ // TODO - should store coordinates in more precise variables before the normalization?
+
+ // angle
+ cv_type d = da::dot<0, 0, 3>(v1, v2);
+ cv_type l = ::sqrt(da::dot<0, 0, 3>(v1, v1) * da::dot<0, 0, 3>(v2, v2));
+ cv_type c = d / l;
+
+ // rotation angle == 0
+ if ( 1 - std::numeric_limits<cv_type>::epsilon() <= c )
+ {
+ set<0, 0>(r, 1); set<0, 1>(r, 0); set<0, 2>(r, 0);
+ set<1, 0>(r, 0); set<1, 1>(r, 1); set<1, 2>(r, 0);
+ set<2, 0>(r, 0); set<2, 1>(r, 0); set<2, 2>(r, 1);
+ return;
+ }
+
+ vector_type axis;
+
+ // rotation angle = 180
+ if ( c <= std::numeric_limits<cv_type>::epsilon() - 1 )
+ {
+ // find arbitrary rotation axis perpendicular to v1
+ da::cross<0, 0, 0>(vector_type(1, 0, 0), v1, axis);
+ if ( da::dot<0, 0, 3>(axis, axis) < std::numeric_limits<cr_type>::epsilon() )
+ da::cross<0, 0, 0>(vector_type(0, 1, 0), v1, axis);
+ }
+ else
+ {
+ // rotation axis
+ da::cross<0, 0, 0>(v1, v2, axis);
+ }
+
+ // sin
+ cv_type s = ::sqrt(1 - c * c);
+ cv_type t = 1 - c;
+ // normalize axis
+ da::normalize<0, 3>(axis);
+
+ cv_type txx = t*get<0>(axis)*get<0>(axis);
+ cv_type tyy = t*get<1>(axis)*get<1>(axis);
+ cv_type tzz = t*get<2>(axis)*get<2>(axis);
+ cv_type txy = t*get<0>(axis)*get<1>(axis);
+ cv_type sx = s*get<0>(axis);
+ cv_type txz = t*get<0>(axis)*get<2>(axis);
+ cv_type sy = s*get<1>(axis);
+ cv_type tyz = t*get<1>(axis)*get<2>(axis);
+ cv_type sz = s*get<2>(axis);
+
+ set<0, 0>(r, txx+c); set<0, 1>(r, txy-sz); set<0, 2>(r, txz+sy);
+ set<1, 0>(r, txy+sz); set<1, 1>(r, tyy+c); set<1, 2>(r, tyz-sx);
+ set<2, 0>(r, txz-sy); set<2, 1>(r, tyz+sx); set<2, 2>(r, tzz+c);
+ }
+};
+
+}} // namespace detail::rotation
 
 #ifndef DOXYGEN_NO_DISPATCH
 namespace dispatch {
 
 template <typename V1, typename V2, typename Rotation,
- typename Tag = typename tag<V1>::type,
+ typename Tag1 = typename tag<V1>::type,
+ typename Tag2 = typename tag<V2>::type,
           typename RTag = typename tag<Rotation>::type
>
 struct rotation
 {
- BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (Tag, Rotation));
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (Tag1, Tag2, Rotation));
 };
 
 template <typename V1, typename V2, typename Rotation>
-struct rotation<V1, V2, Rotation, vector_tag, rotation_quaternion_tag>
+struct rotation<V1, V2, Rotation, vector_tag, vector_tag, rotation_quaternion_tag>
 {
     static const bool cs_check =
         ::boost::is_same<typename traits::coordinate_system<V1>::type, cs::cartesian>::value &&
@@ -35,12 +126,12 @@
 
     BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THOSE_SYSTEMS, (V1, V2));
 
- typedef typename select_most_precise<
+ typedef typename geometry::select_most_precise<
         typename traits::coordinate_type<V1>::type,
         typename traits::coordinate_type<V2>::type
>::type cv_type;
 
- typedef typename select_most_precise<
+ typedef typename geometry::select_most_precise<
         cv_type,
         typename traits::coordinate_type<Rotation>::type
>::type cr_type;
@@ -49,11 +140,14 @@
 
     inline static void apply(V1 const& v1, V2 const& v2, Rotation & r)
     {
+ namespace da = detail::algebra;
+
         // TODO - should store coordinates in more precise variables before the normalization?
 
         // half angle
- cv_type d = dot(v1, v2);
- cv_type w = ::sqrt(dot(v1, v1) * dot(v2, v2)) + d;
+ cv_type d = da::dot<0, 0, 3>(v1, v2);
+ cv_type l = ::sqrt(da::dot<0, 0, 3>(v1, v1) * da::dot<0, 0, 3>(v2, v2));
+ cv_type w = l + d;
 
         // rotation angle 0 or pi
         if ( -std::numeric_limits<cv_type>::epsilon() <= w && w <= std::numeric_limits<cv_type>::epsilon() )
@@ -68,58 +162,31 @@
             {
                 set<0>(r, 0);
                 // find arbitrary rotation axis perpendicular to v1
- assign_cross(vector_type(1, 0, 0), v1, r);
- if ( length_sqr(r) < std::numeric_limits<cr_type>::epsilon() )
- assign_cross(vector_type(0, 1, 0), v1, r);
+ da::cross<0, 0, 1>(vector_type(1, 0, 0), v1, r);
+ if ( da::dot<1, 1, 3>(r, r) < std::numeric_limits<cr_type>::epsilon() )
+ da::cross<0, 0, 1>(vector_type(0, 1, 0), v1, r);
 
                 // normalize axis
- cr_type lsqr = length_sqr(r);
- if ( std::numeric_limits<cr_type>::epsilon() < lsqr )
- scale(r, 1.0f / ::sqrt(lsqr));
+ da::normalize<1, 3>(r);
             }
         }
         else
         {
             set<0>(r, w);
             // rotation axis
- assign_cross(v1, v2, r);
+ da::cross<0, 0, 1>(v1, v2, r);
 
- // normalize
- cr_type lsqr = length_sqr(r);
- if ( std::numeric_limits<cr_type>::epsilon() < lsqr )
- scale(r, 1.0f / ::sqrt(lsqr));
+ // normalize quaternion
+ da::normalize<0, 4>(r);
         }
     }
-
- // TODO - should return more precise type?
- template <typename V1, typename V2>
- inline static cv_type dot(V1 const& v1, V2 const& v2)
- {
- return get<0>(v1)*get<0>(v2) + get<1>(v1)*get<1>(v2) + get<2>(v1)*get<2>(v2);
- }
-
- // TODO - should return more precise type?
- inline static cr_type length_sqr(Rotation const& r)
- {
- return get<0>(r)*get<0>(r) + get<1>(r)*get<1>(r) + get<2>(r)*get<2>(r) + get<3>(r)*get<3>(r);
- }
-
- inline static void assign_cross(V1 const& v1, V2 const& v2, Rotation & r)
- {
- set<1>(r, get<1>(v1)*get<2>(v2) - get<2>(v1)*get<1>(v2));
- set<2>(r, get<2>(v1)*get<0>(v2) - get<0>(v1)*get<2>(v2));
- set<3>(r, get<0>(v1)*get<1>(v2) - get<1>(v1)*get<0>(v2));
- }
-
- inline static void scale(Rotation & r, cr_type const& v)
- {
- set<0>(r, get<0>(r) * v);
- set<1>(r, get<1>(r) * v);
- set<2>(r, get<2>(r) * v);
- set<3>(r, get<3>(r) * v);
- }
 };
 
+template <typename V1, typename V2, typename Rotation>
+struct rotation<V1, V2, Rotation, vector_tag, vector_tag, rotation_matrix_tag>
+ : detail::rotation::matrix<V1, V2, Rotation, vector_tag, vector_tag, traits::dimension<Rotation>::value>
+{};
+
 } // namespace dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Deleted: trunk/boost/geometry/extensions/algebra/algorithms/transform.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/algorithms/transform.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
+++ (empty file)
@@ -1,174 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-
-// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
-
-// Use, modification and distribution is subject to the Boost Software License,
-// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
-#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
-
-#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
-#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
-#include <boost/geometry/arithmetic/arithmetic.hpp>
-
-namespace boost { namespace geometry {
-
-namespace detail { namespace transform_geometrically {
-
-template <typename Box, typename Vector, std::size_t Dimension>
-struct box_vector_cartesian
-{
- BOOST_MPL_ASSERT_MSG((0 < Dimension), INVALID_DIMENSION, (Box));
-
- static inline void apply(Box & box, Vector const& vector)
- {
- box_vector_cartesian<Box, Vector, Dimension-1>::apply(box, vector);
- set<min_corner, Dimension-1>(box, get<min_corner, Dimension-1>(box) + get<Dimension-1>(vector));
- set<max_corner, Dimension-1>(box, get<max_corner, Dimension-1>(box) + get<Dimension-1>(vector));
- }
-};
-
-template <typename Box, typename Vector>
-struct box_vector_cartesian<Box, Vector, 1>
-{
- static inline void apply(Box & box, Vector const& vector)
- {
- set<min_corner, 0>(box, get<min_corner, 0>(box) + get<0>(vector));
- set<max_corner, 0>(box, get<max_corner, 0>(box) + get<0>(vector));
- }
-};
-
-}} // namespace detail::transform
-
-#ifndef DOXYGEN_NO_DISPATCH
-namespace dispatch {
-
-template <typename Geometry, typename Transform,
- typename GTag = typename tag<Geometry>::type,
- typename TTag = typename tag<Transform>::type>
-struct transform_geometrically
-{
- BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (GTag, TTag));
-};
-
-// Point translation by Vector
-template <typename Point, typename Vector>
-struct transform_geometrically<Point, Vector, point_tag, vector_tag>
-{
- BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
- BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
-
- static inline void apply(Point & point, Vector const& vector)
- {
- typedef boost::mpl::bool_<
- boost::is_same<
- typename traits::coordinate_system<Point>::type,
- cs::cartesian
- >::value
- > is_cartesian;
- apply(point, vector, is_cartesian());
- }
-
- static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
- {
- for_each_coordinate(point, detail::point_operation<Vector, std::plus>(vector));
- }
-
- static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
- {
- typedef typename traits::coordinate_system<Point>::type cs;
- BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
- }
-};
-
-// Box translation by Vector
-template <typename Box, typename Vector>
-struct transform_geometrically<Box, Vector, box_tag, vector_tag>
-{
- typedef typename traits::point_type<Box>::type point_type;
-
- BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
- BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
-
- static inline void apply(Box & box, Vector const& vector)
- {
- typedef boost::mpl::bool_<
- boost::is_same<
- typename traits::coordinate_system<point_type>::type,
- cs::cartesian
- >::value
- > is_cartesian;
- apply(box, vector, is_cartesian());
- }
-
- static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
- {
- geometry::detail::transform_geometrically::box_vector_cartesian<
- Box, Vector, traits::dimension<point_type>::value
- >::apply(box, vector);
- }
-
- static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
- {
- typedef typename traits::coordinate_system<point_type>::type cs;
- BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
- }
-};
-
-// Vector rotation by Quaternion
-template <typename Vector, typename RotationQuaternion>
-struct transform_geometrically<Vector, RotationQuaternion, vector_tag, rotation_quaternion_tag>
-{
- static inline void apply(Vector & v, RotationQuaternion const& r)
- {
- concept::check_concepts_and_equal_dimensions<Vector, RotationQuaternion const>();
-
- // TODO - choose more precise type?
-
- typedef typename select_most_precise<
- typename traits::coordinate_type<Vector>::type,
- typename traits::coordinate_type<RotationQuaternion>::type
- >::type T;
-
- T a = /*get<0>(r) * 0 */- get<1>(r) * get<0>(v) - get<2>(r) * get<1>(v) - get<3>(r) * get<2>(v);
- T b = get<0>(r) * get<0>(v)/* + get<1>(r) * 0*/ + get<2>(r) * get<2>(v) - get<3>(r) * get<1>(v);
- T c = get<0>(r) * get<1>(v) - get<1>(r) * get<2>(v)/* + get<2>(r) * 0*/ + get<3>(r) * get<0>(v);
- T d = get<0>(r) * get<2>(v) + get<1>(r) * get<1>(v) - get<2>(r) * get<0>(v)/* + get<3>(r) * 0*/;
-
- set<0>(v, - a * get<1>(r) + b * get<0>(r) - c * get<3>(r) + d * get<2>(r));
- set<1>(v, - a * get<2>(r) + b * get<3>(r) + c * get<0>(r) - d * get<1>(r));
- set<2>(v, - a * get<3>(r) - b * get<2>(r) + c * get<1>(r) + d * get<0>(r));
- }
-};
-
-// TODO - other geometries and transformations
-
-} // namespace dispatch
-#endif // DOXYGEN_NO_DISPATCH
-
-template <typename Geometry, typename Transformation>
-inline void transform_geometrically(Geometry & g, Transformation const& t)
-{
- dispatch::transform_geometrically<Geometry, Transformation>::apply(g, t);
-}
-
-template <typename GeometrySrc, typename Transformation, typename GeometryDst>
-inline void transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t, GeometryDst & gdst)
-{
- geometry::convert(gsrc, gdst);
- geometry::transform_geometrically(gdst, t);
-}
-
-template <typename GeometryDst, typename GeometrySrc, typename Transformation>
-inline GeometryDst return_transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t)
-{
- GeometryDst res;
- transformed_geometrically(gsrc, t, res);
- return res;
-}
-
-}} // namespace boost::geometry
-
-#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP

Added: trunk/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -0,0 +1,187 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
+
+#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+
+namespace boost { namespace geometry {
+
+namespace detail { namespace transform_geometrically {
+
+template <typename Box, typename Vector, std::size_t Dimension>
+struct box_vector_cartesian
+{
+ BOOST_MPL_ASSERT_MSG((0 < Dimension), INVALID_DIMENSION, (Box));
+
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ box_vector_cartesian<Box, Vector, Dimension-1>::apply(box, vector);
+ set<min_corner, Dimension-1>(box, get<min_corner, Dimension-1>(box) + get<Dimension-1>(vector));
+ set<max_corner, Dimension-1>(box, get<max_corner, Dimension-1>(box) + get<Dimension-1>(vector));
+ }
+};
+
+template <typename Box, typename Vector>
+struct box_vector_cartesian<Box, Vector, 1>
+{
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ set<min_corner, 0>(box, get<min_corner, 0>(box) + get<0>(vector));
+ set<max_corner, 0>(box, get<max_corner, 0>(box) + get<0>(vector));
+ }
+};
+
+}} // namespace detail::transform
+
+#ifndef DOXYGEN_NO_DISPATCH
+namespace dispatch {
+
+template <typename Geometry, typename Transform,
+ typename GTag = typename tag<Geometry>::type,
+ typename TTag = typename tag<Transform>::type>
+struct transform_geometrically
+{
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THOSE_TAGS, (GTag, TTag));
+};
+
+// Point translation by Vector
+template <typename Point, typename Vector>
+struct transform_geometrically<Point, Vector, point_tag, vector_tag>
+{
+ BOOST_CONCEPT_ASSERT( (concept::Point<Point>) );
+ BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
+
+ static inline void apply(Point & point, Vector const& vector)
+ {
+ typedef boost::mpl::bool_<
+ boost::is_same<
+ typename traits::coordinate_system<Point>::type,
+ cs::cartesian
+ >::value
+ > is_cartesian;
+ apply(point, vector, is_cartesian());
+ }
+
+ static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
+ {
+ for_each_coordinate(point, detail::point_operation<Vector, std::plus>(vector));
+ }
+
+ static inline void apply(Point & point, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
+ {
+ typedef typename traits::coordinate_system<Point>::type cs;
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
+ }
+};
+
+// Box translation by Vector
+template <typename Box, typename Vector>
+struct transform_geometrically<Box, Vector, box_tag, vector_tag>
+{
+ typedef typename traits::point_type<Box>::type point_type;
+
+ BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
+ BOOST_CONCEPT_ASSERT( (concept::Vector<Vector>) );
+
+ static inline void apply(Box & box, Vector const& vector)
+ {
+ typedef boost::mpl::bool_<
+ boost::is_same<
+ typename traits::coordinate_system<point_type>::type,
+ cs::cartesian
+ >::value
+ > is_cartesian;
+ apply(box, vector, is_cartesian());
+ }
+
+ static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<true> /*is_cartesian*/)
+ {
+ geometry::detail::transform_geometrically::box_vector_cartesian<
+ Box, Vector, traits::dimension<point_type>::value
+ >::apply(box, vector);
+ }
+
+ static inline void apply(Box & box, Vector const& vector, boost::mpl::bool_<false> /*is_cartesian*/)
+ {
+ typedef typename traits::coordinate_system<point_type>::type cs;
+ BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_CS, (cs));
+ }
+};
+
+// Vector rotation by Quaternion
+template <typename Vector, typename RotationQuaternion>
+struct transform_geometrically<Vector, RotationQuaternion, vector_tag, rotation_quaternion_tag>
+{
+ static inline void apply(Vector & v, RotationQuaternion const& r)
+ {
+ concept::check_concepts_and_equal_dimensions<Vector, RotationQuaternion const>();
+
+ // TODO - choose more precise type?
+
+ typedef typename select_most_precise<
+ typename traits::coordinate_type<Vector>::type,
+ typename traits::coordinate_type<RotationQuaternion>::type
+ >::type T;
+
+ T a = /*get<0>(r) * 0 */- get<1>(r) * get<0>(v) - get<2>(r) * get<1>(v) - get<3>(r) * get<2>(v);
+ T b = get<0>(r) * get<0>(v)/* + get<1>(r) * 0*/ + get<2>(r) * get<2>(v) - get<3>(r) * get<1>(v);
+ T c = get<0>(r) * get<1>(v) - get<1>(r) * get<2>(v)/* + get<2>(r) * 0*/ + get<3>(r) * get<0>(v);
+ T d = get<0>(r) * get<2>(v) + get<1>(r) * get<1>(v) - get<2>(r) * get<0>(v)/* + get<3>(r) * 0*/;
+
+ set<0>(v, - a * get<1>(r) + b * get<0>(r) - c * get<3>(r) + d * get<2>(r));
+ set<1>(v, - a * get<2>(r) + b * get<3>(r) + c * get<0>(r) - d * get<1>(r));
+ set<2>(v, - a * get<3>(r) - b * get<2>(r) + c * get<1>(r) + d * get<0>(r));
+ }
+};
+
+// Vector rotation by Matrix
+template <typename Vector, typename RotationMatrix>
+struct transform_geometrically<Vector, RotationMatrix, vector_tag, rotation_matrix_tag>
+{
+ static inline void apply(Vector & v, RotationMatrix const& r)
+ {
+ concept::check_concepts_and_equal_dimensions<Vector, RotationMatrix const>();
+
+ // TODO vector_type and convert from Vector
+ Vector tmp(v);
+ detail::algebra::matrix_mul(r, tmp, v);
+ }
+};
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+template <typename Geometry, typename Transformation>
+inline void transform_geometrically(Geometry & g, Transformation const& t)
+{
+ dispatch::transform_geometrically<Geometry, Transformation>::apply(g, t);
+}
+
+template <typename GeometrySrc, typename Transformation, typename GeometryDst>
+inline void transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t, GeometryDst & gdst)
+{
+ geometry::convert(gsrc, gdst);
+ geometry::transform_geometrically(gdst, t);
+}
+
+template <typename GeometryDst, typename GeometrySrc, typename Transformation>
+inline GeometryDst return_transformed_geometrically(GeometrySrc const& gsrc, Transformation const& t)
+{
+ GeometryDst res;
+ transformed_geometrically(gsrc, t, res);
+ return res;
+}
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP

Modified: trunk/boost/geometry/extensions/algebra/core/access.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/access.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/access.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -81,6 +81,16 @@
     }
 };
 
+template<typename RM, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<rotation_matrix_tag, RM, CoordinateType, I, J, boost::false_type>
+ : detail::indexed_access_non_pointer<RM, CoordinateType, I, J>
+{};
+
+template<typename RM, typename CoordinateType, std::size_t I, std::size_t J>
+struct indexed_access<rotation_matrix_tag, RM, CoordinateType, I, J, boost::true_type>
+ : detail::indexed_access_pointer<RM, CoordinateType, I, J>
+{};
+
 } // namespace core_dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Modified: trunk/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/coordinate_dimension.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -34,6 +34,11 @@
     : traits::dimension<typename geometry::util::bare_type<G>::type>
 {};
 
+template <typename G>
+struct dimension<rotation_matrix_tag, G>
+ : traits::dimension<typename geometry::util::bare_type<G>::type>
+{};
+
 } // namespace core_dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Modified: trunk/boost/geometry/extensions/algebra/core/coordinate_system.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/coordinate_system.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/coordinate_system.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -40,6 +40,14 @@
>::type type;
 };
 
+template <typename G>
+struct coordinate_system<rotation_matrix_tag, G>
+{
+ typedef typename traits::coordinate_system<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
 } // namespace core_dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Modified: trunk/boost/geometry/extensions/algebra/core/coordinate_type.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/coordinate_type.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/coordinate_type.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -40,6 +40,14 @@
>::type type;
 };
 
+template <typename G>
+struct coordinate_type<rotation_matrix_tag, G>
+{
+ typedef typename traits::coordinate_type<
+ typename geometry::util::bare_type<G>::type
+ >::type type;
+};
+
 } // namespace core_dispatch
 #endif // DOXYGEN_NO_DISPATCH
 

Modified: trunk/boost/geometry/extensions/algebra/core/tags.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/tags.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/tags.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -22,6 +22,7 @@
 
 struct vector_tag {};
 struct rotation_quaternion_tag {};
+struct rotation_matrix_tag {};
 
 
 }} // namespace boost::geometry

Modified: trunk/boost/geometry/extensions/algebra/core/topological_dimension.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/core/topological_dimension.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/core/topological_dimension.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -35,6 +35,9 @@
 //
 //template <>
 //struct top_dim<rotation_quaternion_tag> : boost::mpl::int_<0> {};
+//
+//template <>
+//struct top_dim<rotation_matrix_tag> : boost::mpl::int_<0> {};
 
 } // namespace core_dispatch
 #endif

Modified: trunk/boost/geometry/extensions/algebra/geometries/concepts/check.hpp
==============================================================================
--- trunk/boost/geometry/extensions/algebra/geometries/concepts/check.hpp (original)
+++ trunk/boost/geometry/extensions/algebra/geometries/concepts/check.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -48,6 +48,16 @@
     : detail::concept_check::check<concept::RotationQuaternion<Geometry> >
 {};
 
+template <typename Geometry>
+struct check<Geometry, rotation_matrix_tag, true>
+ : detail::concept_check::check<concept::ConstRotationMatrix<Geometry> >
+{};
+
+template <typename Geometry>
+struct check<Geometry, rotation_matrix_tag, false>
+ : detail::concept_check::check<concept::RotationMatrix<Geometry> >
+{};
+
 } // namespace dispatch
 #endif
 

Added: trunk/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -0,0 +1,141 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/core/coordinate_dimension.hpp>
+#include <boost/geometry/core/access.hpp>
+
+namespace boost { namespace geometry { namespace concept {
+
+template <typename Geometry>
+class RotationMatrix
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ enum { ccount = dimension<Geometry>::value };
+
+ template <typename G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ G* g = 0;
+ geometry::set<I, J>(*g, geometry::get<I, J>(*g));
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(RotationMatrix)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+
+template <typename Geometry>
+class ConstRotationMatrix
+{
+#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
+
+ typedef typename coordinate_type<Geometry>::type ctype;
+ typedef typename coordinate_system<Geometry>::type csystem;
+
+ enum { ccount = dimension<Geometry>::value };
+
+ template <typename G, std::size_t I, std::size_t J, std::size_t N>
+ struct dimension_checker_row
+ {
+ static void apply()
+ {
+ const G* g = 0;
+ ctype coord(geometry::get<I, J>(*g));
+ boost::ignore_unused_variable_warning(coord);
+ dimension_checker_row<G, I, J+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker_row<G, I, N, N>
+ {
+ static void apply() {}
+ };
+
+ template <typename G, std::size_t I, std::size_t N>
+ struct dimension_checker
+ {
+ static void apply()
+ {
+ dimension_checker_row<G, I, 0, N>;
+ dimension_checker<G, I+1, N>::apply();
+ }
+ };
+
+ template <typename G, std::size_t N>
+ struct dimension_checker<G, N, N>
+ {
+ static void apply() {}
+ };
+
+public:
+
+ /// BCCL macro to apply the concept
+ BOOST_CONCEPT_USAGE(ConstRotationMatrix)
+ {
+ static const bool cs_check = ::boost::is_same<csystem, cs::cartesian>::value;
+ BOOST_MPL_ASSERT_MSG(cs_check, NOT_IMPLEMENTED_FOR_THIS_CS, (csystem));
+
+ dimension_checker<Geometry, 0, ccount>::apply();
+ }
+#endif
+};
+
+}}} // namespace boost::geometry::concept
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_CONCEPTS_ROTATION_MATRIX_CONCEPT_HPP

Added: trunk/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/algebra/geometries/rotation_matrix.hpp 2013-05-30 15:24:46 EDT (Thu, 30 May 2013)
@@ -0,0 +1,117 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP
+
+#include <cstddef>
+
+#include <boost/geometry/extensions/algebra/core/tags.hpp>
+#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
+
+namespace boost { namespace geometry {
+
+namespace model {
+
+template <typename T, std::size_t Dimension>
+class rotation_matrix
+{
+ BOOST_CONCEPT_ASSERT( (concept::RotationMatrix<rotation_matrix>) );
+
+public:
+
+ /// @brief Default constructor, no initialization
+ inline rotation_matrix()
+ {}
+
+ /// @brief Get a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @return the cell value
+ template <std::size_t I, std::size_t J>
+ inline T const& get() const
+ {
+ BOOST_STATIC_ASSERT(I < Dimension);
+ BOOST_STATIC_ASSERT(J < Dimension);
+ return m_values[I * Dimension + J];
+ }
+
+ /// @brief Set a coordinate
+ /// @tparam I row index
+ /// @tparam J col index
+ /// @param value value to set
+ template <std::size_t I, std::size_t J>
+ inline void set(T const& value)
+ {
+ BOOST_STATIC_ASSERT(I < Dimension);
+ BOOST_STATIC_ASSERT(J < Dimension);
+ m_values[I * Dimension + J] = value;
+ }
+
+private:
+
+ T m_values[Dimension * Dimension];
+};
+
+} // namespace model
+
+#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+namespace traits
+{
+
+template <typename CoordinateType, std::size_t Dimension>
+struct tag<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef rotation_matrix_tag type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct coordinate_type<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef CoordinateType type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct coordinate_system<model::rotation_matrix<CoordinateType, Dimension> >
+{
+ typedef cs::cartesian type;
+};
+
+template <typename CoordinateType, std::size_t Dimension>
+struct dimension<model::rotation_matrix<CoordinateType, Dimension> >
+ : boost::mpl::int_<Dimension>
+{};
+
+template <typename CoordinateType, std::size_t Dimension, std::size_t I, std::size_t J>
+struct indexed_access<model::rotation_matrix<CoordinateType, Dimension>, I, J>
+{
+ typedef CoordinateType coordinate_type;
+
+ static inline coordinate_type get(model::rotation_matrix<CoordinateType, Dimension> const& m)
+ {
+ return m.template get<I, J>();
+ }
+
+ static inline void set(model::rotation_matrix<CoordinateType, Dimension> & m, coordinate_type const& value)
+ {
+ m.template set<I, J>(value);
+ }
+};
+
+} // namespace traits
+#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_GEOMETRIES_ROTATION_MATRIX_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk