]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/cartesian/buffer_join_round.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / cartesian / buffer_join_round.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
4
5// This file was modified by Oracle on 2015.
6// Modifications copyright (c) 2015, Oracle and/or its affiliates.
7
8// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9
10// Use, modification and distribution is subject to the Boost Software License,
11// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12// http://www.boost.org/LICENSE_1_0.txt)
13
14#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
15#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP
16
17#include <algorithm>
18
19#include <boost/geometry/core/cs.hpp>
20#include <boost/geometry/policies/compare.hpp>
21#include <boost/geometry/strategies/buffer.hpp>
22#include <boost/geometry/util/math.hpp>
23#include <boost/geometry/util/select_most_precise.hpp>
24
25#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
26#include <iostream>
27#include <boost/geometry/io/wkt/wkt.hpp>
28#endif
29
30
31namespace boost { namespace geometry
32{
33
34
35namespace strategy { namespace buffer
36{
37
38/*!
39\brief Let the buffer create rounded corners
40\ingroup strategies
41\details This strategy can be used as JoinStrategy for the buffer algorithm.
42 It creates a rounded corners around each convex vertex. It can be applied
43 for (multi)linestrings and (multi)polygons.
44 This strategy is only applicable for Cartesian coordinate systems.
45
46\qbk{
47[heading Example]
48[buffer_join_round]
49[heading Output]
50[$img/strategies/buffer_join_round.png]
51[heading See also]
52\* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
53\* [link geometry.reference.strategies.strategy_buffer_join_miter join_miter]
54}
55 */
56class join_round
57{
58public :
59
60 //! \brief Constructs the strategy
61 //! \param points_per_circle points which would be used for a full circle
62 explicit inline join_round(std::size_t points_per_circle = 90)
63 : m_points_per_circle(points_per_circle)
64 {}
65
66private :
67 template
68 <
69 typename PromotedType,
70 typename Point,
71 typename DistanceType,
72 typename RangeOut
73 >
74 inline void generate_points(Point const& vertex,
75 Point const& perp1, Point const& perp2,
76 DistanceType const& buffer_distance,
77 RangeOut& range_out) const
78 {
79 PromotedType const dx1 = get<0>(perp1) - get<0>(vertex);
80 PromotedType const dy1 = get<1>(perp1) - get<1>(vertex);
81 PromotedType const dx2 = get<0>(perp2) - get<0>(vertex);
82 PromotedType const dy2 = get<1>(perp2) - get<1>(vertex);
83
84 PromotedType const two_pi = geometry::math::two_pi<PromotedType>();
85
86 PromotedType const angle1 = atan2(dy1, dx1);
87 PromotedType angle2 = atan2(dy2, dx2);
88 while (angle2 > angle1)
89 {
90 angle2 -= two_pi;
91 }
92 PromotedType const angle_diff = angle1 - angle2;
93
94 // Divide the angle into an integer amount of steps to make it
95 // visually correct also for a low number of points / circle
96
97 // If a full circle is divided into 3 parts (e.g. angle is 125),
98 // the one point in between must still be generated
99 // The calculation below:
100 // - generates 1 point in between for an angle of 125 based on 3 points
101 // - generates 0 points in between for an angle of 90 based on 4 points
102
103 std::size_t const n = (std::max)(static_cast<std::size_t>(
104 ceil(m_points_per_circle * angle_diff / two_pi)), std::size_t(1));
105
106 PromotedType const diff = angle_diff / static_cast<PromotedType>(n);
107 PromotedType a = angle1 - diff;
108
109 // Walk to n - 1 to avoid generating the last point
110 for (std::size_t i = 0; i < n - 1; i++, a -= diff)
111 {
112 Point p;
113 set<0>(p, get<0>(vertex) + buffer_distance * cos(a));
114 set<1>(p, get<1>(vertex) + buffer_distance * sin(a));
115 range_out.push_back(p);
116 }
117 }
118
119public :
120
121
122#ifndef DOXYGEN_SHOULD_SKIP_THIS
123 //! Fills output_range with a rounded shape around a vertex
124 template <typename Point, typename DistanceType, typename RangeOut>
125 inline bool apply(Point const& ip, Point const& vertex,
126 Point const& perp1, Point const& perp2,
127 DistanceType const& buffer_distance,
128 RangeOut& range_out) const
129 {
130 typedef typename coordinate_type<Point>::type coordinate_type;
131 typedef typename boost::range_value<RangeOut>::type output_point_type;
132
133 typedef typename geometry::select_most_precise
134 <
135 typename geometry::select_most_precise
136 <
137 coordinate_type,
138 typename geometry::coordinate_type<output_point_type>::type
139 >::type,
140 double
141 >::type promoted_type;
142
143 geometry::equal_to<Point> equals;
144 if (equals(perp1, perp2))
145 {
146#ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
147 std::cout << "Corner for equal points " << geometry::wkt(ip) << " " << geometry::wkt(perp1) << std::endl;
148#endif
149 return false;
150 }
151
152 // Generate 'vectors'
153 coordinate_type vix = (get<0>(ip) - get<0>(vertex));
154 coordinate_type viy = (get<1>(ip) - get<1>(vertex));
155
156 promoted_type length_i = geometry::math::sqrt(vix * vix + viy * viy);
157 DistanceType const bd = geometry::math::abs(buffer_distance);
158 promoted_type prop = bd / length_i;
159
160 Point bp;
161 set<0>(bp, get<0>(vertex) + vix * prop);
162 set<1>(bp, get<1>(vertex) + viy * prop);
163
164 range_out.push_back(perp1);
165 generate_points<promoted_type>(vertex, perp1, perp2, bd, range_out);
166 range_out.push_back(perp2);
167 return true;
168 }
169
170 template <typename NumericType>
171 static inline NumericType max_distance(NumericType const& distance)
172 {
173 return distance;
174 }
175
176#endif // DOXYGEN_SHOULD_SKIP_THIS
177
178private :
179 std::size_t m_points_per_circle;
180};
181
182
183}} // namespace strategy::buffer
184
185}} // namespace boost::geometry
186
187#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP