]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. | |
5 | // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. | |
6 | // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. | |
7 | ||
8 | // This file was modified by Oracle on 2013-2016. | |
9 | // Modifications copyright (c) 2013-2016, Oracle and/or its affiliates. | |
10 | ||
11 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
12 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle | |
13 | ||
14 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
15 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
16 | ||
17 | // Use, modification and distribution is subject to the Boost Software License, | |
18 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
19 | // http://www.boost.org/LICENSE_1_0.txt) | |
20 | ||
21 | #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_BOX_BOX_HPP | |
22 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_BOX_BOX_HPP | |
23 | ||
24 | #include <cstddef> | |
25 | ||
26 | #include <boost/geometry/core/access.hpp> | |
27 | #include <boost/geometry/core/tags.hpp> | |
28 | ||
29 | #include <boost/geometry/algorithms/dispatch/disjoint.hpp> | |
30 | ||
31 | #include <boost/geometry/util/normalize_spheroidal_coordinates.hpp> | |
32 | #include <boost/geometry/util/select_most_precise.hpp> | |
33 | ||
34 | ||
35 | namespace boost { namespace geometry | |
36 | { | |
37 | ||
38 | #ifndef DOXYGEN_NO_DETAIL | |
39 | namespace detail { namespace disjoint | |
40 | { | |
41 | ||
42 | template | |
43 | < | |
44 | typename Box1, typename Box2, | |
45 | std::size_t Dimension = 0, | |
46 | std::size_t DimensionCount = dimension<Box1>::value, | |
47 | typename CSTag = typename tag_cast | |
48 | < | |
49 | typename cs_tag<Box1>::type, | |
50 | spherical_tag | |
51 | >::type | |
52 | > | |
53 | struct box_box | |
54 | { | |
55 | static inline bool apply(Box1 const& box1, Box2 const& box2) | |
56 | { | |
57 | if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2)) | |
58 | { | |
59 | return true; | |
60 | } | |
61 | if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2)) | |
62 | { | |
63 | return true; | |
64 | } | |
65 | return box_box | |
66 | < | |
67 | Box1, Box2, | |
68 | Dimension + 1, DimensionCount | |
69 | >::apply(box1, box2); | |
70 | } | |
71 | }; | |
72 | ||
73 | ||
74 | template <typename Box1, typename Box2, std::size_t DimensionCount, typename CSTag> | |
75 | struct box_box<Box1, Box2, DimensionCount, DimensionCount, CSTag> | |
76 | { | |
77 | static inline bool apply(Box1 const& , Box2 const& ) | |
78 | { | |
79 | return false; | |
80 | } | |
81 | }; | |
82 | ||
83 | ||
84 | template <typename Box1, typename Box2, std::size_t DimensionCount> | |
85 | struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag> | |
86 | { | |
87 | static inline bool apply(Box1 const& box1, Box2 const& box2) | |
88 | { | |
89 | typedef typename geometry::select_most_precise | |
90 | < | |
91 | typename coordinate_type<Box1>::type, | |
92 | typename coordinate_type<Box2>::type | |
93 | >::type calc_t; | |
94 | typedef typename coordinate_system<Box1>::type::units units_t; | |
95 | typedef math::detail::constants_on_spheroid<calc_t, units_t> constants; | |
96 | ||
97 | calc_t const b1_min = get<min_corner, 0>(box1); | |
98 | calc_t const b1_max = get<max_corner, 0>(box1); | |
99 | calc_t const b2_min = get<min_corner, 0>(box2); | |
100 | calc_t const b2_max = get<max_corner, 0>(box2); | |
101 | ||
102 | // min <= max <=> diff >= 0 | |
103 | calc_t const diff1 = b1_max - b1_min; | |
104 | calc_t const diff2 = b2_max - b2_min; | |
105 | ||
106 | // check the intersection if neither box cover the whole globe | |
107 | if (diff1 < constants::period() && diff2 < constants::period()) | |
108 | { | |
109 | // calculate positive longitude translation with b1_min as origin | |
110 | calc_t const diff_min = math::longitude_distance_unsigned<units_t>(b1_min, b2_min); | |
111 | calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min | |
112 | ||
113 | if (b2_min_transl > b1_max // b2_min right of b1_max | |
114 | && b2_min_transl - constants::period() + diff2 < b1_min) // b2_max left of b1_min | |
115 | { | |
116 | return true; | |
117 | } | |
118 | } | |
119 | ||
120 | return box_box | |
121 | < | |
122 | Box1, Box2, | |
123 | 1, DimensionCount | |
124 | >::apply(box1, box2); | |
125 | } | |
126 | }; | |
127 | ||
128 | ||
129 | /*! | |
130 | \brief Internal utility function to detect if boxes are disjoint | |
131 | \note Is used from other algorithms, declared separately | |
132 | to avoid circular references | |
133 | */ | |
134 | template <typename Box1, typename Box2> | |
135 | inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2) | |
136 | { | |
137 | return box_box<Box1, Box2>::apply(box1, box2); | |
138 | } | |
139 | ||
140 | ||
141 | }} // namespace detail::disjoint | |
142 | #endif // DOXYGEN_NO_DETAIL | |
143 | ||
144 | ||
145 | #ifndef DOXYGEN_NO_DISPATCH | |
146 | namespace dispatch | |
147 | { | |
148 | ||
149 | ||
150 | template <typename Box1, typename Box2, std::size_t DimensionCount> | |
151 | struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, false> | |
152 | : detail::disjoint::box_box<Box1, Box2, 0, DimensionCount> | |
153 | {}; | |
154 | ||
155 | ||
156 | } // namespace dispatch | |
157 | #endif // DOXYGEN_NO_DISPATCH | |
158 | ||
159 | ||
160 | }} // namespace boost::geometry | |
161 | ||
162 | ||
163 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_BOX_BOX_HPP |