From 0bc5cb33ede81d7533fff570f2024a78bcc2389a Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 21 Jan 2022 12:34:32 +0100 Subject: [PATCH] Fix a few issues in plotting code. Fix bug in EDA_ANGLE::IsCardinal() Fixes #10547 https://gitlab.com/kicad/code/kicad/issues/10547 --- common/plotters/GERBER_plotter.cpp | 18 ++++++++++++------ common/plotters/PS_plotter.cpp | 4 ++-- common/plotters/plotter.cpp | 1 + libs/kimath/include/geometry/eda_angle.h | 19 +++++++------------ libs/kimath/src/geometry/eda_angle.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 29a2c05866..46a34ea48d 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -1263,12 +1263,13 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize, VECTOR2I size( aSize ); EDA_ANGLE orient( aOrient ); + orient.Normalize(); GBR_METADATA* gbr_metadata = static_cast( aData ); // Flash a vertical or horizontal shape (this is a basic aperture). if( orient.IsCardinal() && aTraceMode == FILLED ) { - if( orient == ANGLE_90 || orient == ANGLE_270 ) /* orientation turned 90 deg. */ + if( orient.IsCardinal90() ) std::swap( size.x, size.y ); VECTOR2I pos_device = userToDeviceCoordinates( aPos ); @@ -1344,13 +1345,18 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize, VECTOR2I size( aSize ); GBR_METADATA* gbr_metadata = static_cast( aData ); + EDA_ANGLE orient( aOrient ); + orient.Normalize(); - // Plot as an aperture flash - if( aOrient == ANGLE_90 || aOrient == ANGLE_270 ) - std::swap( size.x, size.y ); - - if( aOrient.IsCardinal() ) + // Horizontal / vertical rect can use a basic aperture (not a macro) + // so use it for rotation n*90 deg + // if( aOrient.IsCardinal() ) + if( orient == ANGLE_0 || orient == ANGLE_90 || orient == ANGLE_180 || orient == ANGLE_270 ) { + if( orient == ANGLE_90 || orient == ANGLE_270 ) + // Build the not rotated equivalent shape: + std::swap( size.x, size.y ); + if( aTraceMode == SKETCH ) { if( gbr_metadata ) diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index 249e00babb..16efb609e9 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -107,8 +107,8 @@ void PSLIKE_PLOTTER::FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSiz VECTOR2I a( 0, -delta / 2 ); VECTOR2I b( 0, delta / 2 ); - RotatePoint( a, aPadOrient ); - RotatePoint( b, aPadOrient ); + RotatePoint( a, orient ); + RotatePoint( b, orient ); if( aTraceMode == FILLED ) ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr ); diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 1381dd2dc8..dfbf415439 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -460,6 +460,7 @@ void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int aWi VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 ); VECTOR2I size( end.x - start.x, end.y - start.y ); EDA_ANGLE orient( size ); + orient = -orient; // this is due to our Y axis orientation size.x = KiROUND( EuclideanNorm( size ) ) + aWidth; size.y = aWidth; diff --git a/libs/kimath/include/geometry/eda_angle.h b/libs/kimath/include/geometry/eda_angle.h index c560698425..a437acade6 100644 --- a/libs/kimath/include/geometry/eda_angle.h +++ b/libs/kimath/include/geometry/eda_angle.h @@ -103,7 +103,7 @@ public: explicit EDA_ANGLE( const VECTOR2I& aVector ) { /* gcc is surprisingly smart in optimizing these conditions in a tree! */ - + if( aVector.x == 0 && aVector.y == 0 ) { m_value = 0; @@ -169,18 +169,13 @@ public: * @return true if angle is one of the four cardinal directions (0/90/180/270 degrees), * otherwise false */ - bool IsCardinal() const - { - double test = m_value; + bool IsCardinal() const; - while( test < 0.0 ) - test += 90.0; - - while( test > 90.0 ) - test -= 90.0; - - return test == 0.0; - } + /** + * @return true if angle is one of the two cardinal directions (90/270 degrees), + * otherwise false + */ + bool IsCardinal90() const; bool IsZero() const { diff --git a/libs/kimath/src/geometry/eda_angle.cpp b/libs/kimath/src/geometry/eda_angle.cpp index 1df1b296af..3387b5b135 100644 --- a/libs/kimath/src/geometry/eda_angle.cpp +++ b/libs/kimath/src/geometry/eda_angle.cpp @@ -46,3 +46,27 @@ EDA_ANGLE EDA_ANGLE::KeepUpright() const } +bool EDA_ANGLE::IsCardinal() const +{ + double test = m_value; + + while( test < 0.0 ) + test += 90.0; + + while( test >= 90.0 ) + test -= 90.0; + + return test == 0.0; +} + + +bool EDA_ANGLE::IsCardinal90() const +{ + // return true if angle is one of the two cardinal directions (90/270 degrees), + double test = std::abs( m_value ); + + while( test >= 180.0 ) + test -= 180.0; + + return test == 90.0; +}