1
// Generic Geometry Library
3
// Copyright Barend Gehrels 1995-2009, Geodan Holding B.V. Amsterdam, the Netherlands.
4
// Copyright Bruno Lalande 2008, 2009
5
// Use, modification and distribution is subject to the Boost Software License,
6
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
9
#ifndef GGL_ALGORITHMS_COMBINE_HPP
10
#define GGL_ALGORITHMS_COMBINE_HPP
14
#include <boost/numeric/conversion/cast.hpp>
16
#include <ggl/arithmetic/arithmetic.hpp>
17
#include <ggl/core/coordinate_dimension.hpp>
18
#include <ggl/core/concepts/box_concept.hpp>
19
#include <ggl/core/concepts/point_concept.hpp>
20
#include <ggl/util/assign_box_corner.hpp>
21
#include <ggl/util/select_coordinate_type.hpp>
24
\defgroup combine combine: add a geometry to a bounding box
26
- BOX + BOX -> BOX: the box will be combined with the other box \image html combine_box_box.png
27
- BOX + POINT -> BOX: the box will combined with the point \image html combine_box_point.png
28
\note Previously called "grow"
33
#ifndef DOXYGEN_NO_DETAIL
34
namespace detail { namespace combine {
38
typename Box, typename Point,
39
std::size_t Dimension, std::size_t DimensionCount
43
typedef typename coordinate_type<Point>::type coordinate_type;
45
static inline void apply(Box& box, Point const& source)
47
coordinate_type const coord = get<Dimension>(source);
49
if (coord < get<min_corner, Dimension>(box))
51
set<min_corner, Dimension>(box, coord );
54
if (coord > get<max_corner, Dimension>(box))
56
set<max_corner, Dimension>(box, coord);
59
point_loop<Box, Point, Dimension + 1, DimensionCount>::apply(box, source);
66
typename Box, typename Point,
67
std::size_t DimensionCount
69
struct point_loop<Box, Point, DimensionCount, DimensionCount>
71
static inline void apply(Box&, Point const&) {}
77
typename BoxIn, typename BoxOut,
79
std::size_t Dimension, std::size_t DimensionCount
83
typedef typename select_coordinate_type<BoxIn, BoxOut>::type coordinate_type;
85
static inline void apply(BoxIn& box, BoxOut const& source)
87
coordinate_type const coord = get<Corner, Dimension>(source);
89
if (coord < get<min_corner, Dimension>(box))
91
set<min_corner, Dimension>(box, coord);
94
if (coord > get<max_corner, Dimension>(box))
96
set<max_corner, Dimension>(box, coord);
101
BoxIn, BoxOut, Corner, Dimension + 1, DimensionCount
102
>::apply(box, source);
109
typename BoxIn, typename BoxOut,
110
std::size_t Corner, std::size_t DimensionCount
112
struct box_loop<BoxIn, BoxOut, Corner, DimensionCount, DimensionCount>
114
static inline void apply(BoxIn&, BoxOut const&) {}
118
// Changes a box b such that it also contains point p
119
template<typename Box, typename Point>
120
struct combine_box_with_point
121
: point_loop<Box, Point, 0, dimension<Point>::type::value>
125
// Changes a box such that the other box is also contained by the box
126
template<typename BoxOut, typename BoxIn>
127
struct combine_box_with_box
129
static inline void apply(BoxOut& b, BoxIn const& other)
131
box_loop<BoxOut, BoxIn, min_corner, 0,
132
dimension<BoxIn>::type::value>::apply(b, other);
133
box_loop<BoxOut, BoxIn, max_corner, 0,
134
dimension<BoxIn>::type::value>::apply(b, other);
138
}} // namespace detail::combine
139
#endif // DOXYGEN_NO_DETAIL
141
#ifndef DOXYGEN_NO_DISPATCH
145
template <typename Tag, typename BoxOut, typename Geometry>
150
// Box + point -> new box containing also point
151
template <typename BoxOut, typename Point>
152
struct combine<point_tag, BoxOut, Point>
153
: detail::combine::combine_box_with_point<BoxOut, Point>
157
// Box + box -> new box containing two input boxes
158
template <typename BoxOut, typename BoxIn>
159
struct combine<box_tag, BoxOut, BoxIn>
160
: detail::combine::combine_box_with_box<BoxOut, BoxIn>
164
} // namespace dispatch
165
#endif // DOXYGEN_NO_DISPATCH
169
\brief Combines a box with another geometry (box, point)
171
\tparam Box type of the box
172
\tparam Geometry of second geometry, to be combined with the box
173
\param box box to combine another geometry with, might be changed
174
\param geometry other geometry
176
template <typename Box, typename Geometry>
177
inline void combine(Box& box, Geometry const& geometry)
179
assert_dimension_equal<Box, Geometry>();
182
typename tag<Geometry>::type,
184
>::apply(box, geometry);
189
#endif // GGL_COMBINE_HPP