3 // Copyright (c) 2016-2017, Oracle and/or its affiliates.
4 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
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)
10 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
11 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
14 #include <boost/geometry/core/srs.hpp>
16 #include <boost/geometry/formulas/geographic.hpp>
18 #include <boost/geometry/strategies/spherical/intersection.hpp>
21 namespace boost { namespace geometry
24 namespace strategy { namespace intersection
27 template <typename Spheroid>
28 struct great_elliptic_segments_calc_policy
29 : spherical_segments_calc_policy
31 explicit great_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
32 : m_spheroid(spheroid)
35 template <typename Point, typename Point3d>
36 Point from_cart3d(Point3d const& point_3d) const
38 return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
41 template <typename Point3d, typename Point>
42 Point3d to_cart3d(Point const& point) const
44 return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
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>
52 typedef typename coordinate_type<Point3d>::type coord_t;
55 plane(Point3d const& p1, Point3d const& p2)
56 : normal(cross_product(p1, p2))
59 int side_value(Point3d const& pt) const
61 return formula::sph_side_value(normal, pt);
64 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
67 detail::vec_normalize(v1);
69 detail::vec_normalize(v2);
71 return dot_product(v1, v2);
74 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
79 detail::vec_normalize(v1);
81 detail::vec_normalize(v2);
83 is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
84 return dot_product(v1, v2);
90 template <typename Point3d>
91 plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
93 return plane<Point3d>(p1, p2);
96 template <typename Point3d>
97 bool intersection_points(plane<Point3d> const& plane1,
98 plane<Point3d> const& plane2,
99 Point3d & ip1, Point3d & ip2) const
101 typedef typename coordinate_type<Point3d>::type coord_t;
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
107 ip1 = formula::projected_to_surface(id, m_spheroid);
110 multiply_value(ip2, coord_t(-1));
119 template <typename Spheroid>
120 struct experimental_elliptic_segments_calc_policy
122 explicit experimental_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
123 : m_spheroid(spheroid)
126 template <typename Point, typename Point3d>
127 Point from_cart3d(Point3d const& point_3d) const
129 return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
132 template <typename Point3d, typename Point>
133 Point3d to_cart3d(Point const& point) const
135 return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
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>
143 typedef typename coordinate_type<Point3d>::type coord_t;
146 plane(Point3d const& p1, Point3d const& p2, Spheroid const& spheroid)
147 : m_spheroid(spheroid)
149 formula::experimental_elliptic_plane(p1, p2, origin, normal, m_spheroid);
152 int side_value(Point3d const& pt) const
154 return formula::elliptic_side_value(origin, normal, pt);
157 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
159 Point3d const v1 = normalized_vec(p1);
160 Point3d const v2 = normalized_vec(p2);
161 return dot_product(v1, v2);
164 coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
166 coord_t const c0 = 0;
168 Point3d const v1 = normalized_vec(p1);
169 Point3d const v2 = normalized_vec(p2);
171 is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
172 return dot_product(v1, v2);
179 Point3d normalized_vec(Point3d const& p) const
182 subtract_point(v, origin);
183 detail::vec_normalize(v);
187 Spheroid const& m_spheroid;
190 template <typename Point3d>
191 plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
193 return plane<Point3d>(p1, p2, m_spheroid);
196 template <typename Point3d>
197 bool intersection_points(plane<Point3d> const& plane1,
198 plane<Point3d> const& plane2,
199 Point3d & ip1, Point3d & ip2) const
201 return formula::planes_spheroid_intersection(plane1.origin, plane1.normal,
202 plane2.origin, plane2.normal,
203 ip1, ip2, m_spheroid);
213 typename Spheroid = srs::spheroid<double>,
214 typename CalculationType = void
216 struct great_elliptic_segments
219 great_elliptic_segments_calc_policy<Spheroid>,
226 typename Spheroid = srs::spheroid<double>,
227 typename CalculationType = void
229 struct experimental_elliptic_segments
232 experimental_elliptic_segments_calc_policy<Spheroid>,
238 }} // namespace strategy::intersection
240 }} // namespace boost::geometry
243 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP