intersection_elliptic.hpp 6.7 KB

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