summaryrefslogtreecommitdiff
path: root/boost/geometry/strategies/geographic/intersection_elliptic.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/strategies/geographic/intersection_elliptic.hpp')
-rw-r--r--boost/geometry/strategies/geographic/intersection_elliptic.hpp243
1 files changed, 243 insertions, 0 deletions
diff --git a/boost/geometry/strategies/geographic/intersection_elliptic.hpp b/boost/geometry/strategies/geographic/intersection_elliptic.hpp
new file mode 100644
index 0000000000..76e9940fe3
--- /dev/null
+++ b/boost/geometry/strategies/geographic/intersection_elliptic.hpp
@@ -0,0 +1,243 @@
+// Boost.Geometry
+
+// Copyright (c) 2016-2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
+#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
+
+
+#include <boost/geometry/core/srs.hpp>
+
+#include <boost/geometry/formulas/geographic.hpp>
+
+#include <boost/geometry/strategies/spherical/intersection.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace intersection
+{
+
+template <typename Spheroid>
+struct great_elliptic_segments_calc_policy
+ : spherical_segments_calc_policy
+{
+ explicit great_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point, typename Point3d>
+ Point from_cart3d(Point3d const& point_3d) const
+ {
+ return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
+ }
+
+ template <typename Point3d, typename Point>
+ Point3d to_cart3d(Point const& point) const
+ {
+ return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
+ }
+
+ // relate_xxx_calc_policy must live londer than plane because it contains
+ // Spheroid object and plane keeps the reference to that object.
+ template <typename Point3d>
+ struct plane
+ {
+ typedef typename coordinate_type<Point3d>::type coord_t;
+
+ // not normalized
+ plane(Point3d const& p1, Point3d const& p2)
+ : normal(cross_product(p1, p2))
+ {}
+
+ int side_value(Point3d const& pt) const
+ {
+ return formula::sph_side_value(normal, pt);
+ }
+
+ coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
+ {
+ Point3d v1 = p1;
+ detail::vec_normalize(v1);
+ Point3d v2 = p2;
+ detail::vec_normalize(v2);
+
+ return dot_product(v1, v2);
+ }
+
+ coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
+ {
+ coord_t const c0 = 0;
+
+ Point3d v1 = p1;
+ detail::vec_normalize(v1);
+ Point3d v2 = p2;
+ detail::vec_normalize(v2);
+
+ is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
+ return dot_product(v1, v2);
+ }
+
+ Point3d normal;
+ };
+
+ template <typename Point3d>
+ plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
+ {
+ return plane<Point3d>(p1, p2);
+ }
+
+ template <typename Point3d>
+ bool intersection_points(plane<Point3d> const& plane1,
+ plane<Point3d> const& plane2,
+ Point3d & ip1, Point3d & ip2) const
+ {
+ typedef typename coordinate_type<Point3d>::type coord_t;
+
+ Point3d id = cross_product(plane1.normal, plane2.normal);
+ // NOTE: the length should be greater than 0 at this point
+ // NOTE: no need to normalize in this case
+
+ ip1 = formula::projected_to_surface(id, m_spheroid);
+
+ ip2 = ip1;
+ multiply_value(ip2, coord_t(-1));
+
+ return true;
+ }
+
+private:
+ Spheroid m_spheroid;
+};
+
+template <typename Spheroid>
+struct experimental_elliptic_segments_calc_policy
+{
+ explicit experimental_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
+ : m_spheroid(spheroid)
+ {}
+
+ template <typename Point, typename Point3d>
+ Point from_cart3d(Point3d const& point_3d) const
+ {
+ return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
+ }
+
+ template <typename Point3d, typename Point>
+ Point3d to_cart3d(Point const& point) const
+ {
+ return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
+ }
+
+ // relate_xxx_calc_policy must live londer than plane because it contains
+ // Spheroid object and plane keeps the reference to that object.
+ template <typename Point3d>
+ struct plane
+ {
+ typedef typename coordinate_type<Point3d>::type coord_t;
+
+ // not normalized
+ plane(Point3d const& p1, Point3d const& p2, Spheroid const& spheroid)
+ : m_spheroid(spheroid)
+ {
+ formula::experimental_elliptic_plane(p1, p2, origin, normal, m_spheroid);
+ }
+
+ int side_value(Point3d const& pt) const
+ {
+ return formula::elliptic_side_value(origin, normal, pt);
+ }
+
+ coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
+ {
+ Point3d const v1 = normalized_vec(p1);
+ Point3d const v2 = normalized_vec(p2);
+ return dot_product(v1, v2);
+ }
+
+ coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
+ {
+ coord_t const c0 = 0;
+
+ Point3d const v1 = normalized_vec(p1);
+ Point3d const v2 = normalized_vec(p2);
+
+ is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
+ return dot_product(v1, v2);
+ }
+
+ Point3d origin;
+ Point3d normal;
+
+ private:
+ Point3d normalized_vec(Point3d const& p) const
+ {
+ Point3d v = p;
+ subtract_point(v, origin);
+ detail::vec_normalize(v);
+ return v;
+ }
+
+ Spheroid const& m_spheroid;
+ };
+
+ template <typename Point3d>
+ plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
+ {
+ return plane<Point3d>(p1, p2, m_spheroid);
+ }
+
+ template <typename Point3d>
+ bool intersection_points(plane<Point3d> const& plane1,
+ plane<Point3d> const& plane2,
+ Point3d & ip1, Point3d & ip2) const
+ {
+ return formula::planes_spheroid_intersection(plane1.origin, plane1.normal,
+ plane2.origin, plane2.normal,
+ ip1, ip2, m_spheroid);
+ }
+
+private:
+ Spheroid m_spheroid;
+};
+
+
+template
+<
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+struct great_elliptic_segments
+ : ecef_segments
+ <
+ great_elliptic_segments_calc_policy<Spheroid>,
+ CalculationType
+ >
+{};
+
+template
+<
+ typename Spheroid = srs::spheroid<double>,
+ typename CalculationType = void
+>
+struct experimental_elliptic_segments
+ : ecef_segments
+ <
+ experimental_elliptic_segments_calc_policy<Spheroid>,
+ CalculationType
+ >
+{};
+
+
+}} // namespace strategy::intersection
+
+}} // namespace boost::geometry
+
+
+#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP