You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
319 lines
7.9 KiB
319 lines
7.9 KiB
// Boost.Geometry (aka GGL, Generic Geometry Library) |
|
|
|
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands. |
|
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France. |
|
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK. |
|
|
|
// 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_ALGORITHMS_EXPAND_HPP |
|
#define BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP |
|
|
|
|
|
#include <cstddef> |
|
|
|
#include <boost/numeric/conversion/cast.hpp> |
|
|
|
#include <boost/geometry/core/coordinate_dimension.hpp> |
|
#include <boost/geometry/geometries/concepts/check.hpp> |
|
|
|
#include <boost/geometry/util/select_coordinate_type.hpp> |
|
|
|
#include <boost/geometry/strategies/compare.hpp> |
|
#include <boost/geometry/policies/compare.hpp> |
|
|
|
|
|
namespace boost { namespace geometry |
|
{ |
|
|
|
#ifndef DOXYGEN_NO_DETAIL |
|
namespace detail { namespace expand |
|
{ |
|
|
|
|
|
template |
|
< |
|
typename Box, typename Point, |
|
typename StrategyLess, typename StrategyGreater, |
|
std::size_t Dimension, std::size_t DimensionCount |
|
> |
|
struct point_loop |
|
{ |
|
typedef typename strategy::compare::detail::select_strategy |
|
< |
|
StrategyLess, 1, Point, Dimension |
|
>::type less_type; |
|
|
|
typedef typename strategy::compare::detail::select_strategy |
|
< |
|
StrategyGreater, -1, Point, Dimension |
|
>::type greater_type; |
|
|
|
typedef typename select_coordinate_type<Point, Box>::type coordinate_type; |
|
|
|
static inline void apply(Box& box, Point const& source) |
|
{ |
|
less_type less; |
|
greater_type greater; |
|
|
|
coordinate_type const coord = get<Dimension>(source); |
|
|
|
if (less(coord, get<min_corner, Dimension>(box))) |
|
{ |
|
set<min_corner, Dimension>(box, coord); |
|
} |
|
|
|
if (greater(coord, get<max_corner, Dimension>(box))) |
|
{ |
|
set<max_corner, Dimension>(box, coord); |
|
} |
|
|
|
point_loop |
|
< |
|
Box, Point, |
|
StrategyLess, StrategyGreater, |
|
Dimension + 1, DimensionCount |
|
>::apply(box, source); |
|
} |
|
}; |
|
|
|
|
|
template |
|
< |
|
typename Box, typename Point, |
|
typename StrategyLess, typename StrategyGreater, |
|
std::size_t DimensionCount |
|
> |
|
struct point_loop |
|
< |
|
Box, Point, |
|
StrategyLess, StrategyGreater, |
|
DimensionCount, DimensionCount |
|
> |
|
{ |
|
static inline void apply(Box&, Point const&) {} |
|
}; |
|
|
|
|
|
template |
|
< |
|
typename Box, typename Geometry, |
|
typename StrategyLess, typename StrategyGreater, |
|
std::size_t Index, |
|
std::size_t Dimension, std::size_t DimensionCount |
|
> |
|
struct indexed_loop |
|
{ |
|
typedef typename strategy::compare::detail::select_strategy |
|
< |
|
StrategyLess, 1, Box, Dimension |
|
>::type less_type; |
|
|
|
typedef typename strategy::compare::detail::select_strategy |
|
< |
|
StrategyGreater, -1, Box, Dimension |
|
>::type greater_type; |
|
|
|
typedef typename select_coordinate_type |
|
< |
|
Box, |
|
Geometry |
|
>::type coordinate_type; |
|
|
|
|
|
static inline void apply(Box& box, Geometry const& source) |
|
{ |
|
less_type less; |
|
greater_type greater; |
|
|
|
coordinate_type const coord = get<Index, Dimension>(source); |
|
|
|
if (less(coord, get<min_corner, Dimension>(box))) |
|
{ |
|
set<min_corner, Dimension>(box, coord); |
|
} |
|
|
|
if (greater(coord, get<max_corner, Dimension>(box))) |
|
{ |
|
set<max_corner, Dimension>(box, coord); |
|
} |
|
|
|
indexed_loop |
|
< |
|
Box, Geometry, |
|
StrategyLess, StrategyGreater, |
|
Index, Dimension + 1, DimensionCount |
|
>::apply(box, source); |
|
} |
|
}; |
|
|
|
|
|
template |
|
< |
|
typename Box, typename Geometry, |
|
typename StrategyLess, typename StrategyGreater, |
|
std::size_t Index, std::size_t DimensionCount |
|
> |
|
struct indexed_loop |
|
< |
|
Box, Geometry, |
|
StrategyLess, StrategyGreater, |
|
Index, DimensionCount, DimensionCount |
|
> |
|
{ |
|
static inline void apply(Box&, Geometry const&) {} |
|
}; |
|
|
|
|
|
|
|
// Changes a box such that the other box is also contained by the box |
|
template |
|
< |
|
typename Box, typename Geometry, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
struct expand_indexed |
|
{ |
|
static inline void apply(Box& box, Geometry const& geometry) |
|
{ |
|
indexed_loop |
|
< |
|
Box, Geometry, |
|
StrategyLess, StrategyGreater, |
|
0, 0, dimension<Geometry>::type::value |
|
>::apply(box, geometry); |
|
|
|
indexed_loop |
|
< |
|
Box, Geometry, |
|
StrategyLess, StrategyGreater, |
|
1, 0, dimension<Geometry>::type::value |
|
>::apply(box, geometry); |
|
} |
|
}; |
|
|
|
}} // namespace detail::expand |
|
#endif // DOXYGEN_NO_DETAIL |
|
|
|
#ifndef DOXYGEN_NO_DISPATCH |
|
namespace dispatch |
|
{ |
|
|
|
template |
|
< |
|
typename Tag, |
|
typename BoxOut, typename Geometry, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
struct expand |
|
{}; |
|
|
|
|
|
// Box + point -> new box containing also point |
|
template |
|
< |
|
typename BoxOut, typename Point, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
struct expand<point_tag, BoxOut, Point, StrategyLess, StrategyGreater> |
|
: detail::expand::point_loop |
|
< |
|
BoxOut, Point, |
|
StrategyLess, StrategyGreater, |
|
0, dimension<Point>::type::value |
|
> |
|
{}; |
|
|
|
|
|
// Box + box -> new box containing two input boxes |
|
template |
|
< |
|
typename BoxOut, typename BoxIn, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
struct expand<box_tag, BoxOut, BoxIn, StrategyLess, StrategyGreater> |
|
: detail::expand::expand_indexed |
|
<BoxOut, BoxIn, StrategyLess, StrategyGreater> |
|
{}; |
|
|
|
template |
|
< |
|
typename Box, typename Segment, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
struct expand<segment_tag, Box, Segment, StrategyLess, StrategyGreater> |
|
: detail::expand::expand_indexed |
|
<Box, Segment, StrategyLess, StrategyGreater> |
|
{}; |
|
|
|
|
|
} // namespace dispatch |
|
#endif // DOXYGEN_NO_DISPATCH |
|
|
|
|
|
/*** |
|
*! |
|
\brief Expands a box using the extend (envelope) of another geometry (box, point) |
|
\ingroup expand |
|
\tparam Box type of the box |
|
\tparam Geometry of second geometry, to be expanded with the box |
|
\param box box to expand another geometry with, might be changed |
|
\param geometry other geometry |
|
\param strategy_less |
|
\param strategy_greater |
|
\note Strategy is currently ignored |
|
* |
|
template |
|
< |
|
typename Box, typename Geometry, |
|
typename StrategyLess, typename StrategyGreater |
|
> |
|
inline void expand(Box& box, Geometry const& geometry, |
|
StrategyLess const& strategy_less, |
|
StrategyGreater const& strategy_greater) |
|
{ |
|
concept::check_concepts_and_equal_dimensions<Box, Geometry const>(); |
|
|
|
dispatch::expand |
|
< |
|
typename tag<Geometry>::type, |
|
Box, |
|
Geometry, |
|
StrategyLess, StrategyGreater |
|
>::apply(box, geometry); |
|
} |
|
***/ |
|
|
|
|
|
/*! |
|
\brief Expands a box using the bounding box (envelope) of another geometry (box, point) |
|
\ingroup expand |
|
\tparam Box type of the box |
|
\tparam Geometry \tparam_geometry |
|
\param box box to be expanded using another geometry, mutable |
|
\param geometry \param_geometry geometry which envelope (bounding box) will be added to the box |
|
|
|
\qbk{[include reference/algorithms/expand.qbk]} |
|
*/ |
|
template <typename Box, typename Geometry> |
|
inline void expand(Box& box, Geometry const& geometry) |
|
{ |
|
concept::check_concepts_and_equal_dimensions<Box, Geometry const>(); |
|
|
|
dispatch::expand |
|
< |
|
typename tag<Geometry>::type, |
|
Box, Geometry, |
|
strategy::compare::default_strategy, |
|
strategy::compare::default_strategy |
|
>::apply(box, geometry); |
|
} |
|
|
|
}} // namespace boost::geometry |
|
|
|
#endif // BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
|
|