Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:06:52

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2016-2017, Oracle and/or its affiliates.
0004 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0005 
0006 // Use, modification and distribution is subject to the Boost Software License,
0007 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0008 // http://www.boost.org/LICENSE_1_0.txt)
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
0011 #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP
0012 
0013 
0014 #include <boost/geometry/srs/spheroid.hpp>
0015 
0016 #include <boost/geometry/formulas/geographic.hpp>
0017 
0018 #include <boost/geometry/strategies/spherical/intersection.hpp>
0019 
0020 
0021 namespace boost { namespace geometry
0022 {
0023 
0024 namespace strategy { namespace intersection
0025 {
0026 
0027 template <typename Spheroid>
0028 struct great_elliptic_segments_calc_policy
0029     : spherical_segments_calc_policy
0030 {
0031     explicit great_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
0032         : m_spheroid(spheroid)
0033     {}
0034 
0035     template <typename Point, typename Point3d>
0036     Point from_cart3d(Point3d const& point_3d) const
0037     {
0038         return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
0039     }
0040 
0041     template <typename Point3d, typename Point>
0042     Point3d to_cart3d(Point const& point) const
0043     {
0044         return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
0045     }
0046 
0047     // relate_xxx_calc_policy must live londer than plane because it contains
0048     // Spheroid object and plane keeps the reference to that object.
0049     template <typename Point3d>
0050     struct plane
0051     {
0052         typedef typename coordinate_type<Point3d>::type coord_t;
0053 
0054         // not normalized
0055         plane(Point3d const& p1, Point3d const& p2)
0056             : normal(cross_product(p1, p2))
0057         {}
0058 
0059         int side_value(Point3d const& pt) const
0060         {
0061             return formula::sph_side_value(normal, pt);
0062         }
0063 
0064         coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
0065         {
0066             Point3d v1 = p1;
0067             detail::vec_normalize(v1);
0068             Point3d v2 = p2;
0069             detail::vec_normalize(v2);
0070 
0071             return dot_product(v1, v2);
0072         }
0073 
0074         coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
0075         {
0076             coord_t const c0 = 0;
0077 
0078             Point3d v1 = p1;
0079             detail::vec_normalize(v1);
0080             Point3d v2 = p2;
0081             detail::vec_normalize(v2);
0082 
0083             is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
0084             return dot_product(v1, v2);
0085         }
0086 
0087         Point3d normal;
0088     };
0089 
0090     template <typename Point3d>
0091     plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
0092     {
0093         return plane<Point3d>(p1, p2);
0094     }
0095 
0096     template <typename Point3d>
0097     bool intersection_points(plane<Point3d> const& plane1,
0098                              plane<Point3d> const& plane2,
0099                              Point3d & ip1, Point3d & ip2) const
0100     {
0101         typedef typename coordinate_type<Point3d>::type coord_t;
0102 
0103         Point3d id = cross_product(plane1.normal, plane2.normal);
0104         // NOTE: the length should be greater than 0 at this point
0105         // NOTE: no need to normalize in this case
0106 
0107         ip1 = formula::projected_to_surface(id, m_spheroid);
0108 
0109         ip2 = ip1;
0110         multiply_value(ip2, coord_t(-1));
0111 
0112         return true;
0113     }
0114 
0115 private:
0116     Spheroid m_spheroid;
0117 };
0118 
0119 template <typename Spheroid>
0120 struct experimental_elliptic_segments_calc_policy
0121 {
0122     explicit experimental_elliptic_segments_calc_policy(Spheroid const& spheroid = Spheroid())
0123         : m_spheroid(spheroid)
0124     {}
0125 
0126     template <typename Point, typename Point3d>
0127     Point from_cart3d(Point3d const& point_3d) const
0128     {
0129         return formula::cart3d_to_geo<Point>(point_3d, m_spheroid);
0130     }
0131 
0132     template <typename Point3d, typename Point>
0133     Point3d to_cart3d(Point const& point) const
0134     {
0135         return formula::geo_to_cart3d<Point3d>(point, m_spheroid);
0136     }
0137 
0138     // relate_xxx_calc_policy must live londer than plane because it contains
0139     // Spheroid object and plane keeps the reference to that object.
0140     template <typename Point3d>
0141     struct plane
0142     {
0143         typedef typename coordinate_type<Point3d>::type coord_t;
0144 
0145         // not normalized
0146         plane(Point3d const& p1, Point3d const& p2, Spheroid const& spheroid)
0147             : m_spheroid(spheroid)
0148         {
0149             formula::experimental_elliptic_plane(p1, p2, origin, normal, m_spheroid);
0150         }
0151 
0152         int side_value(Point3d const& pt) const
0153         {
0154             return formula::elliptic_side_value(origin, normal, pt);
0155         }
0156 
0157         coord_t cos_angle_between(Point3d const& p1, Point3d const& p2) const
0158         {
0159             Point3d const v1 = normalized_vec(p1);
0160             Point3d const v2 = normalized_vec(p2);
0161             return dot_product(v1, v2);
0162         }
0163 
0164         coord_t cos_angle_between(Point3d const& p1, Point3d const& p2, bool & is_forward) const
0165         {
0166             coord_t const c0 = 0;
0167 
0168             Point3d const v1 = normalized_vec(p1);
0169             Point3d const v2 = normalized_vec(p2);
0170 
0171             is_forward = dot_product(normal, cross_product(v1, v2)) >= c0;
0172             return dot_product(v1, v2);
0173         }
0174 
0175         Point3d origin;
0176         Point3d normal;
0177 
0178     private:
0179         Point3d normalized_vec(Point3d const& p) const
0180         {
0181             Point3d v = p;
0182             subtract_point(v, origin);
0183             detail::vec_normalize(v);
0184             return v;
0185         }
0186 
0187         Spheroid const& m_spheroid;
0188     };
0189 
0190     template <typename Point3d>
0191     plane<Point3d> get_plane(Point3d const& p1, Point3d const& p2) const
0192     {
0193         return plane<Point3d>(p1, p2, m_spheroid);
0194     }
0195 
0196     template <typename Point3d>
0197     bool intersection_points(plane<Point3d> const& plane1,
0198                              plane<Point3d> const& plane2,
0199                              Point3d & ip1, Point3d & ip2) const
0200     {
0201         return formula::planes_spheroid_intersection(plane1.origin, plane1.normal,
0202                                                      plane2.origin, plane2.normal,
0203                                                      ip1, ip2, m_spheroid);
0204     }
0205 
0206 private:
0207     Spheroid m_spheroid;
0208 };
0209 
0210 
0211 template
0212 <
0213     typename Spheroid = srs::spheroid<double>,
0214     typename CalculationType = void
0215 >
0216 struct great_elliptic_segments
0217     : ecef_segments
0218         <
0219             great_elliptic_segments_calc_policy<Spheroid>,
0220             CalculationType
0221         >
0222 {};
0223 
0224 template
0225 <
0226     typename Spheroid = srs::spheroid<double>,
0227     typename CalculationType = void
0228 >
0229 struct experimental_elliptic_segments
0230     : ecef_segments
0231         <
0232             experimental_elliptic_segments_calc_policy<Spheroid>,
0233             CalculationType
0234         >
0235 {};
0236 
0237 
0238 }} // namespace strategy::intersection
0239 
0240 }} // namespace boost::geometry
0241 
0242 
0243 #endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_INTERSECTION_ELLIPTIC_HPP