buffer_point_circle.hpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands.
  3. // This file was modified by Oracle on 2015.
  4. // Modifications copyright (c) 2015, Oracle and/or its affiliates.
  5. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  6. // Use, modification and distribution is subject to the Boost Software License,
  7. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP
  10. #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP
  11. #include <cstddef>
  12. #include <boost/range.hpp>
  13. #include <boost/geometry/util/math.hpp>
  14. #include <boost/geometry/strategies/buffer.hpp>
  15. namespace boost { namespace geometry
  16. {
  17. namespace strategy { namespace buffer
  18. {
  19. /*!
  20. \brief Create a circular buffer around a point
  21. \ingroup strategies
  22. \details This strategy can be used as PointStrategy for the buffer algorithm.
  23. It creates a circular buffer around a point. It can be applied
  24. for points and multi_points, but also for a linestring (if it is degenerate,
  25. so consisting of only one point) and for polygons (if it is degenerate).
  26. This strategy is only applicable for Cartesian coordinate systems.
  27. \qbk{
  28. [heading Example]
  29. [buffer_point_circle]
  30. [heading Output]
  31. [$img/strategies/buffer_point_circle.png]
  32. [heading See also]
  33. \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
  34. \* [link geometry.reference.strategies.strategy_buffer_point_square point_square]
  35. }
  36. */
  37. class point_circle
  38. {
  39. public :
  40. //! \brief Constructs the strategy
  41. //! \param count number of points for the created circle (if count
  42. //! is smaller than 3, count is internally set to 3)
  43. explicit point_circle(std::size_t count = 90)
  44. : m_count((count < 3u) ? 3u : count)
  45. {}
  46. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  47. //! Fills output_range with a circle around point using distance_strategy
  48. template
  49. <
  50. typename Point,
  51. typename OutputRange,
  52. typename DistanceStrategy
  53. >
  54. inline void apply(Point const& point,
  55. DistanceStrategy const& distance_strategy,
  56. OutputRange& output_range) const
  57. {
  58. typedef typename boost::range_value<OutputRange>::type output_point_type;
  59. typedef typename geometry::select_most_precise
  60. <
  61. typename geometry::select_most_precise
  62. <
  63. typename geometry::coordinate_type<Point>::type,
  64. typename geometry::coordinate_type<output_point_type>::type
  65. >::type,
  66. double
  67. >::type promoted_type;
  68. promoted_type const buffer_distance = distance_strategy.apply(point, point,
  69. strategy::buffer::buffer_side_left);
  70. promoted_type const two_pi = geometry::math::two_pi<promoted_type>();
  71. promoted_type const diff = two_pi / promoted_type(m_count);
  72. promoted_type a = 0;
  73. for (std::size_t i = 0; i < m_count; i++, a -= diff)
  74. {
  75. output_point_type p;
  76. set<0>(p, get<0>(point) + buffer_distance * cos(a));
  77. set<1>(p, get<1>(point) + buffer_distance * sin(a));
  78. output_range.push_back(p);
  79. }
  80. // Close it:
  81. output_range.push_back(output_range.front());
  82. }
  83. #endif // DOXYGEN_SHOULD_SKIP_THIS
  84. private :
  85. std::size_t m_count;
  86. };
  87. }} // namespace strategy::buffer
  88. }} // namespace boost::geometry
  89. #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_POINT_CIRCLE_HPP