Validate arc output when editing
Handles checking output of the arc to ensure we don't end up generating an invalid arc. Also keeps the limit of the arc angle to be (360,360) excluding 0. Fixes https://gitlab.com/kicad/code/kicad/issues/10070
This commit is contained in:
parent
aa5b6c70a7
commit
8fc831cbc2
|
@ -109,7 +109,7 @@ void RotatePoint( double *pX, double *pY, double cx, double cy, double angle );
|
|||
const VECTOR2I CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aMid, const VECTOR2I& aEnd );
|
||||
const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd );
|
||||
const wxPoint CalcArcCenter( const wxPoint& aStart, const wxPoint& aMid, const wxPoint& aEnd );
|
||||
const wxPoint CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle );
|
||||
const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aAngle );
|
||||
|
||||
/**
|
||||
* Return the subtended angle for a given arc.
|
||||
|
|
|
@ -359,10 +359,10 @@ void RotatePoint( double* pX, double* pY, double angle )
|
|||
}
|
||||
|
||||
|
||||
const wxPoint CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle )
|
||||
const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aEnd, double aAngle )
|
||||
{
|
||||
VECTOR2I start = aStart;
|
||||
VECTOR2I end = aEnd;
|
||||
VECTOR2D start = aStart;
|
||||
VECTOR2D end = aEnd;
|
||||
|
||||
if( aAngle < 0 )
|
||||
{
|
||||
|
@ -376,14 +376,14 @@ const wxPoint CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, doubl
|
|||
aAngle = 360 - aAngle;
|
||||
}
|
||||
|
||||
int chord = ( start - end ).EuclideanNorm();
|
||||
int r = ( chord / 2 ) / sin( aAngle * M_PI / 360.0 );
|
||||
double chord = ( start - end ).EuclideanNorm();
|
||||
double r = chord / ( 2.0 * sin( ( aAngle / 2.0 ) * M_PI / 180.0 ) );
|
||||
|
||||
VECTOR2I vec = end - start;
|
||||
VECTOR2D vec = end - start;
|
||||
vec = vec.Resize( r );
|
||||
vec = vec.Rotate( ( 180.0 - aAngle ) * M_PI / 360.0 );
|
||||
vec = vec.Rotate( ( 90.0 - aAngle / 2.0 ) * M_PI / 180.0 );
|
||||
|
||||
return (wxPoint) ( start + vec );
|
||||
return start + vec;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ DIALOG_GRAPHIC_ITEM_PROPERTIES::DIALOG_GRAPHIC_ITEM_PROPERTIES( PCB_BASE_EDIT_FR
|
|||
m_bezierCtrl2Y.SetCoordType( ORIGIN_TRANSFORMS::ABS_Y_COORD );
|
||||
|
||||
m_angle.SetUnits( EDA_UNITS::DEGREES );
|
||||
m_AngleValidator.SetRange( -360.0, 360.0 );
|
||||
m_AngleValidator.SetRange( -359.9, 359.9 );
|
||||
m_angleCtrl->SetValidator( m_AngleValidator );
|
||||
m_AngleValidator.SetWindow( m_angleCtrl );
|
||||
|
||||
|
@ -316,8 +316,11 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
|
|||
}
|
||||
|
||||
if( m_item->GetShape() == SHAPE_T::ARC )
|
||||
m_item->SetCenter( CalcArcCenter( m_item->GetStart(), m_item->GetEnd(), m_AngleValue ) );
|
||||
{
|
||||
VECTOR2D center = CalcArcCenter( m_item->GetStart(), m_item->GetEnd(), m_AngleValue );
|
||||
|
||||
m_item->SetCenter( wxPoint( KiROUND( center.x ), KiROUND( center.y ) ) );
|
||||
}
|
||||
if( m_fp_item )
|
||||
{
|
||||
// We are editing a footprint; init the item coordinates relative to the footprint anchor.
|
||||
|
@ -371,10 +374,28 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::Validate()
|
|||
error_msgs.Add( _( "The arc angle cannot be zero." ) );
|
||||
|
||||
if( m_startX.GetValue() == m_endX.GetValue() && m_startY.GetValue() == m_endY.GetValue() )
|
||||
error_msgs.Add( _( "The radius cannot be zero." ) );
|
||||
{
|
||||
error_msgs.Add( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
|
||||
0.0, m_angle.GetDoubleValue() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
VECTOR2D start( m_startX.GetValue(), m_startY.GetValue() );
|
||||
VECTOR2D end( m_endX.GetValue(), m_endY.GetValue() );
|
||||
VECTOR2D center = CalcArcCenter( start, end, m_angle.GetDoubleValue() );
|
||||
|
||||
double radius = ( center - start ).EuclideanNorm();
|
||||
double max_offset = std::max( std::abs( center.x ) + radius,
|
||||
std::abs( center.y ) + radius );
|
||||
|
||||
if( max_offset >= ( std::numeric_limits<VECTOR2I::coord_type>::max() / 2 )
|
||||
|| center == start || center == end )
|
||||
{
|
||||
error_msgs.Add( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
|
||||
radius, m_angle.GetDoubleValue() ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
// Check radius.
|
||||
if( m_endX.GetValue() == 0 )
|
||||
|
|
|
@ -1929,7 +1929,9 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool
|
|||
frame()->SetMsgPanel( graphic );
|
||||
break;
|
||||
}
|
||||
else if( arcManager.GetStep() == KIGFX::PREVIEW::ARC_GEOM_MANAGER::SET_ANGLE )
|
||||
// Don't show the edit panel if we can't represent the arc with it
|
||||
else if( ( arcManager.GetStep() == KIGFX::PREVIEW::ARC_GEOM_MANAGER::SET_ANGLE )
|
||||
&& ( arcManager.GetStartRadiusEnd() != arcManager.GetEndRadiusEnd() ) )
|
||||
{
|
||||
frame()->OnEditItemRequest( graphic );
|
||||
m_view->Update( &preview );
|
||||
|
|
Loading…
Reference in New Issue