• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 2018.
6 // Modifications copyright (c) 2015, 2018, Oracle and/or its affiliates.
7 
8 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
14 
15 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP
16 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP
17 
18 #include <cstddef>
19 
20 #include <boost/range/value_type.hpp>
21 
22 #include <boost/geometry/core/access.hpp>
23 #include <boost/geometry/core/coordinate_type.hpp>
24 
25 #include <boost/geometry/strategies/buffer.hpp>
26 
27 #include <boost/geometry/util/math.hpp>
28 #include <boost/geometry/util/select_most_precise.hpp>
29 
30 namespace boost { namespace geometry
31 {
32 
33 namespace strategy { namespace buffer
34 {
35 
36 /*!
37 \brief Create a circular buffer around a point
38 \ingroup strategies
39 \details This strategy can be used as PointStrategy for the buffer algorithm.
40     It creates a circular buffer around a point. It can be applied
41     for points and multi_points, but also for a linestring (if it is degenerate,
42     so consisting of only one point) and for polygons (if it is degenerate).
43     This strategy is only applicable for Cartesian coordinate systems.
44 
45 \qbk{
46 [heading Example]
47 [buffer_point_circle]
48 [heading Output]
49 [$img/strategies/buffer_point_circle.png]
50 [heading See also]
51 \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
52 \* [link geometry.reference.strategies.strategy_buffer_point_square point_square]
53 \* [link geometry.reference.strategies.strategy_buffer_geographic_point_circle geographic_point_circle]
54 }
55  */
56 class point_circle
57 {
58 public :
59     //! \brief Constructs the strategy
60     //! \param count number of points for the created circle (if count
61     //! is smaller than 3, count is internally set to 3)
point_circle(std::size_t count=90)62     explicit point_circle(std::size_t count = 90)
63         : m_count((count < 3u) ? 3u : count)
64     {}
65 
66 #ifndef DOXYGEN_SHOULD_SKIP_THIS
67     //! Fills output_range with a circle around point using distance_strategy
68     template
69     <
70         typename Point,
71         typename OutputRange,
72         typename DistanceStrategy
73     >
apply(Point const & point,DistanceStrategy const & distance_strategy,OutputRange & output_range) const74     inline void apply(Point const& point,
75                 DistanceStrategy const& distance_strategy,
76                 OutputRange& output_range) const
77     {
78         typedef typename boost::range_value<OutputRange>::type output_point_type;
79 
80         typedef typename geometry::select_most_precise
81             <
82                 typename geometry::select_most_precise
83                     <
84                         typename geometry::coordinate_type<Point>::type,
85                         typename geometry::coordinate_type<output_point_type>::type
86                     >::type,
87                 double
88             >::type promoted_type;
89 
90         promoted_type const buffer_distance = distance_strategy.apply(point, point,
91                         strategy::buffer::buffer_side_left);
92 
93         promoted_type const two_pi = geometry::math::two_pi<promoted_type>();
94 
95         promoted_type const diff = two_pi / promoted_type(m_count);
96         promoted_type a = 0;
97 
98         for (std::size_t i = 0; i < m_count; i++, a -= diff)
99         {
100             output_point_type p;
101             set<0>(p, get<0>(point) + buffer_distance * cos(a));
102             set<1>(p, get<1>(point) + buffer_distance * sin(a));
103             output_range.push_back(p);
104         }
105 
106         // Close it:
107         output_range.push_back(output_range.front());
108     }
109 #endif // DOXYGEN_SHOULD_SKIP_THIS
110 
111 private :
112     std::size_t m_count;
113 };
114 
115 
116 }} // namespace strategy::buffer
117 
118 }} // namespace boost::geometry
119 
120 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP
121