[geometry]: [index] improved margin and content, [extensions] nsphere - fixed disjoint/intersects, added content, margin, is_valid.

[SVN r84830]
This commit is contained in:
Adam Wulkiewicz
2013-06-18 22:51:33 +00:00
parent c583fb2eb5
commit 8e11107a2c
8 changed files with 269 additions and 22 deletions

View File

@@ -132,7 +132,7 @@ struct disjoint<Point, NSphere, DimensionCount, point_tag, nsphere_tag, Reverse>
static inline bool apply(Point const& p, NSphere const& s)
{
typedef typename coordinate_system<Point>::type p_cs;
typedef typename typename coordinate_system<NSphere>::type s_cs;
typedef typename coordinate_system<NSphere>::type s_cs;
static const bool check_cs = ::boost::is_same<p_cs, cs::cartesian>::value && ::boost::is_same<s_cs, cs::cartesian>::value;
BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (p_cs, s_cs));
@@ -149,7 +149,7 @@ struct disjoint<NSphere, Box, DimensionCount, nsphere_tag, box_tag, Reverse>
static inline bool apply(NSphere const& s, Box const& b)
{
typedef typename coordinate_system<Box>::type b_cs;
typedef typename typename coordinate_system<NSphere>::type s_cs;
typedef typename coordinate_system<NSphere>::type s_cs;
static const bool check_cs = ::boost::is_same<b_cs, cs::cartesian>::value && ::boost::is_same<s_cs, cs::cartesian>::value;
BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (b_cs, s_cs));
@@ -165,15 +165,20 @@ struct disjoint<NSphere1, NSphere2, DimensionCount, nsphere_tag, nsphere_tag, Re
{
static inline bool apply(NSphere1 const& s1, NSphere2 const& s2)
{
typedef typename typename coordinate_system<NSphere1>::type s1_cs;
typedef typename typename coordinate_system<NSphere2>::type s2_cs;
typedef typename coordinate_system<NSphere1>::type s1_cs;
typedef typename coordinate_system<NSphere2>::type s2_cs;
static const bool check_cs = ::boost::is_same<s1_cs, cs::cartesian>::value && ::boost::is_same<s2_cs, cs::cartesian>::value;
BOOST_MPL_ASSERT_MSG(check_cs, NOT_IMPLEMENTED_FOR_THOSE_COORDINATE_SYSTEMS, (s1_cs, s2_cs));
return get_radius<0>(s1) + get_radius<0>(s2)
/*return get_radius<0>(s1) + get_radius<0>(s2)
< ::sqrt(geometry::detail::disjoint::points_or_spheres_comparable_distance_cartesian<
Point, NSphere, 0, DimensionCount
>::apply(p, s));
NSphere1, NSphere2, 0, DimensionCount
>::apply(s1, s2));*/
return get_radius<0>(s1) * get_radius<0>(s1) + 2 * get_radius<0>(s1) * get_radius<0>(s2) + get_radius<0>(s2) * get_radius<0>(s2)
< geometry::detail::disjoint::points_or_spheres_comparable_distance_cartesian<
NSphere1, NSphere2, 0, DimensionCount
>::apply(s1, s2);
}
};

View File

@@ -0,0 +1,76 @@
// Boost.Geometry Index
//
// n-dimensional content (hypervolume) - 2d area, 3d volume, ...
//
// Copyright (c) 2011-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_NSPHERE_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP
#include <boost/geometry/index/detail/algorithms/content.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
// TODO replace it by comparable_content?
// probably radius^Dimension would be sufficient
// WARNING! this would work only if the same Geometries were compared
// so it shouldn't be used in the case of Variants!
// The same with margin()!
template <typename NSphere, size_t Dimension>
struct content_nsphere
{
BOOST_STATIC_ASSERT(2 < Dimension);
typedef typename detail::default_content_result<NSphere>::type result_type;
static inline result_type apply(NSphere const& s)
{
return (content_nsphere<NSphere, Dimension - 2>::apply(s)
* 2 * get_radius<0>(s) * get_radius<0>(s)
* ::boost::math::constants::pi<result_type>()) / Dimension;
}
};
template <typename NSphere>
struct content_nsphere<NSphere, 2>
{
typedef typename detail::default_content_result<NSphere>::type result_type;
static inline result_type apply(NSphere const& s)
{
return ::boost::math::constants::pi<result_type>() * get_radius<0>(s) * get_radius<0>(s);
}
};
template <typename NSphere>
struct content_nsphere<NSphere, 1>
{
typedef typename detail::default_content_result<NSphere>::type result_type;
static inline result_type apply(NSphere const& s)
{
return 2 * get_radius<0>(s);
}
};
template <typename Indexable>
struct content<Indexable, nsphere_tag>
{
static typename default_content_result<Indexable>::type apply(Indexable const& i)
{
return dispatch::content_nsphere<Indexable, detail::traits::dimension<Indexable>::value>::apply(i);
}
};
} // namespace dispatch
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_CONTENT_HPP

View File

@@ -0,0 +1,33 @@
// Boost.Geometry Index
//
// n-dimensional Indexable validity check
//
// Copyright (c) 2011-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_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#define BOOST_GEOMETRY_EXTENSIONS_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP
#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
template <typename Indexable>
struct is_valid<Indexable, nsphere_tag>
{
static inline bool apply(Indexable const& i)
{
return 0 <= geometry::get_radius<0>(i);
}
};
} // namespace dispatch
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_EXTENSIONS_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP

View File

@@ -0,0 +1,59 @@
// Boost.Geometry Index
//
// n-dimensional margin value (hypersurface), 2d perimeter, 3d surface, etc...
//
// Copyright (c) 2011-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_NSPHERE_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP
#include <boost/geometry/index/detail/algorithms/margin.hpp>
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename NSphere, size_t Dimension>
struct comparable_margin_nsphere
{
BOOST_STATIC_ASSERT(1 < Dimension);
BOOST_STATIC_ASSERT(Dimension <= detail::traits::dimension<NSphere>::value);
static inline typename default_margin_result<NSphere>::type apply(NSphere const& s)
{
return comparable_margin_nsphere<NSphere, Dimension-1>::apply(s)
* geometry::get_radius<0>(s);
}
};
template <typename NSphere>
struct comparable_margin_nsphere<NSphere, 1>
{
static inline typename default_margin_result<NSphere>::type apply(NSphere const& s)
{
return 1;
}
};
namespace dispatch {
template <typename NSphere>
struct comparable_margin<NSphere, nsphere_tag>
{
typedef typename default_margin_result<NSphere>::type result_type;
static inline result_type apply(NSphere const& g)
{
return comparable_margin_nsphere<
NSphere, dimension<NSphere>::value
>::apply(g);
}
};
} // namespace dispatch
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_ALGORITHMS_MARGIN_HPP

View File

@@ -0,0 +1,30 @@
// Boost.Geometry Index
//
// Indexable's traits and related functions
//
// Copyright (c) 2011-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)
#include <boost/geometry/index/detail/indexable.hpp>
#ifndef BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP
#define BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP
namespace boost { namespace geometry { namespace index { namespace detail {
namespace dispatch {
template <typename Indexable>
struct point_type<Indexable, geometry::nsphere_tag>
{
typedef typename geometry::traits::point_type<Indexable>::type type;
};
} // namespace dispatch
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_INDEX_DETAIL_INDEXABLE_HPP

View File

@@ -35,4 +35,9 @@
#include <boost/geometry/extensions/nsphere/algorithms/within.hpp>
#include <boost/geometry/extensions/nsphere/algorithms/disjoint.hpp>
#include <boost/geometry/extensions/nsphere/index/detail/indexable.hpp>
#include <boost/geometry/extensions/nsphere/index/detail/algorithms/content.hpp>
#include <boost/geometry/extensions/nsphere/index/detail/algorithms/is_valid.hpp>
#include <boost/geometry/extensions/nsphere/index/detail/algorithms/margin.hpp>
#endif // BOOST_GEOMETRY_EXTENSIONS_NSPHERE_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry Index
//
// n-dimensional box's content (hypervolume) - 2d area, 3d volume, ...
// n-dimensional content (hypervolume) - 2d area, 3d volume, ...
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
@@ -19,7 +19,7 @@ template <typename Indexable>
struct default_content_result
{
typedef typename select_most_precise<
typename detail::traits::coordinate_type<Indexable>::type,
typename coordinate_type<Indexable>::type,
long double
>::type type;
};
@@ -27,20 +27,20 @@ struct default_content_result
namespace dispatch {
template <typename Box, size_t CurrentDimension>
struct content_for_each_dimension
struct content_box
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
//BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension<Box>::value);
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
return content_for_each_dimension<Box, CurrentDimension - 1>::apply(b) *
return content_box<Box, CurrentDimension - 1>::apply(b) *
( detail::get<max_corner, CurrentDimension - 1>(b) - detail::get<min_corner, CurrentDimension - 1>(b) );
}
};
template <typename Box>
struct content_for_each_dimension<Box, 1>
struct content_box<Box, 1>
{
static inline typename detail::default_content_result<Box>::type apply(Box const& b)
{
@@ -51,7 +51,7 @@ struct content_for_each_dimension<Box, 1>
template <typename Indexable, typename Tag>
struct content
{
// TODO: awulkiew - static assert?
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_INDEXABLE_AND_TAG, (Indexable, Tag));
};
template <typename Indexable>
@@ -68,7 +68,7 @@ struct content<Indexable, box_tag>
{
static typename default_content_result<Indexable>::type apply(Indexable const& b)
{
return dispatch::content_for_each_dimension<Indexable, detail::traits::dimension<Indexable>::value>::apply(b);
return dispatch::content_box<Indexable, dimension<Indexable>::value>::apply(b);
}
};
@@ -78,7 +78,7 @@ template <typename Indexable>
typename default_content_result<Indexable>::type content(Indexable const& b)
{
return dispatch::content<Indexable,
typename detail::traits::tag<Indexable>::type
typename tag<Indexable>::type
>::apply(b);
}

View File

@@ -13,6 +13,9 @@
#include <boost/geometry/index/detail/indexable.hpp>
// WARNING! comparable_margin() will work only if the same Geometries are compared
// so it shouldn't be used in the case of Variants!
namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Box>
@@ -90,11 +93,15 @@ struct default_margin_result
// }
//};
// TODO - test if this definition of margin is ok for Dimension > 2
// Now it's sum of edges lengths
// maybe margin_for_each_dimension should be used to get more or less hypersurface?
template <typename Box, size_t CurrentDimension>
struct simple_margin_for_each_dimension
{
BOOST_STATIC_ASSERT(0 < CurrentDimension);
BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension<Box>::value);
//BOOST_STATIC_ASSERT(CurrentDimension <= dimension<Box>::value);
static inline typename default_margin_result<Box>::type apply(Box const& b)
{
@@ -112,17 +119,49 @@ struct simple_margin_for_each_dimension<Box, 1>
}
};
template <typename Box>
typename default_margin_result<Box>::type comparable_margin(Box const& b)
namespace dispatch {
template <typename Geometry, typename Tag>
struct comparable_margin
{
//return detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
return detail::simple_margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_GEOMETRY, (Geometry, Tag));
};
template <typename Geometry>
struct comparable_margin<Geometry, point_tag>
{
typedef typename default_margin_result<Geometry>::type result_type;
static inline result_type apply(Geometry const& g) { return 0; }
};
template <typename Box>
struct comparable_margin<Box, box_tag>
{
typedef typename default_margin_result<Box>::type result_type;
static inline result_type apply(Box const& g)
{
//return detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
return detail::simple_margin_for_each_dimension<Box, dimension<Box>::value>::apply(g);
}
};
} // namespace dispatch
template <typename Geometry>
typename default_margin_result<Geometry>::type comparable_margin(Geometry const& g)
{
return dispatch::comparable_margin<
Geometry,
typename tag<Geometry>::type
>::apply(g);
}
//template <typename Box>
//typename default_margin_result<Box>::type margin(Box const& b)
//{
// return 2 * detail::margin_for_each_dimension<Box, detail::traits::dimension<Box>::value>::apply(b);
// return 2 * detail::margin_for_each_dimension<Box, dimension<Box>::value>::apply(b);
//}
}}}} // namespace boost::geometry::index::detail