Fix a few issues in plotting code. Fix bug in EDA_ANGLE::IsCardinal()

Fixes #10547
https://gitlab.com/kicad/code/kicad/issues/10547
This commit is contained in:
jean-pierre charras 2022-01-21 12:34:32 +01:00
parent c8a50d9b50
commit 0bc5cb33ed
5 changed files with 46 additions and 20 deletions

View File

@ -1263,12 +1263,13 @@ void GERBER_PLOTTER::FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
VECTOR2I size( aSize ); VECTOR2I size( aSize );
EDA_ANGLE orient( aOrient ); EDA_ANGLE orient( aOrient );
orient.Normalize();
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
// Flash a vertical or horizontal shape (this is a basic aperture). // Flash a vertical or horizontal shape (this is a basic aperture).
if( orient.IsCardinal() && aTraceMode == FILLED ) 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 ); std::swap( size.x, size.y );
VECTOR2I pos_device = userToDeviceCoordinates( aPos ); VECTOR2I pos_device = userToDeviceCoordinates( aPos );
@ -1344,13 +1345,18 @@ void GERBER_PLOTTER::FlashPadRect( const VECTOR2I& pos, const VECTOR2I& aSize,
VECTOR2I size( aSize ); VECTOR2I size( aSize );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
EDA_ANGLE orient( aOrient );
orient.Normalize();
// Plot as an aperture flash // Horizontal / vertical rect can use a basic aperture (not a macro)
if( aOrient == ANGLE_90 || aOrient == ANGLE_270 ) // so use it for rotation n*90 deg
std::swap( size.x, size.y ); // if( aOrient.IsCardinal() )
if( orient == ANGLE_0 || orient == ANGLE_90 || orient == ANGLE_180 || orient == ANGLE_270 )
if( aOrient.IsCardinal() )
{ {
if( orient == ANGLE_90 || orient == ANGLE_270 )
// Build the not rotated equivalent shape:
std::swap( size.x, size.y );
if( aTraceMode == SKETCH ) if( aTraceMode == SKETCH )
{ {
if( gbr_metadata ) if( gbr_metadata )

View File

@ -107,8 +107,8 @@ void PSLIKE_PLOTTER::FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSiz
VECTOR2I a( 0, -delta / 2 ); VECTOR2I a( 0, -delta / 2 );
VECTOR2I b( 0, delta / 2 ); VECTOR2I b( 0, delta / 2 );
RotatePoint( a, aPadOrient ); RotatePoint( a, orient );
RotatePoint( b, aPadOrient ); RotatePoint( b, orient );
if( aTraceMode == FILLED ) if( aTraceMode == FILLED )
ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr ); ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr );

View File

@ -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 center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 );
VECTOR2I size( end.x - start.x, end.y - start.y ); VECTOR2I size( end.x - start.x, end.y - start.y );
EDA_ANGLE orient( size ); EDA_ANGLE orient( size );
orient = -orient; // this is due to our Y axis orientation
size.x = KiROUND( EuclideanNorm( size ) ) + aWidth; size.x = KiROUND( EuclideanNorm( size ) ) + aWidth;
size.y = aWidth; size.y = aWidth;

View File

@ -103,7 +103,7 @@ public:
explicit EDA_ANGLE( const VECTOR2I& aVector ) explicit EDA_ANGLE( const VECTOR2I& aVector )
{ {
/* gcc is surprisingly smart in optimizing these conditions in a tree! */ /* gcc is surprisingly smart in optimizing these conditions in a tree! */
if( aVector.x == 0 && aVector.y == 0 ) if( aVector.x == 0 && aVector.y == 0 )
{ {
m_value = 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), * @return true if angle is one of the four cardinal directions (0/90/180/270 degrees),
* otherwise false * otherwise false
*/ */
bool IsCardinal() const bool IsCardinal() const;
{
double test = m_value;
while( test < 0.0 ) /**
test += 90.0; * @return true if angle is one of the two cardinal directions (90/270 degrees),
* otherwise false
while( test > 90.0 ) */
test -= 90.0; bool IsCardinal90() const;
return test == 0.0;
}
bool IsZero() const bool IsZero() const
{ {

View File

@ -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;
}