File indexing completed on 2025-02-22 10:06:52
0001
0002
0003
0004
0005
0006
0007
0008
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
0048
0049 template <typename Point3d>
0050 struct plane
0051 {
0052 typedef typename coordinate_type<Point3d>::type coord_t;
0053
0054
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
0105
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
0139
0140 template <typename Point3d>
0141 struct plane
0142 {
0143 typedef typename coordinate_type<Point3d>::type coord_t;
0144
0145
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 }}
0239
0240 }}
0241
0242
0243 #endif