diff options
Diffstat (limited to 'boost/geometry/strategies/cartesian/buffer_join_round.hpp')
-rw-r--r-- | boost/geometry/strategies/cartesian/buffer_join_round.hpp | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/boost/geometry/strategies/cartesian/buffer_join_round.hpp b/boost/geometry/strategies/cartesian/buffer_join_round.hpp index 9e467c85a0..9ec51cd1ec 100644 --- a/boost/geometry/strategies/cartesian/buffer_join_round.hpp +++ b/boost/geometry/strategies/cartesian/buffer_join_round.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2012-2015 Barend Gehrels, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,6 +9,8 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_ROUND_HPP +#include <algorithm> + #include <boost/assert.hpp> #include <boost/geometry/core/cs.hpp> #include <boost/geometry/policies/compare.hpp> @@ -69,34 +71,38 @@ private : DistanceType const& buffer_distance, RangeOut& range_out) const { - PromotedType dx1 = get<0>(perp1) - get<0>(vertex); - PromotedType dy1 = get<1>(perp1) - get<1>(vertex); - PromotedType dx2 = get<0>(perp2) - get<0>(vertex); - PromotedType dy2 = get<1>(perp2) - get<1>(vertex); + PromotedType const dx1 = get<0>(perp1) - get<0>(vertex); + PromotedType const dy1 = get<1>(perp1) - get<1>(vertex); + PromotedType const dx2 = get<0>(perp2) - get<0>(vertex); + PromotedType const dy2 = get<1>(perp2) - get<1>(vertex); - BOOST_ASSERT(buffer_distance != 0); + PromotedType const two = 2.0; + PromotedType const two_pi = two * geometry::math::pi<PromotedType>(); - dx1 /= buffer_distance; - dy1 /= buffer_distance; - dx2 /= buffer_distance; - dy2 /= buffer_distance; + PromotedType const angle1 = atan2(dy1, dx1); + PromotedType angle2 = atan2(dy2, dx2); + while (angle2 > angle1) + { + angle2 -= two_pi; + } + PromotedType const angle_diff = angle1 - angle2; - PromotedType angle_diff = acos(dx1 * dx2 + dy1 * dy2); + // Divide the angle into an integer amount of steps to make it + // visually correct also for a low number of points / circle - PromotedType two = 2.0; - PromotedType steps = m_points_per_circle; - int n = boost::numeric_cast<int>(steps * angle_diff - / (two * geometry::math::pi<PromotedType>())); + // If a full circle is divided into 3 parts (e.g. angle is 125), + // the one point in between must still be generated + // The calculation below: + // - generates 1 point in between for an angle of 125 based on 3 points + // - generates 0 points in between for an angle of 90 based on 4 points - if (n <= 1) - { - return; - } + int const n = (std::max)(static_cast<int>( + ceil(m_points_per_circle * angle_diff / two_pi)), 1); - PromotedType const angle1 = atan2(dy1, dx1); - PromotedType diff = angle_diff / PromotedType(n); + PromotedType const diff = angle_diff / static_cast<PromotedType>(n); PromotedType a = angle1 - diff; + // Walk to n - 1 to avoid generating the last point for (int i = 0; i < n - 1; i++, a -= diff) { Point p; |