Another try at fixing arcs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15471 Fixes https://gitlab.com/kicad/code/kicad/-/issues/15469
This commit is contained in:
parent
e98dfa2bfc
commit
10e2e4a12d
|
@ -339,12 +339,12 @@ void CAIRO_GAL_BASE::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
|||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle )
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle )
|
||||
{
|
||||
syncLineWidth();
|
||||
|
||||
double startAngle = aStartAngle.AsRadians();
|
||||
double endAngle = aEndAngle.AsRadians();
|
||||
double endAngle = startAngle + aAngle.AsRadians();
|
||||
|
||||
// calculate start and end arc angles according to the rotation transform matrix
|
||||
// and normalize:
|
||||
|
@ -378,7 +378,7 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
|||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
|
||||
double aWidth, double aMaxError )
|
||||
{
|
||||
// Note: aMaxError is not used because Cairo can draw true arcs
|
||||
|
@ -387,7 +387,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
|||
m_lineWidth = aWidth;
|
||||
m_isStrokeEnabled = true;
|
||||
m_isFillEnabled = false;
|
||||
DrawArc( aCenterPoint, aRadius, aStartAngle, aEndAngle );
|
||||
DrawArc( aCenterPoint, aRadius, aStartAngle, aAngle );
|
||||
m_isFillEnabled = true;
|
||||
m_isStrokeEnabled = false;
|
||||
return;
|
||||
|
@ -398,7 +398,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
|||
// calculate start and end arc angles according to the rotation transform matrix
|
||||
// and normalize:
|
||||
double startAngleS = aStartAngle.AsRadians();
|
||||
double endAngleS = aEndAngle.AsRadians();
|
||||
double endAngleS = startAngleS + aAngle.AsRadians();
|
||||
arc_angles_xform_and_normalize( startAngleS, endAngleS );
|
||||
|
||||
double r = xform( aRadius );
|
||||
|
|
|
@ -892,16 +892,16 @@ void OPENGL_GAL::drawCircle( const VECTOR2D& aCenterPoint, double aRadius, bool
|
|||
|
||||
|
||||
void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle )
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle )
|
||||
{
|
||||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
||||
double startAngle = aStartAngle.AsRadians();
|
||||
double endAngle = aEndAngle.AsRadians();
|
||||
double endAngle = startAngle + aAngle.AsRadians();
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += M_PI * 2;
|
||||
// Normalize arc angles
|
||||
SWAP( startAngle, >, endAngle );
|
||||
|
||||
const double alphaIncrement = calcAngleStep( aRadius );
|
||||
|
||||
|
@ -964,7 +964,7 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
|||
|
||||
|
||||
void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
|
||||
double aWidth, double aMaxError )
|
||||
{
|
||||
if( aRadius <= 0 )
|
||||
|
@ -977,7 +977,7 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
|||
}
|
||||
|
||||
double startAngle = aStartAngle.AsRadians();
|
||||
double endAngle = aEndAngle.AsRadians();
|
||||
double endAngle = startAngle + aAngle.AsRadians();
|
||||
|
||||
// Swap the angles, if start angle is greater than end angle
|
||||
SWAP( startAngle, >, endAngle );
|
||||
|
|
|
@ -657,20 +657,20 @@ void DXF_PLOTTER::ThickSegment( const VECTOR2I& aStart, const VECTOR2I& aEnd, in
|
|||
|
||||
|
||||
void DXF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
|
||||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
||||
EDA_ANGLE startAngle( aStartAngle );
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
EDA_ANGLE startAngle = -aStartAngle;
|
||||
EDA_ANGLE endAngle = startAngle - aAngle;
|
||||
|
||||
// In DXF, arcs are drawn CCW.
|
||||
// If startAngle > endAngle, it is CW. So transform it to CCW
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
if( endAngle < startAngle )
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
VECTOR2D centre_device = userToDeviceCoordinates( aCenter );
|
||||
double radius_device = userToDeviceSize( aRadius );
|
||||
|
|
|
@ -818,14 +818,11 @@ void GERBER_PLOTTER::Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFil
|
|||
|
||||
|
||||
void GERBER_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
|
||||
while( endAngle < aStartAngle )
|
||||
endAngle += ANGLE_360;
|
||||
EDA_ANGLE endAngle = aStartAngle + aAngle;
|
||||
|
||||
// aFill is not used here.
|
||||
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
|
||||
|
@ -875,7 +872,7 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
|||
{
|
||||
VECTOR2I start, end;
|
||||
start.x = aCenter.x + KiROUND( aRadius * aStartAngle.Cos() );
|
||||
start.y = aCenter.y - KiROUND( aRadius * aStartAngle.Sin() );
|
||||
start.y = aCenter.y + KiROUND( aRadius * aStartAngle.Sin() );
|
||||
|
||||
if( !aPlotInRegion )
|
||||
MoveTo( start );
|
||||
|
@ -883,14 +880,14 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn
|
|||
LineTo( start );
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
|
||||
end.y = aCenter.y - KiROUND( aRadius * aEndAngle.Sin() );
|
||||
end.y = aCenter.y + KiROUND( 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 );
|
||||
|
||||
fprintf( m_outputFile, "G75*\n" ); // Multiquadrant (360 degrees) mode
|
||||
|
||||
if( aStartAngle < aEndAngle )
|
||||
if( aStartAngle > aEndAngle )
|
||||
fprintf( m_outputFile, "G03*\n" ); // Active circular interpolation, CCW
|
||||
else
|
||||
fprintf( m_outputFile, "G02*\n" ); // Active circular interpolation, CW
|
||||
|
@ -1145,11 +1142,12 @@ void GERBER_PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, i
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, int aWidth,
|
||||
const EDA_ANGLE& aAngle, double aRadius, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
|
||||
SetCurrentLineWidth( aWidth, gbr_metadata );
|
||||
|
||||
if( gbr_metadata )
|
||||
|
@ -1157,57 +1155,19 @@ void GERBER_PLOTTER::ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartA
|
|||
|
||||
if( aTraceMode == FILLED )
|
||||
{
|
||||
Arc( aCentre, aStartAngle, aEndAngle, aRadius, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
Arc( aCentre, aStartAngle, aAngle, aRadius, FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
|
||||
Arc( aCentre, aStartAngle, aEndAngle, aRadius - ( aWidth - m_currentPenWidth ) / 2,
|
||||
Arc( aCentre, aStartAngle, aAngle, aRadius - ( aWidth - m_currentPenWidth ) / 2,
|
||||
FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
Arc( aCentre, aStartAngle, aEndAngle, aRadius + ( aWidth - m_currentPenWidth ) / 2,
|
||||
Arc( aCentre, aStartAngle, aAngle, aRadius + ( aWidth - m_currentPenWidth ) / 2,
|
||||
FILL_T::NO_FILL, DO_NOT_SET_LINE_WIDTH );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::ThickArc( const VECTOR2I& aCentre, const VECTOR2I& aStart,
|
||||
const VECTOR2I& aEnd, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
EDA_ANGLE start_angle( aStart - aCentre );
|
||||
EDA_ANGLE end_angle( aEnd - aCentre );
|
||||
|
||||
if( start_angle > end_angle )
|
||||
{
|
||||
if( end_angle < ANGLE_0 )
|
||||
end_angle.Normalize();
|
||||
else
|
||||
start_angle = start_angle.Normalize() - ANGLE_360;
|
||||
}
|
||||
|
||||
int radius = (aStart - aCentre).EuclideanNorm();
|
||||
|
||||
if( !m_yaxisReversed ) // should be always the case
|
||||
{
|
||||
std::swap( end_angle, start_angle );
|
||||
end_angle = -end_angle;
|
||||
start_angle = -start_angle;
|
||||
}
|
||||
|
||||
ThickArc( aCentre, start_angle, end_angle, radius, aWidth, aTraceMode, aData );
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::ThickArc( const EDA_SHAPE& aArcShape,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
wxASSERT( aArcShape.GetShape() == SHAPE_T::ARC );
|
||||
|
||||
ThickArc( aArcShape.getCenter(), aArcShape.GetStart(), aArcShape.GetEnd(),
|
||||
aArcShape.GetWidth(), aTraceMode, aData );
|
||||
}
|
||||
|
||||
|
||||
void GERBER_PLOTTER::ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width,
|
||||
OUTLINE_MODE tracemode, void* aData )
|
||||
{
|
||||
|
|
|
@ -568,7 +568,7 @@ void HPGL_PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end,
|
|||
|
||||
|
||||
void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
if( aRadius <= 0 )
|
||||
return;
|
||||
|
@ -581,23 +581,16 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
chord_angle = std::max( m_arcMinChordDegrees, std::min( chord_angle, ANGLE_45 ) );
|
||||
|
||||
VECTOR2D centre_device = userToDeviceCoordinates( aCenter );
|
||||
EDA_ANGLE angle = aAngle;
|
||||
|
||||
EDA_ANGLE startAngle( aStartAngle );
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
if( !m_plotMirror )
|
||||
angle = -angle;
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
|
||||
EDA_ANGLE angle;
|
||||
|
||||
if( m_plotMirror )
|
||||
angle = startAngle - endAngle;
|
||||
else
|
||||
angle = endAngle - startAngle;
|
||||
EDA_ANGLE startAngle = -aStartAngle;
|
||||
|
||||
// Calculate arc start point:
|
||||
VECTOR2I cmap( aCenter.x + KiROUND( aRadius * aStartAngle.Cos() ),
|
||||
aCenter.y - KiROUND( aRadius * aStartAngle.Sin() ) );
|
||||
VECTOR2I cmap( aCenter.x + KiROUND( aRadius * startAngle.Cos() ),
|
||||
aCenter.y - KiROUND( aRadius * startAngle.Sin() ) );
|
||||
VECTOR2D cmap_dev = userToDeviceCoordinates( cmap );
|
||||
|
||||
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%.0f,%g",
|
||||
|
|
|
@ -284,59 +284,8 @@ void PDF_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T aFill, int w
|
|||
}
|
||||
|
||||
|
||||
void PDF_PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError )
|
||||
{
|
||||
wxASSERT( m_workFile );
|
||||
|
||||
/*
|
||||
* Arcs are not so easily approximated by beziers (in the general case), so we approximate
|
||||
* them in the old way
|
||||
*/
|
||||
EDA_ANGLE startAngle( aStart - aCenter );
|
||||
EDA_ANGLE endAngle( aEnd - aCenter );
|
||||
int radius = ( aStart - aCenter ).EuclideanNorm();
|
||||
int numSegs = GetArcToSegmentCount( radius, aMaxError, FULL_CIRCLE );
|
||||
EDA_ANGLE delta = ANGLE_360 / std::max( 8, numSegs );
|
||||
VECTOR2I start( aStart );
|
||||
VECTOR2I end( aEnd );
|
||||
VECTOR2I pt;
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
VECTOR2D pos_dev = userToDeviceCoordinates( start );
|
||||
fprintf( m_workFile, "%g %g m ", pos_dev.x, pos_dev.y );
|
||||
|
||||
for( EDA_ANGLE ii = delta; startAngle + ii < endAngle; ii += delta )
|
||||
{
|
||||
pt = start;
|
||||
RotatePoint( pt, aCenter, -ii );
|
||||
|
||||
pos_dev = userToDeviceCoordinates( pt );
|
||||
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
|
||||
}
|
||||
|
||||
pos_dev = userToDeviceCoordinates( end );
|
||||
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
|
||||
|
||||
// The arc is drawn... if not filled we stroke it, otherwise we finish
|
||||
// closing the pie at the center
|
||||
if( aFill == FILL_T::NO_FILL )
|
||||
{
|
||||
fputs( "S\n", m_workFile );
|
||||
}
|
||||
else
|
||||
{
|
||||
pos_dev = userToDeviceCoordinates( aCenter );
|
||||
fprintf( m_workFile, "%g %g l b\n", pos_dev.x, pos_dev.y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
wxASSERT( m_workFile );
|
||||
|
||||
|
@ -350,14 +299,14 @@ void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
* Arcs are not so easily approximated by beziers (in the general case), so we approximate
|
||||
* them in the old way
|
||||
*/
|
||||
EDA_ANGLE startAngle( aStartAngle );
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
EDA_ANGLE startAngle = -aStartAngle;
|
||||
EDA_ANGLE endAngle = startAngle - aAngle;
|
||||
VECTOR2I start;
|
||||
VECTOR2I end;
|
||||
const EDA_ANGLE delta( 5, DEGREES_T ); // increment to draw circles
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
if( startAngle > endAngle )
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
|
|
|
@ -521,31 +521,34 @@ VECTOR2D mapCoords( const VECTOR2D& aSource )
|
|||
}
|
||||
|
||||
|
||||
void PS_PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError )
|
||||
void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
|
||||
VECTOR2D center_device = userToDeviceCoordinates( aCenter );
|
||||
VECTOR2D start_device = userToDeviceCoordinates( aStart );
|
||||
VECTOR2D end_device = userToDeviceCoordinates( aEnd );
|
||||
double radius_device = ( start_device - center_device ).EuclideanNorm();
|
||||
VECTOR2D center_device = userToDeviceCoordinates( aCenter );
|
||||
double radius_device = userToDeviceSize( aRadius );
|
||||
|
||||
EDA_ANGLE endA = aStartAngle + aAngle;
|
||||
VECTOR2D start( aRadius * aStartAngle.Cos(), aRadius * aStartAngle.Sin() );
|
||||
VECTOR2D end( aRadius * endA.Cos(), aRadius * endA.Sin() );
|
||||
|
||||
start += aCenter;
|
||||
end += aCenter;
|
||||
|
||||
VECTOR2D start_device = userToDeviceCoordinates( start );
|
||||
VECTOR2D end_device = userToDeviceCoordinates( end );
|
||||
EDA_ANGLE startAngle( mapCoords( start_device - center_device ) );
|
||||
EDA_ANGLE endAngle( mapCoords( end_device - center_device ) );
|
||||
|
||||
// userToDeviceCoordinates gets our start/ends out of order
|
||||
if( !m_plotMirror )
|
||||
if( !m_plotMirror ^ ( aAngle < ANGLE_0 ) )
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
fprintf( m_outputFile, "%g %g %g %g %g arc%d\n",
|
||||
center_device.x,
|
||||
center_device.y,
|
||||
radius_device,
|
||||
startAngle.AsDegrees(),
|
||||
endAngle.AsDegrees(),
|
||||
getFillId( aFill ) );
|
||||
fprintf( m_outputFile, "%g %g %g %g %g arc%d\n", center_device.x, center_device.y,
|
||||
radius_device, startAngle.AsDegrees(), endAngle.AsDegrees(), getFillId( aFill ) );
|
||||
}
|
||||
|
||||
void PS_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
|
||||
|
|
|
@ -428,7 +428,7 @@ void SVG_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int wi
|
|||
|
||||
|
||||
void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
/* Draws an arc of a circle, centered on (xc,yc), with starting point (x1, y1) and ending
|
||||
* at (x2, y2). The current pen is used for the outline and the current brush for filling
|
||||
|
@ -443,11 +443,11 @@ void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
|||
return;
|
||||
}
|
||||
|
||||
EDA_ANGLE startAngle( aStartAngle );
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
EDA_ANGLE startAngle = -aStartAngle;
|
||||
EDA_ANGLE endAngle = startAngle - aAngle;
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
if( endAngle < startAngle )
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
// Calculate start point.
|
||||
VECTOR2D centre_device = userToDeviceCoordinates( aCenter );
|
||||
|
|
|
@ -146,58 +146,53 @@ double PLOTTER::GetDashGapLenIU( int aLineWidth ) const
|
|||
}
|
||||
|
||||
#include <wx/log.h>
|
||||
void PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError )
|
||||
void PLOTTER::Arc( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd, FILL_T aFill,
|
||||
int aWidth )
|
||||
{
|
||||
// Recalculate aCenter using double to be sure we will use a exact value, from aStart and aEnd
|
||||
// it must be on the line passing by the middle of segment {aStart, aEnd}
|
||||
// To simplify calculations, use aStart as origin in intermediate calculations
|
||||
VECTOR2D center = aCenter - aStart;
|
||||
VECTOR2D end = aEnd - aStart;
|
||||
EDA_ANGLE segAngle( end );
|
||||
VECTOR2D aCenter = CalcArcCenter( aStart, aMid, aEnd );
|
||||
|
||||
// Rotate end and center, to make segment {aStart, aEnd} horizontal
|
||||
RotatePoint( end, segAngle );
|
||||
RotatePoint( center, segAngle );
|
||||
EDA_ANGLE startAngle( aStart - aCenter );
|
||||
EDA_ANGLE endAngle( aEnd - aCenter );
|
||||
|
||||
// center.x must be at end.x/2 coordinate
|
||||
center.x = end.x / 2;
|
||||
// < 0: left, 0 : on the line, > 0 : right
|
||||
double det = ( aEnd - aStart ).Cross( aMid - aStart );
|
||||
|
||||
// Now calculate the right center position
|
||||
RotatePoint( center, -segAngle );
|
||||
center += aStart;
|
||||
int cw = det <= 0;
|
||||
EDA_ANGLE angle = endAngle - startAngle;
|
||||
|
||||
EDA_ANGLE startAngle( VECTOR2D( aStart ) - center );
|
||||
EDA_ANGLE endAngle( VECTOR2D( aEnd ) - center );
|
||||
double radius = ( VECTOR2D( aStart ) - center ).EuclideanNorm();
|
||||
if( cw )
|
||||
angle.Normalize();
|
||||
else
|
||||
angle.NormalizeNegative();
|
||||
|
||||
// In old Kicad code, calls to Arc() using angles calls this function after
|
||||
// swapping angles and negate them (to compensate the inverted Y axis).
|
||||
// So to be compatible with Arc() calls with angles, do the same thing
|
||||
std::swap( startAngle, endAngle );
|
||||
startAngle = -startAngle;
|
||||
endAngle = -endAngle;
|
||||
|
||||
Arc( aCenter, startAngle, endAngle, radius, aFill, aWidth );
|
||||
double radius = ( aStart - aCenter ).EuclideanNorm();
|
||||
Arc( aCenter, startAngle, angle, radius, aFill, aWidth );
|
||||
}
|
||||
|
||||
|
||||
void PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
void PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
|
||||
double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
EDA_ANGLE startAngle( aStartAngle );
|
||||
EDA_ANGLE endAngle( aEndAngle );
|
||||
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
|
||||
}
|
||||
|
||||
|
||||
void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
|
||||
{
|
||||
EDA_ANGLE startAngle = aStartAngle;
|
||||
EDA_ANGLE endAngle = startAngle + aAngle;
|
||||
const EDA_ANGLE delta( 5.0, DEGREES_T ); // increment to draw arc
|
||||
VECTOR2I start, end;
|
||||
const int sign = -1;
|
||||
const int sign = 1;
|
||||
|
||||
while( endAngle < startAngle )
|
||||
endAngle += ANGLE_360;
|
||||
if( aAngle < ANGLE_0 )
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
SetCurrentLineWidth( aWidth );
|
||||
|
||||
start.x = aCenter.x + KiROUND( aRadius * startAngle.Cos() );
|
||||
start.y = aCenter.y + sign*KiROUND( aRadius * startAngle.Sin() );
|
||||
start.y = aCenter.y + sign * KiROUND( aRadius * startAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
|
@ -212,12 +207,12 @@ void PLOTTER::Arc( 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.y = aCenter.y + sign * KiROUND( aRadius * ii.Sin() );
|
||||
LineTo( end );
|
||||
}
|
||||
|
||||
end.x = aCenter.x + KiROUND( aRadius * endAngle.Cos() );
|
||||
end.y = aCenter.y + sign*KiROUND( aRadius * endAngle.Sin() );
|
||||
end.y = aCenter.y + sign * KiROUND( aRadius * endAngle.Sin() );
|
||||
|
||||
if( aFill != FILL_T::NO_FILL )
|
||||
{
|
||||
|
@ -581,57 +576,47 @@ void PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int widt
|
|||
|
||||
|
||||
void PLOTTER::ThickArc( const VECTOR2D& centre, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, int aWidth,
|
||||
const EDA_ANGLE& aAngle, double aRadius, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
if( aTraceMode == FILLED )
|
||||
{
|
||||
Arc( centre, aStartAngle, aEndAngle, aRadius, FILL_T::NO_FILL, aWidth );
|
||||
Arc( centre, aStartAngle, aAngle, aRadius, FILL_T::NO_FILL, aWidth );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( -1 );
|
||||
Arc( centre, aStartAngle, aEndAngle, aRadius - ( aWidth - m_currentPenWidth ) / 2,
|
||||
Arc( centre, aStartAngle, aAngle, aRadius - ( aWidth - m_currentPenWidth ) / 2,
|
||||
FILL_T::NO_FILL, -1 );
|
||||
Arc( centre, aStartAngle, aEndAngle, aRadius + ( aWidth - m_currentPenWidth ) / 2,
|
||||
Arc( centre, aStartAngle, aAngle, aRadius + ( aWidth - m_currentPenWidth ) / 2,
|
||||
FILL_T::NO_FILL, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PLOTTER::ThickArc( const VECTOR2I& aCentre, const VECTOR2I& aStart,
|
||||
const VECTOR2I& aEnd, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
if( aTraceMode == FILLED )
|
||||
{
|
||||
Arc( aCentre, aStart, aEnd, FILL_T::NO_FILL, aWidth, GetPlotterArcHighDef() );
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCurrentLineWidth( -1 );
|
||||
int radius = ( aStart - aCentre ).EuclideanNorm();
|
||||
|
||||
int new_radius = radius - ( aWidth - m_currentPenWidth ) / 2;
|
||||
VECTOR2I start = ( aStart - aCentre ).Resize( new_radius ) + aCentre;
|
||||
VECTOR2I end = ( aEnd - aCentre ).Resize( new_radius ) + aCentre;
|
||||
|
||||
Arc( aCentre, start, end, FILL_T::NO_FILL, -1, GetPlotterArcHighDef() );
|
||||
|
||||
new_radius = radius + ( aWidth - m_currentPenWidth ) / 2;
|
||||
start = ( aStart - aCentre ).Resize( new_radius ) + aCentre;
|
||||
end = ( aEnd - aCentre ).Resize( new_radius ) + aCentre;
|
||||
|
||||
Arc( aCentre, start, end, FILL_T::NO_FILL, -1, GetPlotterArcHighDef() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PLOTTER::ThickArc( const EDA_SHAPE& aArcShape,
|
||||
OUTLINE_MODE aTraceMode, void* aData )
|
||||
{
|
||||
ThickArc( aArcShape.getCenter(),aArcShape.GetStart(), aArcShape.GetEnd(),
|
||||
aArcShape.GetWidth(), aTraceMode, aData );
|
||||
VECTOR2D center = aArcShape.getCenter();
|
||||
VECTOR2D mid = aArcShape.GetArcMid();
|
||||
VECTOR2D start = aArcShape.GetStart();
|
||||
VECTOR2D end = aArcShape.GetEnd();
|
||||
|
||||
EDA_ANGLE startAngle( start - center );
|
||||
EDA_ANGLE endAngle( end - center );
|
||||
EDA_ANGLE angle = endAngle - startAngle;
|
||||
|
||||
// < 0: left, 0 : on the line, > 0 : right
|
||||
double det = ( end - start ).Cross( mid - start );
|
||||
|
||||
if( det <= 0 ) // cw
|
||||
angle.Normalize();
|
||||
else
|
||||
angle.NormalizeNegative();
|
||||
|
||||
double radius = ( start - center ).EuclideanNorm();
|
||||
|
||||
ThickArc( center, startAngle, angle, radius, aArcShape.GetWidth(), aTraceMode, aData );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ struct VIEW_OVERLAY::COMMAND_ARC : public VIEW_OVERLAY::COMMAND
|
|||
|
||||
virtual void Execute( VIEW* aView ) const override
|
||||
{
|
||||
aView->GetGAL()->DrawArc( m_center, m_radius, m_startAngle, m_endAngle );
|
||||
aView->GetGAL()->DrawArc( m_center, m_radius, m_startAngle, m_endAngle - m_startAngle );
|
||||
}
|
||||
|
||||
VECTOR2D m_center;
|
||||
|
|
|
@ -223,12 +223,8 @@ void LIB_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOffs
|
|||
case SHAPE_T::ARC:
|
||||
{
|
||||
VECTOR2I mid = aTransform.TransformCoordinate( GetArcMid() ) + aOffset;
|
||||
VECTOR2I center = CalcArcCenter( start, mid, end );
|
||||
|
||||
EDA_ANGLE startAngle = EDA_ANGLE( start - center );
|
||||
EDA_ANGLE endAngle = EDA_ANGLE( end - center );
|
||||
|
||||
aPlotter->Arc( center, -startAngle, -endAngle, GetRadius(), fill, penWidth );
|
||||
aPlotter->Arc( start, mid, end, fill, penWidth );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -900,7 +900,7 @@ void SCH_PAINTER::draw( const LIB_SHAPE* aShape, int aLayer, bool aDimmed )
|
|||
|
||||
std::swap( startAngle, endAngle );
|
||||
|
||||
m_gal->DrawArc( center, shape->GetRadius(), startAngle, endAngle );
|
||||
m_gal->DrawArc( center, shape->GetRadius(), startAngle, endAngle - startAngle );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1988,7 +1988,7 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer )
|
|||
aShape->CalcArcAngles( startAngle, endAngle );
|
||||
|
||||
m_gal->DrawArc( aShape->GetCenter(), aShape->GetRadius(), startAngle,
|
||||
endAngle );
|
||||
endAngle - startAngle );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,13 +140,7 @@ void SCH_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
|||
switch( GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
{
|
||||
// In some plotters (not all) the arc is approximated by segments, and
|
||||
// a error max is needed. We try to approximate by 360/5 segments by 360 deg
|
||||
int arc2segment_error = CircleToEndSegmentDeltaRadius( GetRadius(), 360/5 );
|
||||
aPlotter->Arc( getCenter(), GetStart(), GetEnd(), m_fill, 0, arc2segment_error );
|
||||
}
|
||||
|
||||
aPlotter->Arc( GetStart(), GetArcMid(), GetEnd(), m_fill, 0 );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
|
@ -183,13 +177,7 @@ void SCH_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground ) const
|
|||
switch( GetShape() )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
{
|
||||
// In some plotters (not all) the arc is approximated by segments, and
|
||||
// a error max is needed. We try to approximate by 360/5 segments by 360 deg
|
||||
int arc2segment_error = CircleToEndSegmentDeltaRadius( GetRadius(), 360/5 );
|
||||
aPlotter->Arc( getCenter(), GetStart(), GetEnd(), FILL_T::NO_FILL, pen_size, arc2segment_error );
|
||||
}
|
||||
|
||||
aPlotter->Arc( GetStart(), GetArcMid(), GetEnd(), m_fill, pen_size );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
|
|
|
@ -337,7 +337,8 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
|||
|
||||
// Adjust the allowed approx error to convert arcs to segments:
|
||||
int arc_to_seg_error = gerbIUScale.mmToIU( 0.005 ); // Allow 5 microns
|
||||
m_gal->DrawArcSegment( center, radius, startAngle, endAngle, width, arc_to_seg_error );
|
||||
m_gal->DrawArcSegment( center, radius, startAngle, endAngle - startAngle, width,
|
||||
arc_to_seg_error );
|
||||
|
||||
#if 0 // Arc Debugging only
|
||||
m_gal->SetIsFill( false );
|
||||
|
|
|
@ -78,14 +78,13 @@ public:
|
|||
void DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) override;
|
||||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle ) override;
|
||||
void DrawArc( const VECTOR2D& aCenterPoint, double aRadius, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle ) override;
|
||||
|
||||
/// @copydoc GAL::DrawArcSegment()
|
||||
/// Note: aMaxError is not used in Cairo, because Cairo can draw true arcs
|
||||
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle, double aWidth,
|
||||
double aMaxError ) override;
|
||||
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aWidth, double aMaxError ) override;
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||
|
|
|
@ -148,10 +148,10 @@ public:
|
|||
* @param aCenterPoint is the center point of the arc.
|
||||
* @param aRadius is the arc radius.
|
||||
* @param aStartAngle is the start angle of the arc.
|
||||
* @param aEndAngle is the end angle of the arc.
|
||||
* @param aAngle is the angle of the arc.
|
||||
*/
|
||||
virtual void DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle ) {};
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle ){};
|
||||
|
||||
/**
|
||||
* Draw an arc segment.
|
||||
|
@ -166,14 +166,14 @@ public:
|
|||
* @param aCenterPoint is the center point of the arc.
|
||||
* @param aRadius is the arc radius.
|
||||
* @param aStartAngle is the start angle of the arc.
|
||||
* @param aEndAngle is the end angle of the arc.
|
||||
* @param aAngle is the angle of the arc.
|
||||
* @param aWidth is the thickness of the arc (pen size).
|
||||
* @param aMaxError is the max allowed error to create segments to approximate a circle.
|
||||
* It has meaning only for back ends that can't draw a true arc, and use segments to approximate.
|
||||
*/
|
||||
virtual void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle,
|
||||
double aWidth, double aMaxError ) {};
|
||||
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
|
||||
double aWidth, double aMaxError ){};
|
||||
|
||||
/**
|
||||
* Draw a rectangle.
|
||||
|
|
|
@ -131,11 +131,11 @@ public:
|
|||
|
||||
/// @copydoc GAL::DrawArc()
|
||||
void DrawArc( const VECTOR2D& aCenterPoint, double aRadius, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle ) override;
|
||||
const EDA_ANGLE& aAngle ) override;
|
||||
|
||||
/// @copydoc GAL::DrawArcSegment()
|
||||
void DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aWidth, double aMaxError ) override;
|
||||
const EDA_ANGLE& aAngle, double aWidth, double aMaxError ) override;
|
||||
|
||||
/// @copydoc GAL::DrawRectangle()
|
||||
void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) override;
|
||||
|
|
|
@ -212,25 +212,11 @@ public:
|
|||
virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
|
||||
int width = USE_DEFAULT_LINE_WIDTH ) = 0;
|
||||
|
||||
/**
|
||||
* Generic fallback: arc rendered as a polyline.
|
||||
* Winding direction: clockwise in right-down coordinate system.
|
||||
*/
|
||||
virtual void Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError );
|
||||
virtual void Arc( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd,
|
||||
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
|
||||
|
||||
/**
|
||||
* Generic fallback: arc rendered as a polyline.
|
||||
* Note also aCentre and aRadius are double to avoid creating rounding issues due
|
||||
* to the fact a arc is defined in Kicad by a start point, a end point and third point
|
||||
* not angles and radius.
|
||||
* In some plotters (i.e. dxf) whe need a good precision when calculating an arc
|
||||
* without error introduced by rounding, to avoid moving the end points,
|
||||
* usually important in outlines when plotting an arc given by center, radius and angles.
|
||||
* Winding direction: counter-clockwise in right-down coordinate system.
|
||||
*/
|
||||
virtual void Arc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH );
|
||||
|
||||
/**
|
||||
|
@ -313,11 +299,11 @@ public:
|
|||
virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
|
||||
OUTLINE_MODE tracemode, void* aData );
|
||||
|
||||
virtual void ThickArc( const VECTOR2I& aCentre, const VECTOR2I& aStart,
|
||||
const VECTOR2I& aEnd, int aWidth,
|
||||
virtual void ThickArc( const EDA_SHAPE& aArcShape,
|
||||
OUTLINE_MODE aTraceMode, void* aData );
|
||||
|
||||
virtual void ThickArc( const EDA_SHAPE& aArcShape,
|
||||
virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData );
|
||||
|
||||
virtual void ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width, OUTLINE_MODE tracemode,
|
||||
|
@ -559,9 +545,19 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& StAngle,
|
||||
const EDA_ANGLE& EndAngle, double aRadius, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData );
|
||||
/**
|
||||
* Generic fallback: arc rendered as a polyline.
|
||||
* Note also aCentre and aRadius are double to avoid creating rounding issues due
|
||||
* to the fact a arc is defined in Kicad by a start point, a end point and third point
|
||||
* not angles and radius.
|
||||
* In some plotters (i.e. dxf) whe need a good precision when calculating an arc
|
||||
* without error introduced by rounding, to avoid moving the end points,
|
||||
* usually important in outlines when plotting an arc given by center, radius and angles.
|
||||
* Winding direction: counter-clockwise in right-down coordinate system.
|
||||
*/
|
||||
virtual void polyArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH );
|
||||
|
||||
// These are marker subcomponents
|
||||
/**
|
||||
|
|
|
@ -95,6 +95,9 @@ public:
|
|||
virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
|
||||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth ) override;
|
||||
|
||||
/**
|
||||
* DXF polygon: doesn't fill it but at least it close the filled ones
|
||||
* DXF does not know thick outline.
|
||||
|
@ -208,10 +211,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
void plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText,
|
||||
const TEXT_ATTRIBUTES& aAttrs );
|
||||
|
||||
|
|
|
@ -64,18 +64,14 @@ public:
|
|||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
|
||||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
// These functions plot an item and manage X2 gerber attributes
|
||||
virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
|
||||
OUTLINE_MODE tracemode, void* aData ) override;
|
||||
|
||||
virtual void ThickArc( const VECTOR2I& aCentre, const VECTOR2I& aStart,
|
||||
const VECTOR2I& aEnd, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData ) override;
|
||||
|
||||
virtual void ThickArc( const EDA_SHAPE& aArcShape,
|
||||
OUTLINE_MODE aTraceMode, void* aData ) override;
|
||||
|
||||
virtual void ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width,
|
||||
OUTLINE_MODE tracemode, void* aData ) override;
|
||||
|
||||
|
@ -268,12 +264,8 @@ public:
|
|||
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
|
||||
|
||||
protected:
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, int aWidth,
|
||||
const EDA_ANGLE& aAngle, double aRadius, int aWidth,
|
||||
OUTLINE_MODE aTraceMode, void* aData ) override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,11 +139,11 @@ protected:
|
|||
*
|
||||
* center is the center of the arc.
|
||||
* StAngled is the start angle of the arc.
|
||||
* aEndAngle is end angle the arc.
|
||||
* aAngle is angle the arc.
|
||||
* Radius is the radius of the arc.
|
||||
*/
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -192,8 +192,9 @@ public:
|
|||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
|
||||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
virtual void Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError ) override;
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
virtual void PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override;
|
||||
|
@ -326,11 +327,8 @@ public:
|
|||
/**
|
||||
* The PDF engine can't directly plot arcs so we use polygonization.
|
||||
*/
|
||||
virtual void Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
FILL_T aFill, int aWidth, int aMaxError ) override;
|
||||
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
/**
|
||||
|
@ -552,9 +550,8 @@ public:
|
|||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
|
||||
int width = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
|
||||
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill,
|
||||
const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
|
||||
int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
|
||||
|
||||
virtual void BezierCurve( const VECTOR2I& aStart, const VECTOR2I& aControl1,
|
||||
|
|
|
@ -844,8 +844,7 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
|
|||
if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
|
||||
width = width + m_lockedShadowMargin;
|
||||
|
||||
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width,
|
||||
m_maxError );
|
||||
m_gal->DrawArcSegment( center, radius, start_angle, angle, width, m_maxError );
|
||||
}
|
||||
|
||||
// Clearance lines
|
||||
|
@ -859,8 +858,8 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
|
|||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetStrokeColor( color );
|
||||
|
||||
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
|
||||
width + clearance * 2, m_maxError );
|
||||
m_gal->DrawArcSegment( center, radius, start_angle, angle, width + clearance * 2,
|
||||
m_maxError );
|
||||
}
|
||||
|
||||
// Debug only: enable this code only to test the TransformArcToPolygon function
|
||||
|
@ -1074,11 +1073,11 @@ void PCB_PAINTER::draw( const PCB_VIA* aVia, int aLayer )
|
|||
|
||||
m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerTop ) );
|
||||
m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerTop ) );
|
||||
m_gal->DrawArc( center, radius, EDA_ANGLE( 240, DEGREES_T ), EDA_ANGLE( 300, DEGREES_T ) );
|
||||
m_gal->DrawArc( center, radius, EDA_ANGLE( 240, DEGREES_T ), EDA_ANGLE( 60, DEGREES_T ) );
|
||||
|
||||
m_gal->SetStrokeColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
|
||||
m_gal->SetFillColor( m_pcbSettings.GetColor( aVia, layerBottom ) );
|
||||
m_gal->DrawArc( center, radius, EDA_ANGLE( 60, DEGREES_T ), EDA_ANGLE( 120, DEGREES_T ) );
|
||||
m_gal->DrawArc( center, radius, EDA_ANGLE( 60, DEGREES_T ), EDA_ANGLE( 60, DEGREES_T ) );
|
||||
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->SetFillColor( color );
|
||||
|
@ -1806,7 +1805,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
|
|||
if( outline_mode )
|
||||
{
|
||||
m_gal->DrawArcSegment( aShape->GetCenter(), aShape->GetRadius(), startAngle,
|
||||
endAngle, thickness, m_maxError );
|
||||
endAngle - startAngle, thickness, m_maxError );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1814,7 +1813,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
|
|||
m_gal->SetIsStroke( false );
|
||||
|
||||
m_gal->DrawArcSegment( aShape->GetCenter(), aShape->GetRadius(), startAngle,
|
||||
endAngle, thickness, m_maxError );
|
||||
endAngle - startAngle, thickness, m_maxError );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -643,20 +643,10 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
|||
|
||||
if( track->Type() == PCB_ARC_T )
|
||||
{
|
||||
const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
|
||||
const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
|
||||
|
||||
// ThickArc expects only positive angle arcs, so flip start/end if
|
||||
// we are negative
|
||||
if( arc->GetAngle() < ANGLE_0 )
|
||||
{
|
||||
aPlotter->ThickArc( arc->GetCenter(), arc->GetEnd(), arc->GetStart(),
|
||||
width, plotMode, &gbr_metadata );
|
||||
}
|
||||
else
|
||||
{
|
||||
aPlotter->ThickArc( arc->GetCenter(), arc->GetStart(), arc->GetEnd(),
|
||||
width, plotMode, &gbr_metadata );
|
||||
}
|
||||
aPlotter->ThickArc( arc->GetCenter(), arc->GetArcAngleStart(), arc->GetAngle(),
|
||||
arc->GetRadius(), width, plotMode, &gbr_metadata );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -239,7 +239,7 @@ void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN_BASE* aL, KIGFX:
|
|||
EDA_ANGLE start_angle = arc.GetStartAngle();
|
||||
EDA_ANGLE angle = arc.GetCentralAngle();
|
||||
|
||||
gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, start_angle + angle);
|
||||
gal->DrawArc( arc.GetCenter(), arc.GetRadius(), start_angle, angle);
|
||||
}
|
||||
|
||||
if( aL->IsClosed() )
|
||||
|
@ -414,14 +414,14 @@ void ROUTER_PREVIEW_ITEM::drawShape( const SHAPE* aShape, KIGFX::GAL* gal ) cons
|
|||
if( m_showClearance && m_clearance > 0 )
|
||||
{
|
||||
gal->SetLineWidth( w + 2 * m_clearance );
|
||||
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
|
||||
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, angle );
|
||||
}
|
||||
|
||||
gal->SetLayerDepth( m_depth );
|
||||
gal->SetStrokeColor( m_color );
|
||||
gal->SetFillColor( m_color );
|
||||
gal->SetLineWidth( w );
|
||||
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, start_angle + angle );
|
||||
gal->DrawArc( arc->GetCenter(), arc->GetRadius(), start_angle, angle );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue