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