Patch up arc hit-testing and printing for 6.0
This could use another look when we're not so near release. We really shouldn't need to special case eeWinding vs. not eeWinding. Fixes https://gitlab.com/kicad/code/kicad/issues/9491
This commit is contained in:
parent
08700e3522
commit
5f8e0ef1e0
|
@ -37,12 +37,13 @@
|
||||||
#include <plotters/plotter.h>
|
#include <plotters/plotter.h>
|
||||||
|
|
||||||
|
|
||||||
EDA_SHAPE::EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill ) :
|
EDA_SHAPE::EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill, bool eeWinding ) :
|
||||||
m_endsSwapped( false ),
|
m_endsSwapped( false ),
|
||||||
m_shape( aType ),
|
m_shape( aType ),
|
||||||
m_width( aLineWidth ),
|
m_width( aLineWidth ),
|
||||||
m_fill( aFill ),
|
m_fill( aFill ),
|
||||||
m_editState( 0 )
|
m_editState( 0 ),
|
||||||
|
m_eeWinding( eeWinding )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,16 +692,19 @@ bool EDA_SHAPE::hitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||||
double endAngle;
|
double endAngle;
|
||||||
CalcArcAngles( startAngle, endAngle );
|
CalcArcAngles( startAngle, endAngle );
|
||||||
|
|
||||||
|
if( m_eeWinding && NormalizeAngleDegrees( startAngle - endAngle, -180.0, 180.0 ) > 0 )
|
||||||
|
std::swap( startAngle, endAngle );
|
||||||
|
|
||||||
double relPosAngle = 180.0 / M_PI * atan2( relPos.y, relPos.x );
|
double relPosAngle = 180.0 / M_PI * atan2( relPos.y, relPos.x );
|
||||||
|
|
||||||
if( relPosAngle >= startAngle && relPosAngle <= endAngle )
|
startAngle = NormalizeAngleDegrees( startAngle, 0.0, 360.0 );
|
||||||
return true;
|
endAngle = NormalizeAngleDegrees( endAngle, 0.0, 360.0 );
|
||||||
|
|
||||||
relPosAngle = NormalizeAngleDegrees( relPosAngle, 0.0, 360.0 );
|
relPosAngle = NormalizeAngleDegrees( relPosAngle, 0.0, 360.0 );
|
||||||
|
|
||||||
if( relPosAngle >= startAngle && relPosAngle <= endAngle )
|
if( endAngle > startAngle )
|
||||||
return true;
|
return relPosAngle >= startAngle && relPosAngle <= endAngle;
|
||||||
|
else
|
||||||
|
return relPosAngle >= startAngle || relPosAngle <= endAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -974,36 +978,52 @@ std::vector<wxPoint> EDA_SHAPE::GetRectCorners() const
|
||||||
|
|
||||||
void EDA_SHAPE::computeArcBBox( EDA_RECT& aBBox ) const
|
void EDA_SHAPE::computeArcBBox( EDA_RECT& aBBox ) const
|
||||||
{
|
{
|
||||||
// Do not include the center, which is not necessarily
|
wxPoint start = m_start;
|
||||||
// inside the BB of a arc with a small angle
|
wxPoint end = m_end;
|
||||||
aBBox.SetOrigin( m_start );
|
double t1, t2;
|
||||||
aBBox.Merge( m_end );
|
|
||||||
|
CalcArcAngles( t1, t2 );
|
||||||
|
|
||||||
|
if( m_eeWinding && NormalizeAngleDegrees( t1 - t2, -180.0, 180.0 ) > 0 )
|
||||||
|
std::swap( start, end );
|
||||||
|
|
||||||
|
// Do not include the center, which is not necessarily inside the BB of an arc with a small
|
||||||
|
// included angle
|
||||||
|
aBBox.SetOrigin( start );
|
||||||
|
aBBox.Merge( end );
|
||||||
|
|
||||||
// Determine the starting quarter
|
// Determine the starting quarter
|
||||||
// 0 right-bottom
|
// 0 right-bottom
|
||||||
// 1 left-bottom
|
// 1 left-bottom
|
||||||
// 2 left-top
|
// 2 left-top
|
||||||
// 3 right-top
|
// 3 right-top
|
||||||
unsigned int quarter = 0; // assume right-bottom
|
unsigned int quarter;
|
||||||
|
|
||||||
if( m_start.x < m_arcCenter.x )
|
if( start.x < m_arcCenter.x )
|
||||||
{
|
{
|
||||||
if( m_start.y <= m_arcCenter.y )
|
if( start.y <= m_arcCenter.y )
|
||||||
quarter = 2;
|
quarter = 2;
|
||||||
else // ( m_start.y > m_arcCenter.y )
|
else
|
||||||
quarter = 1;
|
quarter = 1;
|
||||||
}
|
}
|
||||||
else if( m_start.x >= m_arcCenter.x )
|
else if( start.x == m_arcCenter.x )
|
||||||
{
|
{
|
||||||
if( m_start.y < m_arcCenter.y )
|
if( start.y < m_arcCenter.y )
|
||||||
quarter = 3;
|
quarter = 3;
|
||||||
else if( m_start.x == m_arcCenter.x )
|
else
|
||||||
quarter = 1;
|
quarter = 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( start.y < m_arcCenter.y )
|
||||||
|
quarter = 3;
|
||||||
|
else
|
||||||
|
quarter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int radius = GetRadius();
|
int radius = GetRadius();
|
||||||
VECTOR2I startRadial = GetStart() - getCenter();
|
VECTOR2I startRadial = start - m_arcCenter;
|
||||||
VECTOR2I endRadial = GetEnd() - getCenter();
|
VECTOR2I endRadial = end - m_arcCenter;
|
||||||
double angleStart = ArcTangente( startRadial.y, startRadial.x );
|
double angleStart = ArcTangente( startRadial.y, startRadial.x );
|
||||||
double arcAngle = RAD2DECIDEG( endRadial.Angle() - startRadial.Angle() );
|
double arcAngle = RAD2DECIDEG( endRadial.Angle() - startRadial.Angle() );
|
||||||
int angle = (int) NormalizeAnglePos( angleStart ) % 900 + NormalizeAnglePos( arcAngle );
|
int angle = (int) NormalizeAnglePos( angleStart ) % 900 + NormalizeAnglePos( arcAngle );
|
||||||
|
@ -1012,21 +1032,10 @@ void EDA_SHAPE::computeArcBBox( EDA_RECT& aBBox ) const
|
||||||
{
|
{
|
||||||
switch( quarter )
|
switch( quarter )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0: aBBox.Merge( wxPoint( m_arcCenter.x, m_arcCenter.y + radius ) ); break; // down
|
||||||
aBBox.Merge( wxPoint( m_arcCenter.x, m_arcCenter.y + radius ) );
|
case 1: aBBox.Merge( wxPoint( m_arcCenter.x - radius, m_arcCenter.y ) ); break; // left
|
||||||
break; // down
|
case 2: aBBox.Merge( wxPoint( m_arcCenter.x, m_arcCenter.y - radius ) ); break; // up
|
||||||
|
case 3: aBBox.Merge( wxPoint( m_arcCenter.x + radius, m_arcCenter.y ) ); break; // right
|
||||||
case 1:
|
|
||||||
aBBox.Merge( wxPoint( m_arcCenter.x - radius, m_arcCenter.y ) );
|
|
||||||
break; // left
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
aBBox.Merge( wxPoint( m_arcCenter.x, m_arcCenter.y - radius ) );
|
|
||||||
break; // up
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
aBBox.Merge( wxPoint( m_arcCenter.x + radius, m_arcCenter.y ) );
|
|
||||||
break; // right
|
|
||||||
}
|
}
|
||||||
|
|
||||||
++quarter %= 4;
|
++quarter %= 4;
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
LIB_SHAPE::LIB_SHAPE( LIB_SYMBOL* aParent, SHAPE_T aShape, int aDefaultLineWidth,
|
LIB_SHAPE::LIB_SHAPE( LIB_SYMBOL* aParent, SHAPE_T aShape, int aDefaultLineWidth,
|
||||||
FILL_T aFillType ) :
|
FILL_T aFillType ) :
|
||||||
LIB_ITEM( LIB_SHAPE_T, aParent ),
|
LIB_ITEM( LIB_SHAPE_T, aParent ),
|
||||||
EDA_SHAPE( aShape, aDefaultLineWidth, aFillType )
|
EDA_SHAPE( aShape, aDefaultLineWidth, aFillType, true )
|
||||||
{
|
{
|
||||||
m_editState = 0;
|
m_editState = 0;
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,11 @@ void LIB_SHAPE::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
|
||||||
|
|
||||||
CalcArcAngles( t1, t2 );
|
CalcArcAngles( t1, t2 );
|
||||||
|
|
||||||
if( t1 > t2 )
|
if( NormalizeAngle180( t1 - t2 ) > 0 )
|
||||||
aTransform.MapAngles( &t1, &t2 );
|
{
|
||||||
|
std::swap( pt1, pt2 );
|
||||||
|
std::swap( t1, t2 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( forceNoFill || GetFillType() == FILL_T::NO_FILL )
|
if( forceNoFill || GetFillType() == FILL_T::NO_FILL )
|
||||||
|
|
|
@ -62,7 +62,7 @@ enum class FILL_T : int
|
||||||
class EDA_SHAPE
|
class EDA_SHAPE
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill );
|
EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill, bool eeWinding );
|
||||||
|
|
||||||
// Do not create a copy constructor & operator=.
|
// Do not create a copy constructor & operator=.
|
||||||
// The ones generated by the compiler are adequate.
|
// The ones generated by the compiler are adequate.
|
||||||
|
@ -308,6 +308,7 @@ protected:
|
||||||
SHAPE_POLY_SET m_poly; // Stores the S_POLYGON shape
|
SHAPE_POLY_SET m_poly; // Stores the S_POLYGON shape
|
||||||
|
|
||||||
int m_editState;
|
int m_editState;
|
||||||
|
bool m_eeWinding; // Awful hack
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EDA_SHAPE_H
|
#endif // EDA_SHAPE_H
|
||||||
|
|
|
@ -35,14 +35,14 @@
|
||||||
|
|
||||||
PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T idtype, SHAPE_T shapetype ) :
|
PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, KICAD_T idtype, SHAPE_T shapetype ) :
|
||||||
BOARD_ITEM( aParent, idtype ),
|
BOARD_ITEM( aParent, idtype ),
|
||||||
EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
|
EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL, false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, SHAPE_T shapetype ) :
|
PCB_SHAPE::PCB_SHAPE( BOARD_ITEM* aParent, SHAPE_T shapetype ) :
|
||||||
BOARD_ITEM( aParent, PCB_SHAPE_T ),
|
BOARD_ITEM( aParent, PCB_SHAPE_T ),
|
||||||
EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL )
|
EDA_SHAPE( shapetype, Millimeter2iu( DEFAULT_LINE_WIDTH ), FILL_T::NO_FILL, false )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue