File indexing completed on 2025-01-18 09:36:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP
0012 #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP
0013
0014
0015 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
0016 #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
0017 #include <boost/geometry/arithmetic/arithmetic.hpp>
0018 #include <boost/geometry/arithmetic/cross_product.hpp>
0019 #include <boost/geometry/arithmetic/dot_product.hpp>
0020 #include <boost/geometry/arithmetic/normalize.hpp>
0021 #include <boost/geometry/core/assert.hpp>
0022 #include <boost/geometry/core/coordinate_dimension.hpp>
0023 #include <boost/geometry/core/coordinate_type.hpp>
0024 #include <boost/geometry/core/radian_access.hpp>
0025 #include <boost/geometry/formulas/spherical.hpp>
0026 #include <boost/geometry/formulas/interpolate_point_spherical.hpp>
0027 #include <boost/geometry/geometries/point.hpp>
0028 #include <boost/geometry/srs/sphere.hpp>
0029 #include <boost/geometry/strategies/densify.hpp>
0030 #include <boost/geometry/strategies/spherical/get_radius.hpp>
0031 #include <boost/geometry/util/math.hpp>
0032 #include <boost/geometry/util/select_most_precise.hpp>
0033
0034
0035 namespace boost { namespace geometry
0036 {
0037
0038 namespace strategy { namespace densify
0039 {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 template
0054 <
0055 typename RadiusTypeOrSphere = double,
0056 typename CalculationType = void
0057 >
0058 class spherical
0059 {
0060 public:
0061 typedef typename strategy_detail::get_radius
0062 <
0063 RadiusTypeOrSphere
0064 >::type radius_type;
0065
0066
0067 inline spherical()
0068 : m_radius(1.0)
0069 {}
0070
0071 template <typename RadiusOrSphere>
0072 explicit inline spherical(RadiusOrSphere const& radius_or_sphere)
0073 : m_radius(strategy_detail::get_radius
0074 <
0075 RadiusOrSphere
0076 >::apply(radius_or_sphere))
0077 {}
0078
0079 template <typename Point, typename AssignPolicy, typename T>
0080 inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const
0081 {
0082 typedef typename AssignPolicy::point_type out_point_t;
0083 typedef typename select_most_precise
0084 <
0085 typename coordinate_type<Point>::type,
0086 typename coordinate_type<out_point_t>::type,
0087 CalculationType
0088 >::type calc_t;
0089
0090 calc_t angle01;
0091
0092 formula::interpolate_point_spherical<calc_t> formula;
0093 formula.compute_angle(p0, p1, angle01);
0094
0095 BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
0096
0097 signed_size_type n = signed_size_type(angle01 * m_radius / length_threshold);
0098 if (n <= 0)
0099 return;
0100
0101 formula.compute_axis(p0, angle01);
0102
0103 calc_t step = angle01 / (n + 1);
0104
0105 calc_t a = step;
0106 for (signed_size_type i = 0 ; i < n ; ++i, a += step)
0107 {
0108 out_point_t p;
0109 formula.compute_point(a, p);
0110
0111 geometry::detail::conversion::point_to_point
0112 <
0113 Point, out_point_t,
0114 2, dimension<out_point_t>::value
0115 >::apply(p0, p);
0116
0117 policy.apply(p);
0118 }
0119 }
0120
0121 inline radius_type radius() const
0122 {
0123 return m_radius;
0124 }
0125
0126 private:
0127 radius_type m_radius;
0128 };
0129
0130
0131 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
0132 namespace services
0133 {
0134
0135 template <>
0136 struct default_strategy<spherical_equatorial_tag>
0137 {
0138 typedef strategy::densify::spherical<> type;
0139 };
0140
0141
0142 }
0143 #endif
0144
0145
0146 }}
0147
0148
0149 }}
0150
0151 #endif