]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/geometry/strategies/geographic/intersection_elliptic.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / geometry / strategies / geographic / intersection_elliptic.hpp
1 // Boost.Geometry
2
3 // Copyright (c) 2016-2017, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5
6 // Use, modification and distribution is subject to the Boost Software License,
7 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9
10 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
11 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
12
13
14 #include <boost/geometry/core/srs.hpp>
15
16 #include <boost/geometry/formulas/geographic.hpp>
17
18 #include <boost/geometry/strategies/spherical/intersection.hpp>
19
20
21 namespace boost { namespace geometry
22 {
23
24 namespace strategy { namespace intersection
25 {
26
27 template <typename Spheroid>
28 struct great_elliptic_segments_calc_policy
29 : spherical_segments_calc_policy
30 {
31 explicit great_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
32 : m_spheroid(spheroid)
33 {}
34
35 template <typename Point, typename Point3d>
36 Point from_cart3d(Point3d const& point_3d) const
37 {
38 return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
39 }
40
41 template <typename Point3d, typename Point>
42 Point3d to_cart3d(Point const& point) const
43 {
44 return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
45 }
46
47 // relate_xxx_calc_policy must live londer than plane because it contains
48 // Spheroid object and plane keeps the reference to that object.
49 template <typename Point3d>
50 struct plane
51 {
52 typedef typename coordinate_type<Point3d>::type coord_t;
53
54 // not normalized
55 plane(Point3d const& p1, Point3d const& p2)
56 : normal(cross_product(p1, p2))
57 {}
58
59 int side_value(Point3d const& pt) const
60 {
61 return formula::sph_side_value(normal, pt);
62 }
63
64 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
65 {
66 Point3d v1 = p1;
67 detail::vec_normalize(v1);
68 Point3d v2 = p2;
69 detail::vec_normalize(v2);
70
71 return dot_product(v1, v2);
72 }
73
74 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
75 {
76 coord_t const c0 = 0;
77
78 Point3d v1 = p1;
79 detail::vec_normalize(v1);
80 Point3d v2 = p2;
81 detail::vec_normalize(v2);
82
83 is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
84 return dot_product(v1, v2);
85 }
86
87 Point3d normal;
88 };
89
90 template <typename Point3d>
91 plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
92 {
93 return plane<Point3d>(p1, p2);
94 }
95
96 template <typename Point3d>
97 bool intersection_points(plane<Point3d> const& plane1,
98 plane<Point3d> const& plane2,
99 Point3d & ip1, Point3d & ip2) const
100 {
101 typedef typename coordinate_type<Point3d>::type coord_t;
102
103 Point3d id = cross_product(plane1.normal, plane2.normal);
104 // NOTE: the length should be greater than 0 at this point
105 // NOTE: no need to normalize in this case
106
107 ip1 = formula::projected_to_surface(id, m_spheroid);
108
109 ip2 = ip1;
110 multiply_value(ip2, coord_t(-1));
111
112 return true;
113 }
114
115 private:
116 Spheroid m_spheroid;
117 };
118
119 template <typename Spheroid>
120 struct experimental_elliptic_segments_calc_policy
121 {
122 explicit experimental_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
123 : m_spheroid(spheroid)
124 {}
125
126 template <typename Point, typename Point3d>
127 Point from_cart3d(Point3d const& point_3d) const
128 {
129 return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
130 }
131
132 template <typename Point3d, typename Point>
133 Point3d to_cart3d(Point const& point) const
134 {
135 return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
136 }
137
138 // relate_xxx_calc_policy must live londer than plane because it contains
139 // Spheroid object and plane keeps the reference to that object.
140 template <typename Point3d>
141 struct plane
142 {
143 typedef typename coordinate_type<Point3d>::type coord_t;
144
145 // not normalized
146 plane(Point3d const& p1, Point3d const& p2, Spheroid const& spheroid)
147 : m_spheroid(spheroid)
148 {
149 formula::experimental_elliptic_plane(p1, p2, origin, normal, m_spheroid);
150 }
151
152 int side_value(Point3d const& pt) const
153 {
154 return formula::elliptic_side_value(origin, normal, pt);
155 }
156
157 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
158 {
159 Point3d const v1 = normalized_vec(p1);
160 Point3d const v2 = normalized_vec(p2);
161 return dot_product(v1, v2);
162 }
163
164 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
165 {
166 coord_t const c0 = 0;
167
168 Point3d const v1 = normalized_vec(p1);
169 Point3d const v2 = normalized_vec(p2);
170
171 is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
172 return dot_product(v1, v2);
173 }
174
175 Point3d origin;
176 Point3d normal;
177
178 private:
179 Point3d normalized_vec(Point3d const& p) const
180 {
181 Point3d v = p;
182 subtract_point(v, origin);
183 detail::vec_normalize(v);
184 return v;
185 }
186
187 Spheroid const& m_spheroid;
188 };
189
190 template <typename Point3d>
191 plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
192 {
193 return plane<Point3d>(p1, p2, m_spheroid);
194 }
195
196 template <typename Point3d>
197 bool intersection_points(plane<Point3d> const& plane1,
198 plane<Point3d> const& plane2,
199 Point3d & ip1, Point3d & ip2) const
200 {
201 return formula::planes_spheroid_intersection(plane1.origin, plane1.normal,
202 plane2.origin, plane2.normal,
203 ip1, ip2, m_spheroid);
204 }
205
206 private:
207 Spheroid m_spheroid;
208 };
209
210
211 template
212 <
213 typename Spheroid = srs::spheroid<double>,
214 typename CalculationType = void
215 >
216 struct great_elliptic_segments
217 : ecef_segments
218 <
219 great_elliptic_segments_calc_policy<Spheroid>,
220 CalculationType
221 >
222 {};
223
224 template
225 <
226 typename Spheroid = srs::spheroid<double>,
227 typename CalculationType = void
228 >
229 struct experimental_elliptic_segments
230 : ecef_segments
231 <
232 experimental_elliptic_segments_calc_policy<Spheroid>,
233 CalculationType
234 >
235 {};
236
237
238 }} // namespace strategy::intersection
239
240 }} // namespace boost::geometry
241
242
243 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP