$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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