fix PAD::TransformShapeWithClearanceToPolygon() incorrect calculation in some cases.
For round rect pads, when the arc error was OUTSIDE, the shape was too big and creates bad shape for chamfered round rect pads. For chamfered pads, when the clearance value was not 0, the chamfer was not at the right place.
This commit is contained in:
parent
b996c0d2f5
commit
7265f84358
|
@ -192,6 +192,8 @@ void TransformOvalToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aStart, wxPo
|
|||
void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const wxSize& aSize,
|
||||
int aCornerRadius, int aError, ERROR_LOC aErrorLoc )
|
||||
{
|
||||
SHAPE_POLY_SET outline;
|
||||
|
||||
wxPoint centers[4];
|
||||
wxSize size( aSize / 2 );
|
||||
|
||||
|
@ -228,26 +230,51 @@ void TransformRoundRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const wxSize& a
|
|||
wxPoint pt( -radius, 0 );
|
||||
RotatePoint( &pt, angle );
|
||||
pt += aCenter;
|
||||
aCornerBuffer.Append( pt.x, pt.y );
|
||||
outline.Append( pt.x, pt.y );
|
||||
}
|
||||
};
|
||||
|
||||
aCornerBuffer.NewOutline();
|
||||
outline.NewOutline();
|
||||
|
||||
aCornerBuffer.Append( centers[0] + wxPoint( -radius, 0 ) );
|
||||
outline.Append( centers[0] + wxPoint( -radius, 0 ) );
|
||||
genArc( centers[0], 0, 900 );
|
||||
aCornerBuffer.Append( centers[0] + wxPoint( 0, radius ) );
|
||||
aCornerBuffer.Append( centers[1] + wxPoint( 0, radius ) );
|
||||
outline.Append( centers[0] + wxPoint( 0, radius ) );
|
||||
outline.Append( centers[1] + wxPoint( 0, radius ) );
|
||||
genArc( centers[1], 900, 1800 );
|
||||
aCornerBuffer.Append( centers[1] + wxPoint( radius, 0 ) );
|
||||
aCornerBuffer.Append( centers[2] + wxPoint( radius, 0 ) );
|
||||
outline.Append( centers[1] + wxPoint( radius, 0 ) );
|
||||
outline.Append( centers[2] + wxPoint( radius, 0 ) );
|
||||
genArc( centers[2], 1800, 2700 );
|
||||
aCornerBuffer.Append( centers[2] + wxPoint( 0, -radius ) );
|
||||
aCornerBuffer.Append( centers[3] + wxPoint( 0, -radius ) );
|
||||
outline.Append( centers[2] + wxPoint( 0, -radius ) );
|
||||
outline.Append( centers[3] + wxPoint( 0, -radius ) );
|
||||
genArc( centers[3], 2700, 3600 );
|
||||
aCornerBuffer.Append( centers[3] + wxPoint( -radius, 0 ) );
|
||||
outline.Append( centers[3] + wxPoint( -radius, 0 ) );
|
||||
|
||||
aCornerBuffer.Outline( 0 ).SetClosed( true );
|
||||
outline.Outline( 0 ).SetClosed( true );
|
||||
|
||||
// The created outlines are bigger than the actual outlines, due to the fact
|
||||
// the corner radius is bigger than the initial value when building a shape outside the
|
||||
// actual shape.
|
||||
// However the bounding box shape does not need to be bigger: only rounded corners must
|
||||
// be modified.
|
||||
// So clamp the too big shape by the actual bounding box
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
{
|
||||
SHAPE_POLY_SET bbox;
|
||||
bbox.NewOutline();
|
||||
wxSize bbox_size = aSize/2;
|
||||
|
||||
bbox.Append( wxPoint( -bbox_size.x, -bbox_size.y ) );
|
||||
bbox.Append( wxPoint( bbox_size.x, -bbox_size.y ) );
|
||||
bbox.Append( wxPoint( bbox_size.x, bbox_size.y ) );
|
||||
bbox.Append( wxPoint( -bbox_size.x, bbox_size.y ) );
|
||||
bbox.Outline( 0 ).SetClosed( true );
|
||||
|
||||
outline.BooleanIntersection( bbox, SHAPE_POLY_SET::PM_FAST );
|
||||
// The result is a convex polygon, no need to simplify or fracture.
|
||||
}
|
||||
|
||||
// Add the outline:
|
||||
aCornerBuffer.Append( outline );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -641,13 +641,44 @@ void PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
wxSize shapesize( m_size );
|
||||
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
|
||||
|
||||
radius += aClearanceValue;
|
||||
shapesize.x += aClearanceValue * 2;
|
||||
shapesize.y += aClearanceValue * 2;
|
||||
double chamferRatio = doChamfer ? GetChamferRectRatio() : 0.0;
|
||||
|
||||
if( aClearanceValue )
|
||||
{
|
||||
radius += aClearanceValue;
|
||||
shapesize.x += aClearanceValue * 2;
|
||||
shapesize.y += aClearanceValue * 2;
|
||||
|
||||
// The chamfer position (the 45 deg line on corner) must be
|
||||
// offsetted by aClearanceValue from the base shape chamfer pos
|
||||
// So we recalculate the chamferRatio to do that
|
||||
//
|
||||
// the chamfered shape is square with widet = w, and a corner dist from center
|
||||
// is w*1.414 / 2 = w*0.707
|
||||
// the distance from corner to chamfer line is ch = chamfer_size/707
|
||||
// the distance from center to chamfer line is
|
||||
// d = w*707 - ch/707
|
||||
// so we have:
|
||||
// base shape: d1 = w1*707 - ch1/707 = 0.707 * ( w1 - w1*chamferRatio)
|
||||
// shape with clearance: d2 = w2*707 - ch2/707 = d1 + aClearanceValue
|
||||
const double rootsq_2 = 1.41421356237/2;
|
||||
int d1 = rootsq_2 * std::min( m_size.x, m_size.y ) * ( 1 - GetChamferRectRatio() );
|
||||
int d2 = d1 + aClearanceValue;
|
||||
// d2 = 0.707 * w2 * ( 1 - chamferRatio2 )
|
||||
// 1 - d2 / ( 0.707 * w2 ) = chamferRatio2
|
||||
chamferRatio = 1.0 - d2 / ( rootsq_2 * std::min( shapesize.x, shapesize.y ) );
|
||||
|
||||
// Ensure chamferRatio = 0.0 ... 0.5
|
||||
if( chamferRatio < 0.0 )
|
||||
chamferRatio = 0.0;
|
||||
|
||||
if( chamferRatio > 0.5 )
|
||||
chamferRatio = 0.5;
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET outline;
|
||||
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle, radius,
|
||||
doChamfer ? GetChamferRectRatio() : 0.0,
|
||||
chamferRatio,
|
||||
doChamfer ? GetChamferPositions() : 0,
|
||||
aError, aErrorLoc );
|
||||
|
||||
|
|
Loading…
Reference in New Issue