diff DEPENDENCIES/generic/include/boost/polygon/detail/minkowski.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/polygon/detail/minkowski.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,131 @@
+/*
+  Copyright 2008 Intel Corporation
+
+  Use, modification and distribution are 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).
+*/
+namespace boost { namespace polygon { namespace detail {
+
+template <typename coordinate_type>
+struct minkowski_offset {
+  typedef point_data<coordinate_type> point;
+  typedef polygon_set_data<coordinate_type> polygon_set;
+  typedef polygon_with_holes_data<coordinate_type> polygon;
+  typedef std::pair<point, point> edge;
+
+  static void convolve_two_segments(std::vector<point>& figure, const edge& a, const edge& b) {
+    figure.clear();
+    figure.push_back(point(a.first));
+    figure.push_back(point(a.first));
+    figure.push_back(point(a.second));
+    figure.push_back(point(a.second));
+    convolve(figure[0], b.second);
+    convolve(figure[1], b.first);
+    convolve(figure[2], b.first);
+    convolve(figure[3], b.second);
+  }
+
+  template <typename itrT1, typename itrT2>
+  static void convolve_two_point_sequences(polygon_set& result, itrT1 ab, itrT1 ae, itrT2 bb, itrT2 be) {
+    if(ab == ae || bb == be)
+      return;
+    point first_a = *ab;
+    point prev_a = *ab;
+    std::vector<point> vec;
+    polygon poly;
+    ++ab;
+    for( ; ab != ae; ++ab) {
+      point first_b = *bb;
+      point prev_b = *bb;
+      itrT2 tmpb = bb;
+      ++tmpb;
+      for( ; tmpb != be; ++tmpb) {
+        convolve_two_segments(vec, std::make_pair(prev_b, *tmpb), std::make_pair(prev_a, *ab));
+        set_points(poly, vec.begin(), vec.end());
+        result.insert(poly);
+        prev_b = *tmpb;
+      }
+      prev_a = *ab;
+    }
+  }
+
+  template <typename itrT>
+  static void convolve_point_sequence_with_polygons(polygon_set& result, itrT b, itrT e, const std::vector<polygon>& polygons) {
+    for(std::size_t i = 0; i < polygons.size(); ++i) {
+      convolve_two_point_sequences(result, b, e, begin_points(polygons[i]), end_points(polygons[i]));
+      for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(polygons[i]);
+          itrh != end_holes(polygons[i]); ++itrh) {
+        convolve_two_point_sequences(result, b, e, begin_points(*itrh), end_points(*itrh));
+      }
+    }
+  }
+
+  static void convolve_two_polygon_sets(polygon_set& result, const polygon_set& a, const polygon_set& b) {
+    result.clear();
+    std::vector<polygon> a_polygons;
+    std::vector<polygon> b_polygons;
+    a.get(a_polygons);
+    b.get(b_polygons);
+    for(std::size_t ai = 0; ai < a_polygons.size(); ++ai) {
+      convolve_point_sequence_with_polygons(result, begin_points(a_polygons[ai]),
+                                            end_points(a_polygons[ai]), b_polygons);
+      for(typename polygon_with_holes_traits<polygon>::iterator_holes_type itrh = begin_holes(a_polygons[ai]);
+          itrh != end_holes(a_polygons[ai]); ++itrh) {
+        convolve_point_sequence_with_polygons(result, begin_points(*itrh),
+                                              end_points(*itrh), b_polygons);
+      }
+      for(std::size_t bi = 0; bi < b_polygons.size(); ++bi) {
+        polygon tmp_poly = a_polygons[ai];
+        result.insert(convolve(tmp_poly, *(begin_points(b_polygons[bi]))));
+        tmp_poly = b_polygons[bi];
+        result.insert(convolve(tmp_poly, *(begin_points(a_polygons[ai]))));
+      }
+    }
+  }
+};
+
+}
+  template<typename T>
+  inline polygon_set_data<T>&
+  polygon_set_data<T>::resize(coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments) {
+    using namespace ::boost::polygon::operators;
+    if(!corner_fill_arc) {
+      if(resizing < 0)
+        return shrink(-resizing);
+      if(resizing > 0)
+        return bloat(resizing);
+      return *this;
+    }
+    if(resizing == 0) return *this;
+    if(empty()) return *this;
+    if(num_circle_segments < 3) num_circle_segments = 4;
+    rectangle_data<coordinate_type> rect;
+    extents(rect);
+    if(resizing < 0) {
+      ::boost::polygon::bloat(rect, 10);
+      (*this) = rect - (*this); //invert
+    }
+    //make_arc(std::vector<point_data< T> >& return_points,
+    //point_data< double> start, point_data< double>  end,
+    //point_data< double> center,  double r, unsigned int num_circle_segments)
+    std::vector<point_data<coordinate_type> > circle;
+    point_data<double> center(0.0, 0.0), start(0.0, (double)resizing);
+    make_arc(circle, start, start, center, std::abs((double)resizing),
+             num_circle_segments);
+    polygon_data<coordinate_type> poly;
+    set_points(poly, circle.begin(), circle.end());
+    polygon_set_data<coordinate_type> offset_set;
+    offset_set += poly;
+    polygon_set_data<coordinate_type> result;
+    detail::minkowski_offset<coordinate_type>::convolve_two_polygon_sets
+      (result, *this, offset_set);
+    if(resizing < 0) {
+      result = result & rect;//eliminate overhang
+      result = result ^ rect;//invert
+    }
+    *this = result;
+    return *this;
+  }
+
+}}