3 // Copyright (c) 2017-2019, Oracle and/or its affiliates.
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
11 #ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP
12 #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP
15 #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
16 #include <boost/geometry/algorithms/detail/signed_size_type.hpp>
17 #include <boost/geometry/arithmetic/arithmetic.hpp>
18 #include <boost/geometry/arithmetic/cross_product.hpp>
19 #include <boost/geometry/arithmetic/dot_product.hpp>
20 #include <boost/geometry/arithmetic/normalize.hpp>
21 #include <boost/geometry/core/assert.hpp>
22 #include <boost/geometry/core/coordinate_dimension.hpp>
23 #include <boost/geometry/core/coordinate_type.hpp>
24 #include <boost/geometry/core/radian_access.hpp>
25 #include <boost/geometry/formulas/spherical.hpp>
26 #include <boost/geometry/formulas/interpolate_point_spherical.hpp>
27 #include <boost/geometry/geometries/point.hpp>
28 #include <boost/geometry/srs/sphere.hpp>
29 #include <boost/geometry/strategies/densify.hpp>
30 #include <boost/geometry/strategies/spherical/get_radius.hpp>
31 #include <boost/geometry/util/math.hpp>
32 #include <boost/geometry/util/select_most_precise.hpp>
35 namespace boost { namespace geometry
38 namespace strategy { namespace densify
43 \brief Densification of spherical segment.
45 \tparam RadiusTypeOrSphere \tparam_radius_or_sphere
46 \tparam CalculationType \tparam_calculation
50 [link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)]
55 typename RadiusTypeOrSphere = double,
56 typename CalculationType = void
61 // For consistency with area strategy the radius is set to 1
66 template <typename RadiusOrSphere>
67 explicit inline spherical(RadiusOrSphere const& radius_or_sphere)
68 : m_radius(strategy_detail::get_radius
71 >::apply(radius_or_sphere))
74 template <typename Point, typename AssignPolicy, typename T>
75 inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const
77 typedef typename AssignPolicy::point_type out_point_t;
78 typedef typename select_most_precise
80 typename coordinate_type<Point>::type,
81 typename coordinate_type<out_point_t>::type,
87 formula::interpolate_point_spherical<calc_t> formula;
88 formula.compute_angle(p0, p1, angle01);
90 BOOST_GEOMETRY_ASSERT(length_threshold > T(0));
92 signed_size_type n = signed_size_type(angle01 * m_radius / length_threshold);
96 formula.compute_axis(p0, angle01);
98 calc_t step = angle01 / (n + 1);
101 for (signed_size_type i = 0 ; i < n ; ++i, a += step)
104 formula.compute_point(a, p);
106 geometry::detail::conversion::point_to_point
109 2, dimension<out_point_t>::value
117 typename strategy_detail::get_radius
124 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
129 struct default_strategy<spherical_equatorial_tag>
131 typedef strategy::densify::spherical<> type;
135 } // namespace services
136 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
139 }} // namespace strategy::densify
142 }} // namespace boost::geometry
144 #endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP