Ticket #6063: boost_polygon_bug6063_fix2.patch
File boost_polygon_bug6063_fix2.patch, 4.2 KB (added by , 11 years ago) |
---|
-
detail/minkowski.hpp
diff -dur orig_polygon/detail/minkowski.hpp polygon/detail/minkowski.hpp
old new 82 82 } 83 83 template<typename T> 84 84 inline polygon_set_data<T>& 85 polygon_set_data<T>::resize(coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments) { 85 polygon_set_data<T>::resize(coordinate_type resizing, bool corner_fill_arc, unsigned int num_circle_segments, 86 double minUnroundedAngleDegrees) { 86 87 using namespace ::boost::polygon::operators; 88 if(resizing == 0) return *this; 89 if(empty()) return *this; 87 90 if(!corner_fill_arc) { 88 91 if(resizing < 0) 89 92 return shrink(-resizing); 90 if(resizing > 0)93 else 91 94 return bloat(resizing); 92 return *this;93 95 } 94 if(resizing == 0) return *this; 95 if(empty()) return *this; 96 96 97 if(num_circle_segments < 3) num_circle_segments = 4; 97 98 rectangle_data<coordinate_type> rect; 98 99 extents(rect); … … 100 101 ::boost::polygon::bloat(rect, 10); 101 102 (*this) = rect - (*this); //invert 102 103 } 103 //make_arc(std::vector<point_data< T> >& return_points, 104 //point_data< double> start, point_data< double> end, 105 //point_data< double> center, double r, unsigned int num_circle_segments) 104 105 // scale arc up so that minimum radius corresponds to 'resizing', 106 // for bug ticket #6063. 107 const double our_pi=3.1415926535897932384626433832795028841971; 108 double arcRadScaling = 1.0/cos(2.0*our_pi/double(num_circle_segments)/2.0); 109 double arcRadius = double(std::abs(resizing))*arcRadScaling; 110 111 if(minUnroundedAngleDegrees < 180.0) 112 { 113 // Don't round corners less than given angle (in radians). 114 // We do this by setting the minimum radius of the 'circle' to correspond to 115 // the distance to the 'elbow' created by normal offset of a corner with the given angle. 116 // e.g. an 90-degree corner with an offset of 1 will generate an elbow at distance sqrt(2). 117 // This will of course offset non-corners more than the given resizing, but the extra area 118 // gets chopped off by the intersection with normal_offset_result, below. 119 double elbowDist = double(std::abs(resizing))/sin(minUnroundedAngleDegrees*our_pi/180.0/2.0); 120 arcRadius = elbowDist*arcRadScaling; 121 } 122 106 123 std::vector<point_data<coordinate_type> > circle; 107 point_data<double> center(0.0, 0.0), start(0.0, (double)resizing); 108 make_arc(circle, start, start, center, std::abs((double)resizing), 109 num_circle_segments); 124 point_data<double> center(0.0, 0.0), start(0.0, arcRadius); 125 make_arc(circle, start, start, center, arcRadius, num_circle_segments); 110 126 polygon_data<coordinate_type> poly; 111 127 set_points(poly, circle.begin(), circle.end()); 112 128 polygon_set_data<coordinate_type> offset_set; … … 114 130 polygon_set_data<coordinate_type> result; 115 131 detail::minkowski_offset<coordinate_type>::convolve_two_polygon_sets 116 132 (result, *this, offset_set); 133 134 // Intersect with result of 'normal' (non-minkowski-sum) offset, 135 // to remove offsets larger than the given 'resizing' when not near corners. 136 // Also for bug ticket #6063 137 polygon_set_data<coordinate_type> normal_offset_result(*this); 138 normal_offset_result.bloat(std::abs(resizing)); 139 result = result & normal_offset_result; 140 117 141 if(resizing < 0) { 118 142 result = result & rect;//eliminate overhang 119 143 result = result ^ rect;//invert 120 144 } 145 121 146 *this = result; 122 147 return *this; 123 148 } -
polygon_set_data.hpp
diff -dur orig_polygon/polygon_set_data.hpp polygon/polygon_set_data.hpp
old new 359 359 } 360 360 361 361 inline polygon_set_data& 362 resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0); 362 resize(coordinate_type resizing, bool corner_fill_arc = false, unsigned int num_circle_segments=0, 363 double minUnroundedAngleDegrees=180.0); 363 364 364 365 template <typename transform_type> 365 366 inline polygon_set_data&