]>
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, 2014, 2015. | |
9 | // Modifications copyright (c) 2013-2015, 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_POINT_POINT_HPP | |
22 | #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP | |
23 | ||
24 | #include <cstddef> | |
25 | ||
26 | #include <boost/type_traits/is_same.hpp> | |
27 | ||
28 | #include <boost/geometry/core/access.hpp> | |
29 | #include <boost/geometry/core/radian_access.hpp> | |
30 | #include <boost/geometry/core/coordinate_dimension.hpp> | |
31 | #include <boost/geometry/core/coordinate_system.hpp> | |
32 | #include <boost/geometry/core/coordinate_type.hpp> | |
33 | #include <boost/geometry/core/cs.hpp> | |
34 | #include <boost/geometry/core/tags.hpp> | |
35 | ||
36 | #include <boost/geometry/util/math.hpp> | |
37 | #include <boost/geometry/util/select_most_precise.hpp> | |
38 | ||
39 | #include <boost/geometry/strategies/strategy_transform.hpp> | |
40 | ||
41 | #include <boost/geometry/geometries/helper_geometry.hpp> | |
42 | ||
43 | #include <boost/geometry/algorithms/transform.hpp> | |
44 | ||
45 | #include <boost/geometry/algorithms/detail/normalize.hpp> | |
46 | ||
47 | #include <boost/geometry/algorithms/dispatch/disjoint.hpp> | |
48 | ||
49 | ||
50 | namespace boost { namespace geometry | |
51 | { | |
52 | ||
53 | ||
54 | #ifndef DOXYGEN_NO_DETAIL | |
55 | namespace detail { namespace disjoint | |
56 | { | |
57 | ||
58 | ||
59 | template <std::size_t Dimension, std::size_t DimensionCount> | |
60 | struct point_point_generic | |
61 | { | |
62 | template <typename Point1, typename Point2> | |
63 | static inline bool apply(Point1 const& p1, Point2 const& p2) | |
64 | { | |
65 | if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2))) | |
66 | { | |
67 | return true; | |
68 | } | |
69 | return | |
70 | point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2); | |
71 | } | |
72 | }; | |
73 | ||
74 | template <std::size_t DimensionCount> | |
75 | struct point_point_generic<DimensionCount, DimensionCount> | |
76 | { | |
77 | template <typename Point1, typename Point2> | |
78 | static inline bool apply(Point1 const&, Point2 const&) | |
79 | { | |
80 | return false; | |
81 | } | |
82 | }; | |
83 | ||
84 | ||
85 | class point_point_on_spheroid | |
86 | { | |
87 | private: | |
88 | template <typename Point1, typename Point2, bool SameUnits> | |
89 | struct are_same_points | |
90 | { | |
91 | static inline bool apply(Point1 const& point1, Point2 const& point2) | |
92 | { | |
93 | typedef typename helper_geometry<Point1>::type helper_point_type1; | |
94 | typedef typename helper_geometry<Point2>::type helper_point_type2; | |
95 | ||
96 | helper_point_type1 point1_normalized | |
97 | = return_normalized<helper_point_type1>(point1); | |
98 | helper_point_type2 point2_normalized | |
99 | = return_normalized<helper_point_type2>(point2); | |
100 | ||
101 | return point_point_generic | |
102 | < | |
103 | 0, dimension<Point1>::value | |
104 | >::apply(point1_normalized, point2_normalized); | |
105 | } | |
106 | }; | |
107 | ||
108 | template <typename Point1, typename Point2> | |
109 | struct are_same_points<Point1, Point2, false> // points have different units | |
110 | { | |
111 | static inline bool apply(Point1 const& point1, Point2 const& point2) | |
112 | { | |
113 | typedef typename geometry::select_most_precise | |
114 | < | |
115 | typename fp_coordinate_type<Point1>::type, | |
116 | typename fp_coordinate_type<Point2>::type | |
117 | >::type calculation_type; | |
118 | ||
119 | typename helper_geometry | |
120 | < | |
121 | Point1, calculation_type, radian | |
122 | >::type helper_point1, helper_point2; | |
123 | ||
124 | Point1 point1_normalized = return_normalized<Point1>(point1); | |
125 | Point2 point2_normalized = return_normalized<Point2>(point2); | |
126 | ||
127 | geometry::transform(point1_normalized, helper_point1); | |
128 | geometry::transform(point2_normalized, helper_point2); | |
129 | ||
130 | return point_point_generic | |
131 | < | |
132 | 0, dimension<Point1>::value | |
133 | >::apply(helper_point1, helper_point2); | |
134 | } | |
135 | }; | |
136 | ||
137 | public: | |
138 | template <typename Point1, typename Point2> | |
139 | static inline bool apply(Point1 const& point1, Point2 const& point2) | |
140 | { | |
141 | return are_same_points | |
142 | < | |
143 | Point1, | |
144 | Point2, | |
145 | boost::is_same | |
146 | < | |
147 | typename coordinate_system<Point1>::type::units, | |
148 | typename coordinate_system<Point2>::type::units | |
149 | >::value | |
150 | >::apply(point1, point2); | |
151 | } | |
152 | }; | |
153 | ||
154 | ||
155 | template | |
156 | < | |
157 | typename Point1, typename Point2, | |
158 | std::size_t Dimension, std::size_t DimensionCount, | |
159 | typename CSTag1 = typename cs_tag<Point1>::type, | |
160 | typename CSTag2 = CSTag1 | |
161 | > | |
162 | struct point_point | |
163 | : point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag> | |
164 | {}; | |
165 | ||
166 | template | |
167 | < | |
168 | typename Point1, typename Point2, | |
169 | std::size_t Dimension, std::size_t DimensionCount | |
170 | > | |
171 | struct point_point | |
172 | < | |
173 | Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag | |
174 | > : point_point_on_spheroid | |
175 | {}; | |
176 | ||
177 | template | |
178 | < | |
179 | typename Point1, typename Point2, | |
180 | std::size_t Dimension, std::size_t DimensionCount | |
181 | > | |
182 | struct point_point | |
183 | < | |
184 | Point1, Point2, Dimension, DimensionCount, geographic_tag | |
185 | > : point_point_on_spheroid | |
186 | {}; | |
187 | ||
188 | template | |
189 | < | |
190 | typename Point1, typename Point2, | |
191 | std::size_t Dimension, std::size_t DimensionCount | |
192 | > | |
193 | struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag> | |
194 | : point_point_generic<Dimension, DimensionCount> | |
195 | {}; | |
196 | ||
197 | ||
198 | /*! | |
199 | \brief Internal utility function to detect of points are disjoint | |
200 | \note To avoid circular references | |
201 | */ | |
202 | template <typename Point1, typename Point2> | |
203 | inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2) | |
204 | { | |
205 | return point_point | |
206 | < | |
207 | Point1, Point2, | |
208 | 0, dimension<Point1>::type::value | |
209 | >::apply(point1, point2); | |
210 | } | |
211 | ||
212 | ||
213 | }} // namespace detail::disjoint | |
214 | #endif // DOXYGEN_NO_DETAIL | |
215 | ||
216 | ||
217 | ||
218 | ||
219 | #ifndef DOXYGEN_NO_DISPATCH | |
220 | namespace dispatch | |
221 | { | |
222 | ||
223 | ||
224 | template <typename Point1, typename Point2, std::size_t DimensionCount> | |
225 | struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false> | |
226 | : detail::disjoint::point_point<Point1, Point2, 0, DimensionCount> | |
227 | {}; | |
228 | ||
229 | ||
230 | } // namespace dispatch | |
231 | #endif // DOXYGEN_NO_DISPATCH | |
232 | ||
233 | }} // namespace boost::geometry | |
234 | ||
235 | #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_POINT_POINT_HPP |