Eeschema: fix a plot issue with arcs.

Arcs are really error prone, due to different Y axis orientation, and geometry transforms.
Probably we should remove plot and print functions using arc angles as parameters
that are a can of worms.
Fixes #12465
https://gitlab.com/kicad/code/kicad/issues/12465
This commit is contained in:
jean-pierre charras 2022-09-20 14:39:41 +02:00
parent 7e8b6083f4
commit bbaf5a21c2
2 changed files with 17 additions and 18 deletions

View File

@ -161,12 +161,12 @@ void PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR
startAngle = startAngle.Normalize() - ANGLE_360;
}
if( m_yaxisReversed )
{
std::swap( startAngle, endAngle );
startAngle = -startAngle;
endAngle = -endAngle;
}
// In Kicad code, call to Arc() using angles call this function after
// sawpping angles and negate them (to compensate the inverted Y axis).
// So to mimic the other calls in Kicad, do the same thing
std::swap( startAngle, endAngle );
startAngle = -startAngle;
endAngle = -endAngle;
Arc( aCenter, startAngle, endAngle, radius, aFill, aWidth );
}
@ -179,15 +179,15 @@ void PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
EDA_ANGLE endAngle( aEndAngle );
const EDA_ANGLE delta( 5.0, DEGREES_T ); // increment to draw arc
VECTOR2I start, end;
const int sign = -1;
if( startAngle > endAngle )
std::swap( startAngle, endAngle );
SetCurrentLineWidth( aWidth );
/* Please NOTE the different sign due to Y-axis flip */
start.x = aCenter.x + KiROUND( aRadius * -startAngle.Cos() );
start.y = aCenter.y + KiROUND( aRadius * -startAngle.Sin() );
start.x = aCenter.x + KiROUND( aRadius * startAngle.Cos() );
start.y = aCenter.y + sign*KiROUND( aRadius * startAngle.Sin() );
if( aFill != FILL_T::NO_FILL )
{
@ -201,13 +201,13 @@ void PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
{
end.x = aCenter.x + KiROUND( aRadius * -ii.Cos() );
end.y = aCenter.y + KiROUND( aRadius * -ii.Sin() );
end.x = aCenter.x + KiROUND( aRadius * ii.Cos() );
end.y = aCenter.y + sign*KiROUND( aRadius * ii.Sin() );
LineTo( end );
}
end.x = aCenter.x + KiROUND( aRadius * -endAngle.Cos() );
end.y = aCenter.y + KiROUND( aRadius * -endAngle.Sin() );
end.x = aCenter.x + KiROUND( aRadius * endAngle.Cos() );
end.y = aCenter.y + sign*KiROUND( aRadius * endAngle.Sin() );
if( aFill != FILL_T::NO_FILL )
{

View File

@ -233,11 +233,10 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOffs
{
case SHAPE_T::ARC:
{
EDA_ANGLE t1, t2;
CalcArcAngles( t1, t2 );
aTransform.MapAngles( &t1, &t2 );
aPlotter->Arc( center, -t2, -t1, GetRadius(), fill, penWidth );
// In some plotters (not all) the arc is approximated by segments, and
// a error max is needed. We try to approximate by 360/5 segments by 360 deg
int arc2segment_error = CircleToEndSegmentDeltaRadius( GetRadius(), 360/5 );
aPlotter->Arc( center, start, end, fill, penWidth, arc2segment_error );
}
break;