]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // Boost.Geometry |
2 | ||
3 | // Copyright (c) 2017-2018, Oracle and/or its affiliates. | |
4 | ||
5 | // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle | |
6 | ||
7 | // Licensed under the Boost Software License version 1.0. | |
8 | // http://www.boost.org/users/license.html | |
9 | ||
10 | #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP | |
11 | #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP | |
12 | ||
13 | ||
14 | #include <boost/geometry/algorithms/detail/convert_point_to_point.hpp> | |
15 | #include <boost/geometry/algorithms/detail/signed_size_type.hpp> | |
16 | #include <boost/geometry/arithmetic/arithmetic.hpp> | |
17 | #include <boost/geometry/arithmetic/dot_product.hpp> | |
18 | #include <boost/geometry/core/assert.hpp> | |
19 | #include <boost/geometry/core/coordinate_dimension.hpp> | |
20 | #include <boost/geometry/core/coordinate_type.hpp> | |
92f5a8d4 | 21 | #include <boost/geometry/geometries/point.hpp> |
11fdf7f2 TL |
22 | #include <boost/geometry/strategies/densify.hpp> |
23 | #include <boost/geometry/util/math.hpp> | |
24 | #include <boost/geometry/util/select_most_precise.hpp> | |
25 | ||
26 | ||
27 | namespace boost { namespace geometry | |
28 | { | |
29 | ||
30 | namespace strategy { namespace densify | |
31 | { | |
32 | ||
33 | ||
34 | /*! | |
35 | \brief Densification of cartesian segment. | |
36 | \ingroup strategies | |
37 | \tparam CalculationType \tparam_calculation | |
38 | ||
39 | \qbk{ | |
40 | [heading See also] | |
41 | [link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)] | |
42 | } | |
43 | */ | |
44 | template | |
45 | < | |
46 | typename CalculationType = void | |
47 | > | |
48 | class cartesian | |
49 | { | |
50 | public: | |
51 | template <typename Point, typename AssignPolicy, typename T> | |
52 | static inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) | |
53 | { | |
54 | typedef typename AssignPolicy::point_type out_point_t; | |
55 | typedef typename select_most_precise | |
56 | < | |
57 | typename coordinate_type<Point>::type, | |
58 | typename coordinate_type<out_point_t>::type, | |
59 | CalculationType | |
60 | >::type calc_t; | |
61 | ||
62 | typedef model::point<calc_t, geometry::dimension<Point>::value, cs::cartesian> calc_point_t; | |
63 | ||
64 | calc_point_t cp0, cp1; | |
65 | geometry::detail::conversion::convert_point_to_point(p0, cp0); | |
66 | geometry::detail::conversion::convert_point_to_point(p1, cp1); | |
67 | ||
68 | // dir01 = xy1 - xy0 | |
69 | calc_point_t dir01 = cp1; | |
70 | geometry::subtract_point(dir01, cp0); | |
71 | calc_t const dot01 = geometry::dot_product(dir01, dir01); | |
72 | calc_t const len = math::sqrt(dot01); | |
73 | ||
74 | BOOST_GEOMETRY_ASSERT(length_threshold > T(0)); | |
75 | ||
76 | signed_size_type n = signed_size_type(len / length_threshold); | |
77 | if (n <= 0) | |
78 | { | |
79 | return; | |
80 | } | |
81 | ||
82 | // NOTE: Normalization will not work for integral coordinates | |
83 | // normalize | |
84 | //geometry::divide_value(dir01, len); | |
85 | ||
86 | calc_t step = len / (n + 1); | |
87 | ||
88 | calc_t d = step; | |
89 | for (signed_size_type i = 0 ; i < n ; ++i, d += step) | |
90 | { | |
91 | // pd = xy0 + d * dir01 | |
92 | calc_point_t pd = dir01; | |
93 | ||
94 | // without normalization | |
95 | geometry::multiply_value(pd, calc_t(i + 1)); | |
96 | geometry::divide_value(pd, calc_t(n + 1)); | |
97 | // with normalization | |
98 | //geometry::multiply_value(pd, d); | |
99 | ||
100 | geometry::add_point(pd, cp0); | |
101 | ||
102 | // NOTE: Only needed if types calc_point_t and out_point_t are different | |
103 | // otherwise pd could simply be passed into policy | |
104 | out_point_t p; | |
105 | assert_dimension_equal<calc_point_t, out_point_t>(); | |
106 | geometry::detail::conversion::convert_point_to_point(pd, p); | |
107 | ||
108 | policy.apply(p); | |
109 | } | |
110 | } | |
111 | }; | |
112 | ||
113 | ||
114 | #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
115 | namespace services | |
116 | { | |
117 | ||
118 | template <> | |
119 | struct default_strategy<cartesian_tag> | |
120 | { | |
121 | typedef strategy::densify::cartesian<> type; | |
122 | }; | |
123 | ||
124 | ||
125 | } // namespace services | |
126 | #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS | |
127 | ||
128 | ||
129 | }} // namespace strategy::densify | |
130 | ||
131 | ||
132 | }} // namespace boost::geometry | |
133 | ||
134 | #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP |