[Boost-bugs] [Boost C++ Libraries] #6063: resize does not offset rectangles (etc.) correctly when using corner_fill_arc

Subject: [Boost-bugs] [Boost C++ Libraries] #6063: resize does not offset rectangles (etc.) correctly when using corner_fill_arc
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2011-10-26 21:18:47


#6063: resize does not offset rectangles (etc.) correctly when using
corner_fill_arc
-------------------------------+--------------------------------------------
 Reporter: dbfaken@… | Owner: ljsimons
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: polygon
  Version: Boost 1.47.0 | Severity: Problem
 Keywords: |
-------------------------------+--------------------------------------------
 When using the 'corner_fill_arc' parameter to
 polygon_set_concept<T>::resize(), a minkowski sum using a polygonalized
 circle is used to get the offset shape.

 A symptom of the problem is demonstrated by the following code:

 {{{
  {
   polygon_set_data<int> ps1, ps2, ps3;
   ps1.insert(rectangle_data<int>(0, 0, 50, 50));
   ps2.insert(rectangle_data<int>(0, 0, 50, 50));
   ps3.insert(rectangle_data<int>(0, 0, 50, 50));
   std::cout << "rect before resize: " << ps1 << std::endl;
   ps1.resize(6, true, 0);
   ps2.resize(6, true, 5);
   ps3.resize(6, true, 6);
   rectangle_data<int> ps1_extents, ps2_extents, ps3_extents;
   extents(ps1_extents, ps1);
   extents(ps2_extents, ps2);
   extents(ps3_extents, ps3);
   std::cout << "extents of resized rect with '0' (4) segments in circle: "
 << ps1_extents << std::endl;
   std::cout << "extents of resized rect with 5 segments in circle: " <<
 ps2_extents << std::endl;
   std::cout << "extents of resized rect with 6 segments in circle: " <<
 ps3_extents << std::endl;
   }
 }}}

 If I put this at the end of the gtl_boost_unit_test.cpp, I get the
 following output:

 {{{
 rect before resize: Polygon Set Data { <0 0, 50 0>:1 <50 0, 50 50>:-1 <0
 50, 50 50>:-1 <0 0, 0 50>:1 }
 extents of resized rect with '0' (4) segments in circle: -5 54 -5 54
 extents of resized rect with 5 segments in circle: -6 54 -6 55
 extents of resized rect with 6 segments in circle: -6 55 -6 56
 }}}


 This shows that the extents of the offset shape vary as the number of
 segments does - which should not be the case!

 The extents should all be: -6 56 -6 56

 ----

 The problem (to my eyes) is that the polygonalized circle does not
 generally have the right shape to get proper offsets in axis-oriented
 directions, so the offset is basically multiplied by some factor of
 sqrt(2).
 Attached is an image of the circle generated with num_circle_segments=16.
 The radius of the circle - i.e. distance from center to each vertex - is
 2. The grid spacing is 1. As can be seen, the top/bottom and left/right
 sides of the circle do not lie on the grid.
 If the circle started with a vertex at(0,2) this would not occur and one
 would presumably get proper offsets in axis-aligned directions.
 Alternately one could offset all the vertices slightly farther, but this
 would offset some vertices farther than desired.

 I would guess the fix is to change the behaviour of make_arc(), which
 generates these points, but I'm not sure exactly what the original
 author's intent was - so maybe just using a new function would be best
 (after all, the complexity of make_arc is overkill when you're generating
 a simple full circle)


 ----

 Another problem is that the behaviour of the 'corner_fill_arc' parameter
 is not really well described. Using this gives much more than corner-
 filling behaviour - it gives different offsets in different directions. I
 would suggest explaining it as it is - a minkowski sum with a
 polygonalized circle, with all that implies.

 E.g. for a 45-degree segment the offset will differ from a 90-degree
 segment unless you pick the right value of num_circle_segments.

 Maybe a more comprehensible solution would be to implement corner rounding
 by the intersection of the normal resize()d shape (as given by
 corner_fill_arc=false) with the resize()d shape given by
 corner_fill_arc=true with a larger 'resizing' (picked so that the minimum
 resizing equals the original resizing).

 This would only affect corners, instead of the whole shape.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/6063>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:07 UTC