geometry extensions: added experimental clear() and reverse() for translations/vectors (assigning zeros and negating) and rotations (assigning identity and calculating invese/conjugate)

[SVN r84615]
This commit is contained in:
Adam Wulkiewicz
2013-06-02 23:53:12 +00:00
parent 6aad0216e8
commit 754989b0ae
7 changed files with 222 additions and 1 deletions

View File

@@ -33,8 +33,14 @@
#include <boost/geometry/extensions/algebra/algorithms/assign.hpp>
#include <boost/geometry/extensions/algebra/algorithms/convert.hpp>
// experimental
#include <boost/geometry/extensions/algebra/algorithms/clear.hpp>
#include <boost/geometry/extensions/algebra/algorithms/reverse.hpp>
#include <boost/geometry/extensions/algebra/algorithms/translation.hpp>
#include <boost/geometry/extensions/algebra/algorithms/rotation.hpp>
// should be removed, transform() should be used instead
#include <boost/geometry/extensions/algebra/algorithms/transform_geometrically.hpp>
#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGEBRA_HPP

View File

@@ -69,6 +69,9 @@ struct assign_identity<rotation_matrix_tag, R>
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
// TODO
// Use assign_zero for initialization of 0-angle rotation instead of assign_identity?
/*!
\brief assign identity to Transformation
\ingroup assign
@@ -117,7 +120,6 @@ struct assign<vector_tag, V, 3>
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -0,0 +1,64 @@
// 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_ALGORITHMS_CLEAR_HPP
#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/extensions/algebra/algorithms/assign.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// This is experimental implementation of clear() which assigns zeros to vectors
// and identities to rotations. It doesn't work for them as for Geometries.
template <typename Vector>
struct clear<Vector, vector_tag>
{
static inline void apply(Vector & v)
{
geometry::assign_zero(v);
}
};
template <typename R>
struct clear<R, rotation_quaternion_tag>
{
static inline void apply(R & r)
{
geometry::assign_identity(r);
}
};
template <typename R>
struct clear<R, rotation_matrix_tag>
{
static inline void apply(R & r)
{
geometry::assign_identity(r);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP

View File

@@ -9,6 +9,9 @@
#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_DETAIL_HPP
// TODO - for multiplication of coordinates
// if coordinate_type is_integral - use double as the result type
namespace boost { namespace geometry
{
@@ -93,6 +96,32 @@ inline static void mul(S & s, T const& v)
return mul_impl<S, T, IS, 0, N>::apply(s, v);
}
// Negation
template <typename V, std::size_t I, std::size_t N>
struct neg_impl
{
BOOST_STATIC_ASSERT(0 < N);
static inline void apply(V & v)
{
set<I>(v, -get<I>(v));
neg_impl<V, I+1, N>::apply(v);
}
};
template <typename V, std::size_t N>
struct neg_impl<V, N, N>
{
static inline void apply(V &) {}
};
template <std::size_t I, std::size_t N, typename V>
inline static void neg(V & v)
{
return neg_impl<V, I, N>::apply(v);
}
// Normalization of N components starting from Ith
template <std::size_t I, std::size_t N, typename S>
@@ -151,6 +180,8 @@ struct matrix_mul_impl<M, V, VD, N, N>
static inline void apply(M const&, V const&, VD &) {}
};
// Matrix rotation - M*V
template <typename M, typename V, typename VD>
inline static void matrix_rotate(M const& m, V const& v, VD & vd)
{
@@ -159,6 +190,8 @@ inline static void matrix_rotate(M const& m, V const& v, VD & vd)
matrix_mul_impl<M, V, VD, 0, dimension>::apply(m, v, vd);
}
// Quaternion rotation - Q*V*Q' - * is Hamilton product
template <typename V, typename Q>
inline static void quaternion_rotate(V & v, Q const& r)
{
@@ -180,6 +213,8 @@ inline static void quaternion_rotate(V & v, Q const& r)
set<2>(v, - a * get<3>(r) - b * get<2>(r) + c * get<1>(r) + d * get<0>(r));
}
// Assign value
template <typename G, typename V, std::size_t B, std::size_t E>
struct assign_value
{
@@ -206,6 +241,8 @@ struct indexed_assign_value_per_index
}
};
// Assign value using indexed access
template <typename G, typename V, std::size_t BI, std::size_t EI, std::size_t ED>
struct indexed_assign_value_per_index<G, V, BI, ED, EI, ED>
{
@@ -238,6 +275,8 @@ struct identity_matrix_per_index
}
};
// Identity matrix
template <typename G, std::size_t BI, std::size_t EI, std::size_t ED>
struct identity_matrix_per_index<G, BI, BI, EI, ED>
{
@@ -270,6 +309,43 @@ struct identity_matrix<G, EI, BD, EI, ED>
static inline void apply(G &) {}
};
// Matrix transpose
template <typename G, std::size_t I, std::size_t D, std::size_t N>
struct matrix_transpose_per_index
{
static inline void apply(G & g)
{
// swap coordinates
typename coordinate_type<G>::type tmp = get<I, D>(g);
set<I, D>(g, get<D, I>(g));
set<D, I>(g, tmp);
matrix_transpose_per_index<G, I, D+1, N>::apply(g);
}
};
template <typename G, std::size_t I, std::size_t N>
struct matrix_transpose_per_index<G, I, N, N>
{
static inline void apply(G &) {}
};
template <typename G, std::size_t I, std::size_t D, std::size_t N>
struct matrix_transpose
{
static inline void apply(G & g)
{
matrix_transpose_per_index<G, I, I+1, N>::apply(g);
matrix_transpose<G, I+1, D, N>::apply(g);
}
};
template <typename G, std::size_t D, std::size_t N>
struct matrix_transpose<G, N, D, N>
{
static inline void apply(G &) {}
};
}} // namespace detail::algebra
#endif // DOXYGEN_NO_DETAIL

View File

@@ -0,0 +1,66 @@
// 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_ALGORITHMS_REVERSE_HPP
#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_REVERSE_HPP
#include <boost/geometry/algorithms/reverse.hpp>
#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// This is experimental implementation of reverse() which negates vectors
// and inverses rotations. It doesn't work for them as for Geometries.
template <typename Vector>
struct reverse<Vector, vector_tag>
{
static inline void apply(Vector & v)
{
detail::algebra::neg<0, dimension<Vector>::value>(v);
}
};
template <typename R>
struct reverse<R, rotation_quaternion_tag>
{
static inline void apply(R & r)
{
detail::algebra::neg<1, 4>(r);
}
};
template <typename R>
struct reverse<R, rotation_matrix_tag>
{
static inline void apply(R & r)
{
detail::algebra::matrix_transpose<
R, 0, 0, dimension<R>::value
>::apply(r);
}
};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_CLEAR_HPP

View File

@@ -13,6 +13,9 @@
#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
// TODO - for multiplication of coordinates
// if coordinate_type is_integral - use double as the result type
namespace boost { namespace geometry {
namespace detail { namespace rotation {

View File

@@ -20,6 +20,10 @@
#include <boost/geometry/extensions/algebra/core/tags.hpp>
#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
// WARNING!
// It is probable that the sequence of coordinate will change in the future
// at the beginning there would be xyz, w would become the last coordinate
namespace boost { namespace geometry
{