Improve moving, rendering and plotting of very small angle arcs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17110
(cherry picked from commit b905b4eac8
)
This commit is contained in:
parent
e0381f25f7
commit
bac0820864
|
@ -1067,9 +1067,21 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
|||
if( seg_count % 2 != 0 )
|
||||
seg_count += 1;
|
||||
|
||||
// Our shaders have trouble rendering null line quads, so delegate this task to DrawSegment.
|
||||
if( seg_count == 0 )
|
||||
{
|
||||
VECTOR2D p_start( aCenterPoint.x + cos( startAngle ) * aRadius,
|
||||
aCenterPoint.y + sin( startAngle ) * aRadius );
|
||||
|
||||
VECTOR2D p_end( aCenterPoint.x + cos( endAngle ) * aRadius,
|
||||
aCenterPoint.y + sin( endAngle ) * aRadius );
|
||||
|
||||
DrawSegment( p_start, p_end, aWidth );
|
||||
return;
|
||||
}
|
||||
|
||||
// Recalculate alphaIncrement with a even integer number of segment
|
||||
if( seg_count )
|
||||
alphaIncrement = ( endAngle - startAngle ) / seg_count;
|
||||
alphaIncrement = ( endAngle - startAngle ) / seg_count;
|
||||
|
||||
Save();
|
||||
m_currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0 );
|
||||
|
|
|
@ -833,10 +833,21 @@ void GERBER_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
{
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
EDA_ANGLE endAngle = aStartAngle + aAngle;
|
||||
double arcLength = std::abs( aRadius * aAngle.AsRadians() );
|
||||
|
||||
// aFill is not used here.
|
||||
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
|
||||
if( arcLength < 100 || std::abs( aAngle.AsDegrees() ) < 0.1 )
|
||||
{
|
||||
// Prevent plotting very short arcs as full circles, especially with 4.5 mm precision.
|
||||
// Also reduce the risk of integer overflow issues.
|
||||
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
EDA_ANGLE endAngle = aStartAngle + aAngle;
|
||||
|
||||
// aFill is not used here.
|
||||
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -565,6 +565,13 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
||||
// Avoid integer overflow when calculating the center point
|
||||
if( std::abs( aAngle.AsDegrees() ) < 5 )
|
||||
{
|
||||
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
|
||||
return;
|
||||
}
|
||||
|
||||
double const radius_device = userToDeviceSize( aRadius );
|
||||
double const circumf_device = 2.0 * M_PI * radius_device;
|
||||
double const target_chord_length = m_arcTargetChordLength;
|
||||
|
|
|
@ -191,8 +191,8 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
start.x = aCenter.x + KiROUND( aRadius * startAngle.Cos() );
|
||||
start.y = aCenter.y + sign * KiROUND( aRadius * startAngle.Sin() );
|
||||
start.x = KiROUND( aCenter.x + aRadius * startAngle.Cos() );
|
||||
start.y = KiROUND( aCenter.y + sign * aRadius * startAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
|
@ -206,13 +206,13 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
|
||||
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
|
||||
{
|
||||
end.x = aCenter.x + KiROUND( aRadius * ii.Cos() );
|
||||
end.y = aCenter.y + sign * KiROUND( aRadius * ii.Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * ii.Cos() );
|
||||
end.y = KiROUND( aCenter.y + sign * aRadius * ii.Sin() );
|
||||
LineTo( end );
|
||||
}
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * endAngle.Cos() );
|
||||
end.y = aCenter.y + sign * KiROUND( aRadius * endAngle.Sin() );
|
||||
end.x = KiROUND( aCenter.x + aRadius * endAngle.Cos() );
|
||||
end.y = KiROUND( aCenter.y + sign * aRadius * endAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
|
|
|
@ -141,7 +141,7 @@ protected:
|
|||
|
||||
double Distance( const VECTOR2I& aP ) const
|
||||
{
|
||||
return ( aP - pos ).EuclideanNorm();
|
||||
return VECTOR2D( (double) aP.x - pos.x, (double) aP.y - pos.y ).EuclideanNorm();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue