Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83272 - trunk/boost/geometry/extensions/strategies
From: barend.gehrels_at_[hidden]
Date: 2013-03-03 07:28:17


Author: barendgehrels
Date: 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
New Revision: 83272
URL: http://svn.boost.org/trac/boost/changeset/83272

Log:
[geometry] reorganized buffer strategies
Added:
   trunk/boost/geometry/extensions/strategies/buffer_distance_asymmetric.hpp (contents, props changed)
   trunk/boost/geometry/extensions/strategies/buffer_distance_symmetric.hpp (contents, props changed)
   trunk/boost/geometry/extensions/strategies/buffer_join_miter.hpp (contents, props changed)
   trunk/boost/geometry/extensions/strategies/buffer_join_round_by_divide.hpp (contents, props changed)
Text files modified:
   trunk/boost/geometry/extensions/strategies/buffer.hpp | 313 ---------------------------------------
   trunk/boost/geometry/extensions/strategies/buffer_join_round.hpp | 217 ++++++++++++---------------
   2 files changed, 104 insertions(+), 426 deletions(-)

Modified: trunk/boost/geometry/extensions/strategies/buffer.hpp
==============================================================================
--- trunk/boost/geometry/extensions/strategies/buffer.hpp (original)
+++ trunk/boost/geometry/extensions/strategies/buffer.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -17,13 +17,12 @@
 
 // Buffer strategies
 
-#include <boost/geometry/core/cs.hpp>
-#include <boost/geometry/strategies/tags.hpp>
-#include <boost/geometry/strategies/side.hpp>
-#include <boost/geometry/util/math.hpp>
-#include <boost/geometry/util/select_most_precise.hpp>
-
 #include <boost/geometry/extensions/strategies/buffer_side.hpp>
+#include <boost/geometry/extensions/strategies/buffer_join_miter.hpp>
+#include <boost/geometry/extensions/strategies/buffer_join_round.hpp>
+#include <boost/geometry/extensions/strategies/buffer_join_round_by_divide.hpp>
+#include <boost/geometry/extensions/strategies/buffer_distance_symmetric.hpp>
+#include <boost/geometry/extensions/strategies/buffer_distance_asymmetric.hpp>
 
 
 namespace boost { namespace geometry
@@ -61,308 +60,6 @@
 
 
 
-// TODO: merge join_miter with join_round, lot of duplicate code
-
-template
-<
- typename PointIn,
- typename PointOut
->
-struct join_miter
-{
- typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
- typedef typename coordinate_type<PointIn>::type coordinate_type;
-
-
- template <typename RangeOut>
- inline void apply(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- coordinate_type const& buffer_distance,
- RangeOut& range_out) const
- {
- coordinate_type zero = 0;
- int signum = buffer_distance > zero ? 1
- : buffer_distance < zero ? -1
- : 0;
-
- if (side::apply(perp1, ip, perp2) == signum)
- {
- }
- else
- {
- PointIn p = ip;
-
- // Normalize it and give it X*dist.
- coordinate_type dx = get<0>(ip) - get<0>(vertex);
- coordinate_type dy = get<1>(ip) - get<1>(vertex);
-
- coordinate_type length = sqrt(dx * dx + dy * dy);
-
- // TODO: make max-mitre-limit flexible
- coordinate_type ten = 10.0;
- coordinate_type zero_seven = 0.7;
-
- coordinate_type max = ten * geometry::math::abs(buffer_distance);
-
- if (length > max)
- {
-
- coordinate_type prop = zero_seven * buffer_distance;
- prop /= length;
- set<0>(p, get<0>(vertex) + dx * prop);
- set<1>(p, get<1>(vertex) + dy * prop);
-
-#ifdef BOOST_GEOMETRY_DEBUG_BUFFER
- std::cout << length << std::endl;
-#endif
- }
-
- range_out.push_back(perp1);
- range_out.push_back(p);
- range_out.push_back(perp2);
- }
-
- }
-};
-
-
-template
-<
- typename PointIn,
- typename PointOut
->
-struct join_bevel
-{
- typedef typename coordinate_type<PointIn>::type coordinate_type;
-
- template <typename RangeOut>
- inline void apply(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- coordinate_type const& buffer_distance,
- RangeOut& range_out) const
- {
- }
-};
-
-
-template
-<
- typename PointIn,
- typename PointOut
->
-struct join_round
-{
-#ifdef BOOST_GEOMETRY_BUFFER_USE_MIDPOINTS
- inline join_round(int max_level = 4)
- : m_max_level(max_level)
-#else
- inline join_round(int steps_per_circle = 100)
- : m_steps_per_circle(steps_per_circle)
-#endif
- {}
-
- typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
- typedef typename coordinate_type<PointOut>::type coordinate_type;
-
- typedef typename geometry::select_most_precise
- <
- typename geometry::select_most_precise
- <
- typename geometry::coordinate_type<PointIn>::type,
- typename geometry::coordinate_type<PointOut>::type
- >::type,
- double
- >::type promoted_type;
-
-
-#ifdef BOOST_GEOMETRY_BUFFER_USE_MIDPOINTS
-
- int m_max_level;
-
- template <typename RangeOut>
- inline void mid_points(PointIn const& vertex,
- PointIn const& p1, PointIn const& p2,
- coordinate_type const& buffer_distance,
- RangeOut& range_out,
- int level = 1) const
- {
- // Generate 'vectors'
- coordinate_type vp1_x = get<0>(p1) - get<0>(vertex);
- coordinate_type vp1_y = get<1>(p1) - get<1>(vertex);
-
- coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex));
- coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex));
-
- // Average them to generate vector in between
- coordinate_type two = 2;
- coordinate_type v_x = (vp1_x + vp2_x) / two;
- coordinate_type v_y = (vp1_y + vp2_y) / two;
-
- coordinate_type length2 = sqrt(v_x * v_x + v_y * v_y);
-
- coordinate_type prop = buffer_distance / length2;
-
- PointIn mid_point;
- set<0>(mid_point, get<0>(vertex) + v_x * prop);
- set<1>(mid_point, get<1>(vertex) + v_y * prop);
-
- if (level < m_max_level)
- {
- mid_points(vertex, p1, mid_point, buffer_distance, range_out, level + 1);
- }
- range_out.push_back(mid_point);
- if (level < m_max_level)
- {
- mid_points(vertex, mid_point, p2, buffer_distance, range_out, level + 1);
- }
- }
-
-#else
-
- int m_steps_per_circle;
-
- template <typename RangeOut>
- inline void generate_points(PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- promoted_type const& buffer_distance,
- RangeOut& range_out) const
- {
- promoted_type dx1 = get<0>(perp1) - get<0>(vertex);
- promoted_type dy1 = get<1>(perp1) - get<1>(vertex);
- promoted_type dx2 = get<0>(perp2) - get<0>(vertex);
- promoted_type dy2 = get<1>(perp2) - get<1>(vertex);
-
- dx1 /= buffer_distance;
- dy1 /= buffer_distance;
- dx2 /= buffer_distance;
- dy2 /= buffer_distance;
-
- promoted_type angle_diff = acos(dx1 * dx2 + dy1 * dy2);
-
- promoted_type two = 2.0;
- promoted_type steps = m_steps_per_circle;
- int n = boost::numeric_cast<int>(steps * angle_diff
- / (two * geometry::math::pi<promoted_type>()));
-
- if (n > 1000)
- {
- // TODO change this / verify this
- std::cout << dx1 << ", " << dy1 << " .. " << dx2 << ", " << dy2 << std::endl;
- std::cout << angle_diff << " -> " << n << std::endl;
- n = 1000;
- }
- else if (n <= 1)
- {
- return;
- }
-
- promoted_type const angle1 = atan2(dy1, dx1);
- promoted_type diff = angle_diff / promoted_type(n);
- promoted_type a = angle1 - diff;
-
- for (int i = 0; i < n - 1; i++, a -= diff)
- {
- PointIn p;
- set<0>(p, get<0>(vertex) + buffer_distance * cos(a));
- set<1>(p, get<1>(vertex) + buffer_distance * sin(a));
- range_out.push_back(p);
- }
- }
-#endif
-
- template <typename RangeOut>
- inline void apply(PointIn const& ip, PointIn const& vertex,
- PointIn const& perp1, PointIn const& perp2,
- coordinate_type const& buffer_distance,
- RangeOut& range_out) const
- {
- if (geometry::equals(perp1, perp2))
- {
- //std::cout << "Corner for equal points " << geometry::wkt(ip) << " " << geometry::wkt(perp1) << std::endl;
- return;
- }
-
- coordinate_type zero = 0;
- int signum = buffer_distance > zero ? 1
- : buffer_distance < zero ? -1
- : 0;
-
- if (side::apply(perp1, ip, perp2) == signum)
- {
- }
- else
- {
- // Generate 'vectors'
- coordinate_type vix = (get<0>(ip) - get<0>(vertex));
- coordinate_type viy = (get<1>(ip) - get<1>(vertex));
-
- coordinate_type length_i = sqrt(vix * vix + viy * viy);
-
-
- coordinate_type const bd = geometry::math::abs(buffer_distance);
- coordinate_type prop = bd / length_i;
-
- PointIn bp;
- set<0>(bp, get<0>(vertex) + vix * prop);
- set<1>(bp, get<1>(vertex) + viy * prop);
-
- range_out.push_back(perp1);
-
-#ifdef BOOST_GEOMETRY_BUFFER_USE_MIDPOINTS
- if (m_max_level <= 1)
- {
- if (m_max_level == 1)
- {
- range_out.push_back(bp);
- }
- }
- else
- {
- mid_points(vertex, perp1, bp, bd, range_out);
- range_out.push_back(bp);
- mid_points(vertex, bp, perp2, bd, range_out);
- }
-#else
- generate_points(vertex, perp1, perp2, bd, range_out);
-#endif
-
- range_out.push_back(perp2);
- }
- }
-};
-
-
-
-template
-<
- typename CoordinateType
->
-class distance_assymetric
-{
-public :
- distance_assymetric(CoordinateType const& left,
- CoordinateType const& right)
- : m_left(left)
- , m_right(right)
- {}
-
- template <typename Point>
- inline CoordinateType apply(Point const& , Point const& ,
- buffer_side_selector side) const
- {
- return side == buffer_side_left ? m_left : m_right;
- }
-
- inline int factor() const
- {
- return m_left < 0 ? -1 : 1;
- }
-
-private :
- CoordinateType m_left;
- CoordinateType m_right;
-};
-
 
 }} // namespace strategy::buffer
 

Added: trunk/boost/geometry/extensions/strategies/buffer_distance_asymmetric.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_distance_asymmetric.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -0,0 +1,58 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_ASYMMETRIC_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_ASYMMETRIC_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace buffer
+{
+
+
+template<typename CoordinateType>
+class distance_asymmetric
+{
+public :
+ distance_asymmetric(CoordinateType const& left,
+ CoordinateType const& right)
+ : m_left(left)
+ , m_right(right)
+ {}
+
+ template <typename Point>
+ inline CoordinateType apply(Point const& , Point const& ,
+ buffer_side_selector side) const
+ {
+ return side == buffer_side_left ? m_left : m_right;
+ }
+
+ inline int factor() const
+ {
+ return m_left < 0 ? -1 : 1;
+ }
+
+private :
+ CoordinateType m_left;
+ CoordinateType m_right;
+};
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_ASYMMETRIC_HPP

Added: trunk/boost/geometry/extensions/strategies/buffer_distance_symmetric.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_distance_symmetric.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -0,0 +1,55 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_SYMMETRIC_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_SYMMETRIC_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace buffer
+{
+
+
+template<typename CoordinateType>
+class distance_symmetric
+{
+public :
+ inline distance_symmetric(CoordinateType const& distance)
+ : m_distance(distance)
+ {}
+
+ template <typename Point>
+ inline CoordinateType apply(Point const& , Point const& ,
+ buffer_side_selector side) const
+ {
+ return m_distance;
+ }
+
+ inline int factor() const
+ {
+ return 1;
+ }
+
+private :
+ CoordinateType m_distance;
+};
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_DISTANCE_SYMMETRIC_HPP

Added: trunk/boost/geometry/extensions/strategies/buffer_join_miter.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_join_miter.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -0,0 +1,104 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_MITER_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_MITER_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace strategy { namespace buffer
+{
+
+// TODO: condider merging/baseclassing join strategies to avoid duplicate code
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_miter
+{
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointIn>::type coordinate_type;
+
+ // Constructor compatible with other join strategies:
+ inline join_miter(int = 0)
+ {}
+
+ template <typename RangeOut>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ coordinate_type const& buffer_distance,
+ RangeOut& range_out) const
+ {
+ coordinate_type zero = 0;
+ int signum = buffer_distance > zero ? 1
+ : buffer_distance < zero ? -1
+ : 0;
+
+ if (side::apply(perp1, ip, perp2) == signum)
+ {
+ }
+ else
+ {
+ PointIn p = ip;
+
+ // Normalize it and give it X*dist.
+ coordinate_type dx = get<0>(ip) - get<0>(vertex);
+ coordinate_type dy = get<1>(ip) - get<1>(vertex);
+
+ coordinate_type length = sqrt(dx * dx + dy * dy);
+
+ // TODO: make max-mitre-limit flexible
+ coordinate_type ten = 10.0;
+ coordinate_type zero_seven = 0.7;
+
+ coordinate_type max = ten * geometry::math::abs(buffer_distance);
+
+ if (length > max)
+ {
+
+ coordinate_type prop = zero_seven * buffer_distance;
+ prop /= length;
+ set<0>(p, get<0>(vertex) + dx * prop);
+ set<1>(p, get<1>(vertex) + dy * prop);
+
+#ifdef BOOST_GEOMETRY_DEBUG_BUFFER
+ std::cout << length << std::endl;
+#endif
+ }
+
+ range_out.push_back(perp1);
+ range_out.push_back(p);
+ range_out.push_back(perp2);
+ }
+
+ }
+};
+
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_MITER_HPP

Modified: trunk/boost/geometry/extensions/strategies/buffer_join_round.hpp
==============================================================================
--- trunk/boost/geometry/extensions/strategies/buffer_join_round.hpp (original)
+++ trunk/boost/geometry/extensions/strategies/buffer_join_round.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -1,11 +1,6 @@
 // Boost.Geometry (aka GGL, Generic Geometry Library)
 
-// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-
-// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
-// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+// Copyright (c) 2007-2013 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
@@ -15,159 +10,145 @@
 #define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_HPP
 
 
+// Buffer strategies
 
-#include <boost/geometry/algorithms/convert.hpp>
-#include <boost/geometry/arithmetic/arithmetic.hpp>
-#include <boost/geometry/arithmetic/dot_product.hpp>
 #include <boost/geometry/core/cs.hpp>
 #include <boost/geometry/strategies/tags.hpp>
 #include <boost/geometry/strategies/side.hpp>
 #include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
 
 #include <boost/geometry/extensions/strategies/buffer_side.hpp>
 
 
-#define BOOST_GEOMETRY_BUFFER_NO_HELPER_POINTS
-
 
 namespace boost { namespace geometry
 {
 
 
-
-
 namespace strategy { namespace buffer
 {
 
 
-
-
-template<typename PointOut>
-struct join_round2
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_round
 {
- typedef PointOut vector_type;
-
- template <typename Vector, typename Point1, typename Point2>
- static inline Vector create_vector(Point1 const& p1, Point2 const& p2)
- {
- Vector v;
- geometry::convert(p1, v);
- subtract_point(v, p2);
- return v;
- }
-
- inline join_round2(int max_level = 4)
- : m_max_level(max_level)
+ inline join_round(int steps_per_circle = 100)
+ : m_steps_per_circle(steps_per_circle)
     {}
 
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
     typedef typename coordinate_type<PointOut>::type coordinate_type;
- int m_max_level;
 
-
- template <typename OutputIterator, typename Point, typename PointP, typename Point1, typename Point2>
- inline void mid_points(Point const& vertex, PointP const& perpendicular,
- Point1 const& p1, Point2 const& p2,
- coordinate_type const& buffer_distance,
- coordinate_type const& max_distance,
- OutputIterator out,
- int level = 1) const
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointIn>::type,
+ typename geometry::coordinate_type<PointOut>::type
+ >::type,
+ double
+ >::type promoted_type;
+
+ int m_steps_per_circle;
+
+ template <typename RangeOut>
+ inline void generate_points(PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ promoted_type const& buffer_distance,
+ RangeOut& range_out) const
     {
- // Generate 'vectors'
- coordinate_type vp1_x = get<0>(p1) - get<0>(vertex);
- coordinate_type vp1_y = get<1>(p1) - get<1>(vertex);
-
- coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex));
- coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex));
-
- // Average them to generate vector in between
- coordinate_type two = 2;
- coordinate_type v_x = (vp1_x + vp2_x) / two;
- coordinate_type v_y = (vp1_y + vp2_y) / two;
-
- coordinate_type between_length = sqrt(v_x * v_x + v_y * v_y);
+ promoted_type dx1 = get<0>(perp1) - get<0>(vertex);
+ promoted_type dy1 = get<1>(perp1) - get<1>(vertex);
+ promoted_type dx2 = get<0>(perp2) - get<0>(vertex);
+ promoted_type dy2 = get<1>(perp2) - get<1>(vertex);
+
+ dx1 /= buffer_distance;
+ dy1 /= buffer_distance;
+ dx2 /= buffer_distance;
+ dy2 /= buffer_distance;
+
+ promoted_type angle_diff = acos(dx1 * dx2 + dy1 * dy2);
+
+ promoted_type two = 2.0;
+ promoted_type steps = m_steps_per_circle;
+ int n = boost::numeric_cast<int>(steps * angle_diff
+ / (two * geometry::math::pi<promoted_type>()));
 
- coordinate_type const positive_buffer_distance = geometry::math::abs(buffer_distance);
- coordinate_type prop = positive_buffer_distance / between_length;
-
- PointOut mid_point;
- set<0>(mid_point, get<0>(vertex) + v_x * prop);
- set<1>(mid_point, get<1>(vertex) + v_y * prop);
-
- if (buffer_distance > max_distance)
+ if (n > 1000)
         {
- // Calculate point projected on original perpendicular segment,
- // using vector maths
- vector_type v = create_vector<vector_type>(perpendicular, vertex);
- vector_type w = create_vector<vector_type>(mid_point, vertex);
-
- coordinate_type c1 = dot_product(w, v);
- if (c1 > 0)
- {
- coordinate_type c2 = dot_product(v, v);
- if (c2 > c1)
- {
- coordinate_type b = c1 / c2;
-
- PointOut projected_point;
-
- multiply_value(v, b);
- geometry::convert(vertex, projected_point);
- add_point(projected_point, v);
-
- coordinate_type projected_distance = geometry::distance(projected_point, mid_point);
-
- if (projected_distance > max_distance)
- {
- // Do not generate from here on.
- return;
- }
- }
- }
+ // TODO change this / verify this
+ std::cout << dx1 << ", " << dy1 << " .. " << dx2 << ", " << dy2 << std::endl;
+ std::cout << angle_diff << " -> " << n << std::endl;
+ n = 1000;
         }
-
- if (level < m_max_level)
+ else if (n <= 1)
         {
- mid_points(vertex, perpendicular, p1, mid_point, positive_buffer_distance, max_distance, out, level + 1);
+ return;
         }
- *out++ = mid_point;
- if (level < m_max_level)
+
+ promoted_type const angle1 = atan2(dy1, dx1);
+ promoted_type diff = angle_diff / promoted_type(n);
+ promoted_type a = angle1 - diff;
+
+ for (int i = 0; i < n - 1; i++, a -= diff)
         {
- mid_points(vertex, perpendicular, mid_point, p2, positive_buffer_distance, max_distance, out, level + 1);
+ PointIn p;
+ set<0>(p, get<0>(vertex) + buffer_distance * cos(a));
+ set<1>(p, get<1>(vertex) + buffer_distance * sin(a));
+ range_out.push_back(p);
         }
     }
 
-
- template <typename OutputIterator, typename Point, typename Point2>
- inline OutputIterator apply(Point const& vertex,
- Point2 const& perpendicular,
- Point2 const& p1, Point2 const& p2,
+ template <typename RangeOut>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
                 coordinate_type const& buffer_distance,
- coordinate_type const& max_distance,
- OutputIterator out) const
+ RangeOut& range_out) const
     {
- mid_points(vertex, perpendicular, p1, p2, buffer_distance, max_distance, out);
- return out;
- }
-};
+ if (geometry::equals(perp1, perp2))
+ {
+ //std::cout << "Corner for equal points " << geometry::wkt(ip) << " " << geometry::wkt(perp1) << std::endl;
+ return;
+ }
 
+ coordinate_type zero = 0;
+ int signum = buffer_distance > zero ? 1
+ : buffer_distance < zero ? -1
+ : 0;
 
-template<typename PointOut>
-struct join_none
-{
- template <typename OutputIterator, typename Point, typename Point2,
- typename DistanceType>
- inline OutputIterator apply(Point const& ,
- Point2 const& ,
- Point2 const& , Point2 const& ,
- DistanceType const& ,
- DistanceType const& ,
- OutputIterator out) const
- {
- return out;
+ if (side::apply(perp1, ip, perp2) == signum)
+ {
+ }
+ else
+ {
+ // Generate 'vectors'
+ coordinate_type vix = (get<0>(ip) - get<0>(vertex));
+ coordinate_type viy = (get<1>(ip) - get<1>(vertex));
+
+ coordinate_type length_i = sqrt(vix * vix + viy * viy);
+
+ coordinate_type const bd = geometry::math::abs(buffer_distance);
+ coordinate_type prop = bd / length_i;
+
+ PointIn bp;
+ set<0>(bp, get<0>(vertex) + vix * prop);
+ set<1>(bp, get<1>(vertex) + viy * prop);
+
+ range_out.push_back(perp1);
+ generate_points(vertex, perp1, perp2, bd, range_out);
+ range_out.push_back(perp2);
+ }
     }
 };
 
 
+
+
 }} // namespace strategy::buffer
 
 

Added: trunk/boost/geometry/extensions/strategies/buffer_join_round_by_divide.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/geometry/extensions/strategies/buffer_join_round_by_divide.hpp 2013-03-03 07:28:16 EST (Sun, 03 Mar 2013)
@@ -0,0 +1,157 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+
+// Copyright (c) 2007-2013 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
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
+#define BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP
+
+
+// Buffer strategies
+
+#include <boost/geometry/core/cs.hpp>
+#include <boost/geometry/strategies/tags.hpp>
+#include <boost/geometry/strategies/side.hpp>
+#include <boost/geometry/util/math.hpp>
+#include <boost/geometry/util/select_most_precise.hpp>
+
+#include <boost/geometry/extensions/strategies/buffer_side.hpp>
+
+
+
+namespace boost { namespace geometry
+{
+
+
+namespace strategy { namespace buffer
+{
+
+
+template
+<
+ typename PointIn,
+ typename PointOut
+>
+struct join_round_by_divide
+{
+ inline join_round_by_divide(int max_level = 4)
+ : m_max_level(max_level)
+ {}
+
+ typedef typename strategy::side::services::default_strategy<typename cs_tag<PointIn>::type>::type side;
+ typedef typename coordinate_type<PointOut>::type coordinate_type;
+
+ typedef typename geometry::select_most_precise
+ <
+ typename geometry::select_most_precise
+ <
+ typename geometry::coordinate_type<PointIn>::type,
+ typename geometry::coordinate_type<PointOut>::type
+ >::type,
+ double
+ >::type promoted_type;
+
+
+ int m_max_level;
+
+ template <typename RangeOut>
+ inline void mid_points(PointIn const& vertex,
+ PointIn const& p1, PointIn const& p2,
+ coordinate_type const& buffer_distance,
+ RangeOut& range_out,
+ int level = 1) const
+ {
+ // Generate 'vectors'
+ coordinate_type vp1_x = get<0>(p1) - get<0>(vertex);
+ coordinate_type vp1_y = get<1>(p1) - get<1>(vertex);
+
+ coordinate_type vp2_x = (get<0>(p2) - get<0>(vertex));
+ coordinate_type vp2_y = (get<1>(p2) - get<1>(vertex));
+
+ // Average them to generate vector in between
+ coordinate_type two = 2;
+ coordinate_type v_x = (vp1_x + vp2_x) / two;
+ coordinate_type v_y = (vp1_y + vp2_y) / two;
+
+ coordinate_type length2 = sqrt(v_x * v_x + v_y * v_y);
+
+ coordinate_type prop = buffer_distance / length2;
+
+ PointIn mid_point;
+ set<0>(mid_point, get<0>(vertex) + v_x * prop);
+ set<1>(mid_point, get<1>(vertex) + v_y * prop);
+
+ if (level < m_max_level)
+ {
+ mid_points(vertex, p1, mid_point, buffer_distance, range_out, level + 1);
+ }
+ range_out.push_back(mid_point);
+ if (level < m_max_level)
+ {
+ mid_points(vertex, mid_point, p2, buffer_distance, range_out, level + 1);
+ }
+ }
+
+ template <typename RangeOut>
+ inline void apply(PointIn const& ip, PointIn const& vertex,
+ PointIn const& perp1, PointIn const& perp2,
+ coordinate_type const& buffer_distance,
+ RangeOut& range_out) const
+ {
+ if (geometry::equals(perp1, perp2))
+ {
+ //std::cout << "Corner for equal points " << geometry::wkt(ip) << " " << geometry::wkt(perp1) << std::endl;
+ return;
+ }
+
+ coordinate_type zero = 0;
+ int signum = buffer_distance > zero ? 1
+ : buffer_distance < zero ? -1
+ : 0;
+
+ if (side::apply(perp1, ip, perp2) == signum)
+ {
+ }
+ else
+ {
+ // Generate 'vectors'
+ coordinate_type vix = (get<0>(ip) - get<0>(vertex));
+ coordinate_type viy = (get<1>(ip) - get<1>(vertex));
+
+ coordinate_type length_i = sqrt(vix * vix + viy * viy);
+
+ coordinate_type const bd = geometry::math::abs(buffer_distance);
+ coordinate_type prop = bd / length_i;
+
+ PointIn bp;
+ set<0>(bp, get<0>(vertex) + vix * prop);
+ set<1>(bp, get<1>(vertex) + viy * prop);
+
+ range_out.push_back(perp1);
+
+ if (m_max_level > 1)
+ {
+ mid_points(vertex, perp1, bp, bd, range_out);
+ range_out.push_back(bp);
+ mid_points(vertex, bp, perp2, bd, range_out);
+ }
+ else if (m_max_level == 1)
+ {
+ range_out.push_back(bp);
+ }
+
+ range_out.push_back(perp2);
+ }
+ }
+};
+
+
+}} // namespace strategy::buffer
+
+
+}} // namespace boost::geometry
+
+#endif // BOOST_GEOMETRY_EXTENSIONS_STRATEGIES_BUFFER_JOIN_ROUND_BY_DIVIDE_HPP


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk