Better calculations in TransformRoundChamferedRectToPolygon().

the old calculations was creating a slightly too small shape for rounded corners.

Now the polygon is outside the perfect shape (as required to create a shape with clearance)

Fixes #4805
https://gitlab.com/kicad/code/kicad/issues/4805
This commit is contained in:
jean-pierre charras 2020-07-05 18:16:33 +02:00
parent 6eca886292
commit 82da739786
2 changed files with 32 additions and 1 deletions

View File

@ -243,7 +243,35 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const
// These are small radius corners (of which there may be many), so peg the segs-per-circle
// to no more than 16.
int numSegs = std::max( GetArcToSegmentCount( aCornerRadius, aError, 360.0 ), 16 );
outline.Inflate( aCornerRadius, numSegs );
// To build the polygonal shape outside the actual shape, we use a bigger
// radius to build rounded corners.
// However, the size of the shape is too large.
// so, we also clamp the polygonal shape with the bounding box
// of the initial shape.
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int radius = aCornerRadius * correction; // make segments outside the circles
outline.Inflate( radius, numSegs );
if( correction > 1.0 )
{
// Refinement: clamp the inflated polygonal shape by the rectangular shape
// containing the rounded polygon
SHAPE_POLY_SET bbox; // the rectangular shape
bbox.NewOutline();
for( const wxPoint& corner : corners )
bbox.Append( corner );
// Just build the rectangular bbox
bbox.Inflate( aCornerRadius, 1, SHAPE_POLY_SET::CORNER_STRATEGY::ALLOW_ACUTE_CORNERS );
// Now, clamp the shape
outline.BooleanIntersection( bbox, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
// Note the final polygon is a simple, convex polygon with no hole
// due to the shape of initial polygons
}
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
{

View File

@ -576,6 +576,9 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int clearance = KiROUND( aClearanceValue * correction );
outline.Inflate( clearance, numSegs );
// TODO: clamp the inflated polygon, because it is slightly too big:
// it was inflated by a value slightly too big to keep rounded corners
// ouside the pad area.
}
aCornerBuffer.Append( outline );