Fix rendering/plotting of arcs with tiny angle and huge radius.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17343

(cherry picked from commit 4d66a8ebdb)
This commit is contained in:
Alex Shvartzkop 2024-03-09 02:07:21 +03:00
parent ed89827908
commit 6df17bba99
6 changed files with 24 additions and 19 deletions

View File

@ -879,19 +879,19 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, bool aPlotInRegion )
const EDA_ANGLE& aEndAngle, double aRadius, bool aPlotInRegion )
{
VECTOR2I start, end;
start.x = aCenter.x + KiROUND( aRadius * aStartAngle.Cos() );
start.y = aCenter.y + KiROUND( aRadius * aStartAngle.Sin() );
start.x = KiROUND( aCenter.x + aRadius * aStartAngle.Cos() );
start.y = KiROUND( aCenter.y + aRadius * aStartAngle.Sin() );
if( !aPlotInRegion )
MoveTo( start );
else
LineTo( start );
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
end.y = aCenter.y + KiROUND( aRadius * aEndAngle.Sin() );
end.x = KiROUND( aCenter.x + aRadius * aEndAngle.Cos() );
end.y = KiROUND( aCenter.y + aRadius * aEndAngle.Sin() );
VECTOR2D devEnd = userToDeviceCoordinates( end );
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );

View File

@ -581,11 +581,11 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
EDA_ANGLE startAngle = -aStartAngle;
// Calculate arc start point:
VECTOR2I cmap( aCenter.x + KiROUND( aRadius * startAngle.Cos() ),
aCenter.y - KiROUND( aRadius * startAngle.Sin() ) );
VECTOR2I cmap( KiROUND( aCenter.x + aRadius * startAngle.Cos() ),
KiROUND( aCenter.y - aRadius * startAngle.Sin() ) );
VECTOR2D cmap_dev = userToDeviceCoordinates( cmap );
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%.0f,%g",
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%g,%g",
centre_device.x,
centre_device.y,
angle.AsDegrees(),

View File

@ -354,21 +354,21 @@ void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
SetCurrentLineWidth( aWidth );
// Usual trig arc plotting routine...
start.x = aCenter.x + KiROUND( aRadius * (-startAngle).Cos() );
start.y = aCenter.y + KiROUND( aRadius * (-startAngle).Sin() );
start.x = KiROUND( aCenter.x + aRadius * ( -startAngle ).Cos() );
start.y = KiROUND( aCenter.y + aRadius * ( -startAngle ).Sin() );
VECTOR2D pos_dev = userToDeviceCoordinates( start );
fprintf( m_workFile, "%g %g m ", pos_dev.x, pos_dev.y );
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 = KiROUND( aCenter.x + aRadius * ( -ii ).Cos() );
end.y = KiROUND( aCenter.y + aRadius * ( -ii ).Sin() );
pos_dev = userToDeviceCoordinates( end );
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
}
end.x = aCenter.x + KiROUND( aRadius * (-endAngle).Cos() );
end.y = aCenter.y + KiROUND( aRadius * (-endAngle).Sin() );
end.x = KiROUND( aCenter.x + aRadius * ( -endAngle ).Cos() );
end.y = KiROUND( aCenter.y + aRadius * ( -endAngle ).Sin() );
pos_dev = userToDeviceCoordinates( end );
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );

View File

@ -292,7 +292,7 @@ protected:
* be initialized before calling it if needed.
*/
void plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle,
int aRadius, bool aPlotInRegion );
double aRadius, bool aPlotInRegion );
void plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion );
/**

View File

@ -193,8 +193,7 @@ bool TestSegmentHit( const VECTOR2I& aRefPoint, const VECTOR2I& aStart, const VE
*/
inline double GetLineLength( const VECTOR2I& aPointA, const VECTOR2I& aPointB )
{
// Implicitly casted to double
return hypot( aPointA.x - aPointB.x, aPointA.y - aPointB.y );
return hypot( (double) aPointA.x - aPointB.x, (double) aPointA.y - aPointB.y );
}
// These are the usual degrees <-> radians conversion routines

View File

@ -1355,7 +1355,10 @@ EDA_ANGLE PCB_ARC::GetAngle() const
EDA_ANGLE PCB_ARC::GetArcAngleStart() const
{
EDA_ANGLE angleStart( m_Start - GetPosition() );
VECTOR2I pos( GetPosition() );
VECTOR2D dir( (double) m_Start.x - pos.x, (double) m_Start.y - pos.y );
EDA_ANGLE angleStart( dir );
return angleStart.Normalize();
}
@ -1363,7 +1366,10 @@ EDA_ANGLE PCB_ARC::GetArcAngleStart() const
// Note: used in python tests. Ignore CLion's claim that it's unused....
EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
{
EDA_ANGLE angleEnd( m_End - GetPosition() );
VECTOR2I pos( GetPosition() );
VECTOR2D dir( (double) m_End.x - pos.x, (double) m_End.y - pos.y );
EDA_ANGLE angleEnd( dir );
return angleEnd.Normalize();
}