From bbaf5a21c23ea2b6ae8eee6c36a0ea64a61a431c Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 20 Sep 2022 14:39:41 +0200 Subject: [PATCH] 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 --- common/plotters/plotter.cpp | 26 +++++++++++++------------- eeschema/lib_shape.cpp | 9 ++++----- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 9fdbe48375..11a5f3a231 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -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 ) { diff --git a/eeschema/lib_shape.cpp b/eeschema/lib_shape.cpp index 8a8d17a177..0014b62e7d 100644 --- a/eeschema/lib_shape.cpp +++ b/eeschema/lib_shape.cpp @@ -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;