Pcbnew: better approximation of arcs by polygons for pads having a very small size.
Especially, small round rect pads have a ugly shape because the number of segments is small and the 90 deg arcs are not very well approximated. The minimal seg count for 90 deg arcs is now 4 (16 segm/circle) for pads. Fixes: lp:1833005 https://bugs.launchpad.net/kicad/+bug/1833005
This commit is contained in:
parent
1f35ec5521
commit
8085899d0a
|
@ -228,7 +228,7 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
double aRotation, int aCornerRadius,
|
||||
double aChamferRatio, int aChamferCorners,
|
||||
int aError )
|
||||
int aApproxErrorMax, int aMinSegPerCircleCount )
|
||||
{
|
||||
// Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
|
||||
// or in actual position/orientation for round rect only
|
||||
|
@ -243,7 +243,8 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
for( int ii = 0; ii < 4; ++ii )
|
||||
outline.Append( corners[ii].x, corners[ii].y );
|
||||
|
||||
int numSegs = std::max( GetArcToSegmentCount( aCornerRadius, aError, 360.0 ), 6 );
|
||||
int numSegs = std::max( GetArcToSegmentCount( aCornerRadius, aApproxErrorMax, 360.0 ),
|
||||
aMinSegPerCircleCount );
|
||||
outline.Inflate( aCornerRadius, numSegs );
|
||||
|
||||
if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
|
||||
|
|
|
@ -117,13 +117,17 @@ void GetRoundRectCornerCenters( wxPoint aCenters[4], int aRadius,
|
|||
* 4 = BOTTOM_LEFT
|
||||
* 8 = BOTTOM_RIGHT
|
||||
* One can have more than one chamfered corner by ORing the corner identifers
|
||||
* @param aError = the IU allowed for error in approximation
|
||||
* @param aApproxErrorMax = the IU allowed for error in approximation
|
||||
* @param aMinSegPerCircleCount = the minimal segments per circle count in approximation
|
||||
* (aApproxErrorMax can generate must more seg count than aMinSegPerCircleCount)
|
||||
* To allow a reasonable good shape even for very small shapes, the min count is 16
|
||||
* (must be a multiple of 4 becauseusually arcs are 90 deg.
|
||||
*/
|
||||
void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
||||
const wxPoint& aPosition, const wxSize& aSize,
|
||||
double aRotation, int aCornerRadius,
|
||||
double aChamferRatio, int aChamferCorners,
|
||||
int aError );
|
||||
int aApproxErrorMax, int aMinSegPerCircleCount = 16 );
|
||||
|
||||
/**
|
||||
* Function TransformRoundedEndsSegmentToPolygon
|
||||
|
|
|
@ -572,6 +572,10 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
|||
{
|
||||
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for pads." );
|
||||
|
||||
// minimal segment count to approximate a circle to create the polygonal pad shape
|
||||
// This minimal value is mainly for very small pads, like SM0402.
|
||||
// Most of time pads are using the segment count given by aError value.
|
||||
const int pad_min_seg_per_circle_count = 16;
|
||||
double angle = m_Orient;
|
||||
int dx = (m_Size.x / 2) + aClearanceValue;
|
||||
int dy = (m_Size.y / 2) + aClearanceValue;
|
||||
|
@ -625,7 +629,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
|||
outline.Append( corners[ii].x, corners[ii].y );
|
||||
}
|
||||
|
||||
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ), 6 );
|
||||
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
|
||||
pad_min_seg_per_circle_count );
|
||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
||||
|
||||
int rounding_radius = KiROUND( aClearanceValue * correction );
|
||||
|
@ -639,7 +644,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
|||
case PAD_SHAPE_ROUNDRECT:
|
||||
{
|
||||
int radius = GetRoundRectCornerRadius() + aClearanceValue;
|
||||
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
|
||||
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ),
|
||||
pad_min_seg_per_circle_count );
|
||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
||||
int clearance = KiROUND( aClearanceValue * correction );
|
||||
int rounding_radius = KiROUND( radius * correction );
|
||||
|
@ -660,7 +666,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon(
|
|||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
{
|
||||
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ), 6 );
|
||||
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ),
|
||||
pad_min_seg_per_circle_count );
|
||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
||||
int clearance = KiROUND( aClearanceValue * correction );
|
||||
SHAPE_POLY_SET outline; // Will contain the corners in board coordinates
|
||||
|
@ -844,7 +851,8 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
|
|||
// The pattern roughtly is a 90 deg arc pie
|
||||
std::vector <wxPoint> corners_buffer;
|
||||
|
||||
int numSegs = std::max( GetArcToSegmentCount( dx + aThermalGap, aError, 360.0 ), 6 );
|
||||
int numSegs = std::max( GetArcToSegmentCount( dx + aThermalGap, aError, 360.0 ),
|
||||
8 );
|
||||
double correction = GetCircletoPolyCorrectionFactor( numSegs );
|
||||
double delta = 3600.0 / numSegs;
|
||||
|
||||
|
|
Loading…
Reference in New Issue