Fix incorrect calculation in TransformCircleToPolygon(), only noticeable
when the allowed aError is (unusually) large.
This commit is contained in:
parent
fa49b54f93
commit
bcb5618315
|
@ -55,11 +55,14 @@ enum ERROR_LOC { ERROR_OUTSIDE, ERROR_INSIDE };
|
|||
int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree );
|
||||
|
||||
/**
|
||||
* @return the max error when approximating a circle by segments
|
||||
* @param aRadius is the radius of the circle
|
||||
* @return the radius diffence of the circle defined by segments inside the circle
|
||||
* and the radius of the circle tangent to the middle of segments (defined by
|
||||
* segments outside this circle)
|
||||
* @param aInnerCircleRadius is the radius of the circle tangent to the middle
|
||||
* of segments
|
||||
* @param aSegCount is the seg count to approximate the circle
|
||||
*/
|
||||
int GetCircleToSegmentError( int aRadius, int aSegCount );
|
||||
int CircleToEndSegmentDeltaRadius( int aInnerCircleRadius, int aSegCount );
|
||||
|
||||
/**
|
||||
* When creating polygons to create a clearance polygonal area, the polygon must
|
||||
|
|
|
@ -56,8 +56,11 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, wxPoint aCenter,
|
|||
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
{
|
||||
int actual_error = GetCircleToSegmentError( radius, numSegs );
|
||||
radius += GetCircleToPolyCorrection( actual_error );
|
||||
// The outer radius should be radius+aError
|
||||
// Recalculate the actual approx error, as it can be smaller than aError
|
||||
// because numSegs is clamped to a minimal value
|
||||
int actual_delta_radius = CircleToEndSegmentDeltaRadius( radius, numSegs );
|
||||
radius += GetCircleToPolyCorrection( actual_delta_radius );
|
||||
}
|
||||
|
||||
for( int angle = 0; angle < 3600; angle += delta )
|
||||
|
@ -90,7 +93,13 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, wxPoint aCenter, i
|
|||
int radius = aRadius;
|
||||
|
||||
if( aErrorLoc == ERROR_OUTSIDE )
|
||||
radius += GetCircleToPolyCorrection( aError );
|
||||
{
|
||||
// The outer radius should be radius+aError
|
||||
// Recalculate the actual approx error, as it can be smaller than aError
|
||||
// because numSegs is clamped to a minimal value
|
||||
int actual_delta_radius = CircleToEndSegmentDeltaRadius( radius, numSegs );
|
||||
radius += GetCircleToPolyCorrection( actual_delta_radius );
|
||||
}
|
||||
|
||||
aCornerBuffer.NewOutline();
|
||||
|
||||
|
|
|
@ -64,18 +64,22 @@ int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree )
|
|||
}
|
||||
|
||||
|
||||
int GetCircleToSegmentError( int aRadius, int aSegCount )
|
||||
int CircleToEndSegmentDeltaRadius( int aRadius, int aSegCount )
|
||||
{
|
||||
// This is similar to the "inverse" of GetArcToSegmentCount()
|
||||
|
||||
// The minimal seg count is 2, giving error = aRadius
|
||||
// The minimal seg count is 3, otherwise we cannot calculate the result
|
||||
// in practice, the min count is clamped to 8 in kicad
|
||||
if( aSegCount <= 2 )
|
||||
return aRadius;
|
||||
aSegCount = 3;
|
||||
|
||||
// The angle between the center of the segment and one end of the segment
|
||||
// when the circle is approximated by aSegCount segments
|
||||
double alpha = M_PI / aSegCount;
|
||||
int error = KiROUND( aRadius * ( 1.0 - cos( alpha) ) );
|
||||
|
||||
return error;
|
||||
// aRadius is the radius of the circle tangent to the middle of each segment
|
||||
// and aRadius/cos(aplha) is the radius of the circle defined by seg ends
|
||||
int delta = KiROUND( aRadius * ( 1/cos(alpha) - 1 ) );
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
// When creating polygons to create a clearance polygonal area, the polygon must
|
||||
|
|
Loading…
Reference in New Issue