Better algo to calculate the segment count to convert a DRAWSEGMENT arc or circle to a set of segments.
Currently, the max error between the arc/circle and a segment is set to 0.05 mm
This commit is contained in:
parent
ebd2b78f86
commit
8fcbb64a46
|
@ -505,17 +505,25 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
|
||||||
if( m_Shape == S_CIRCLE || m_Shape == S_ARC )
|
if( m_Shape == S_CIRCLE || m_Shape == S_ARC )
|
||||||
{
|
{
|
||||||
// this is an ugly hack, but I don't want to change the file format now that we are in feature freeze.
|
// this is an ugly hack, but I don't want to change the file format now that we are in feature freeze.
|
||||||
// the circle to segment count parameter is essentially useless for larger circle/arc shapes as it doesn't provide
|
// the circle to segment count parameter is essentially useless for larger circle/arc shapes as
|
||||||
// sufficient approximation accuracy. Here we compute the necessary number of segments based on
|
// it doesn't provide sufficient approximation accuracy.
|
||||||
// percentage accuracy required. This is currently mapped to the CircleToSegmentCount parameter: low value (16)
|
// Here we compute the necessary number of segments based on error between circle and segments
|
||||||
// means 1% accuracy, high - 0.33% acciracy.
|
// The max error is the distance between the middle of a segment, and the circle
|
||||||
|
//
|
||||||
|
// Warning: too small values can create very long calculation time in zone filling
|
||||||
|
double error_max = Millimeter2iu( 0.05 );
|
||||||
|
// error relative to the radius value
|
||||||
|
double rel_error = error_max / GetRadius();
|
||||||
|
// best arc increment
|
||||||
|
double step = 180 / M_PI * acos( 1.0 - rel_error );
|
||||||
|
// the best seg count for a circle
|
||||||
|
int segCount = KiROUND( 360.0 / step );
|
||||||
|
|
||||||
double accuracy = aCircleToSegmentsCount == 16 ? 0.01 : 0.0033;
|
if( segCount > aCircleToSegmentsCount )
|
||||||
double r = GetRadius();
|
{
|
||||||
double step = 180.0 / M_PI * acos( r * ( 1.0 - accuracy ) / r );
|
aCircleToSegmentsCount = segCount;
|
||||||
|
aCorrectionFactor = 1.0 / cos( M_PI / (aCircleToSegmentsCount * 2) );
|
||||||
aCircleToSegmentsCount = (int) ceil( 360.0 / step );
|
}
|
||||||
aCorrectionFactor = 1.0 / cos( M_PI / (aCircleToSegmentsCount * 2) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( m_Shape )
|
switch( m_Shape )
|
||||||
|
|
Loading…
Reference in New Issue