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