void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, int aRadius, FILL_T aFill, int aWidth ) { SetCurrentLineWidth( aWidth ); wxPoint start, end; start.x = aCenter.x + KiROUND( cosdecideg( aRadius, aStAngle ) ); start.y = aCenter.y - KiROUND( sindecideg( aRadius, aStAngle ) ); MoveTo( start ); end.x = aCenter.x + KiROUND( cosdecideg( aRadius, aEndAngle ) ); end.y = aCenter.y - KiROUND( sindecideg( aRadius, aEndAngle ) ); DPOINT devEnd = userToDeviceCoordinates( end ); DPOINT devCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start ); fprintf( outputFile, "G75*\n" ); // Multiquadrant mode if( aStAngle < aEndAngle ) fprintf( outputFile, "G03" ); else fprintf( outputFile, "G02" ); fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", KiROUND( devEnd.x ), KiROUND( devEnd.y ), KiROUND( devCenter.x ), KiROUND( devCenter.y ) ); fprintf( outputFile, "G01*\n" ); // Back to linear interp. }
void PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxPoint start, end; const int delta = 50; // increment (in 0.1 degrees) to draw circles if( StAngle > EndAngle ) std::swap( StAngle, EndAngle ); SetCurrentLineWidth( width ); /* Please NOTE the different sign due to Y-axis flip */ start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) ); start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) ); MoveTo( start ); for( int ii = StAngle + delta; ii < EndAngle; ii += delta ) { end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) ); end.y = centre.y + KiROUND( sindecideg( radius, -ii ) ); LineTo( end ); } end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) ); end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) ); FinishTo( end ); }
/* Plot an arc: * Center = center coord * Stangl, endAngle = angle of beginning and end * Radius = radius of the arc * Command * PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, NbSegm; PU; * Or PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, PU; */ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( outputFile ); double angle; if( radius <= 0 ) return; DPOINT centre_dev = userToDeviceCoordinates( centre ); if( m_plotMirror ) angle = StAngle - EndAngle; else angle = EndAngle - StAngle; NORMALIZE_ANGLE_180( angle ); angle /= 10; // Calculate arc start point: wxPoint cmap; cmap.x = centre.x + KiROUND( cosdecideg( radius, StAngle ) ); cmap.y = centre.y - KiROUND( sindecideg( radius, StAngle ) ); DPOINT cmap_dev = userToDeviceCoordinates( cmap ); fprintf( outputFile, "PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,", cmap_dev.x, cmap_dev.y, centre_dev.x, centre_dev.y ); fprintf( outputFile, "%.0f", angle ); fprintf( outputFile, ";PU;\n" ); PenFinish(); }
/** * The PDF engine can't directly plot arcs, it uses the base emulation. * So no filled arcs (not a great loss... ) */ void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, int radius, FILL_T fill, int width ) { wxASSERT( workFile ); if( radius <= 0 ) return; /* Arcs are not so easily approximated by beziers (in the general case), so we approximate them in the old way */ wxPoint start, end; const int delta = 50; // increment (in 0.1 degrees) to draw circles if( StAngle > EndAngle ) EXCHG( StAngle, EndAngle ); SetCurrentLineWidth( width ); // Usual trig arc plotting routine... start.x = centre.x + KiROUND( cosdecideg( radius, -StAngle ) ); start.y = centre.y + KiROUND( sindecideg( radius, -StAngle ) ); DPOINT pos_dev = userToDeviceCoordinates( start ); fprintf( workFile, "%g %g m ", pos_dev.x, pos_dev.y ); for( int ii = StAngle + delta; ii < EndAngle; ii += delta ) { end.x = centre.x + KiROUND( cosdecideg( radius, -ii ) ); end.y = centre.y + KiROUND( sindecideg( radius, -ii ) ); pos_dev = userToDeviceCoordinates( end ); fprintf( workFile, "%g %g l ", pos_dev.x, pos_dev.y ); } end.x = centre.x + KiROUND( cosdecideg( radius, -EndAngle ) ); end.y = centre.y + KiROUND( sindecideg( radius, -EndAngle ) ); pos_dev = userToDeviceCoordinates( end ); fprintf( 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( fill == NO_FILL ) { fputs( "S\n", workFile ); } else { pos_dev = userToDeviceCoordinates( centre ); fprintf( workFile, "%g %g l b\n", pos_dev.x, pos_dev.y ); } }
/* Fills all cells of the routing matrix contained in the circle * half-width = lg, center = ux0, uy0, ux1,uy1 is a point on the circle. * coord are in PCB units. */ void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer, int color, int op_logic ) { int radius, nb_segm; int x0, y0, // Starting point of the current segment trace. x1, y1; // End point. int ii; int angle; radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) ); x0 = x1 = radius; y0 = y1 = 0; if( lg < 1 ) lg = 1; nb_segm = ( 2 * radius ) / lg; if( nb_segm < 5 ) nb_segm = 5; if( nb_segm > 100 ) nb_segm = 100; for( ii = 1; ii < nb_segm; ii++ ) { angle = (3600 * ii) / nb_segm; x1 = KiROUND( cosdecideg( radius, angle ) ); y1 = KiROUND( sindecideg( radius, angle ) ); DrawSegmentQcq( x0 + ux0, y0 + uy0, x1 + ux0, y1 + uy0, lg, layer, color, op_logic ); x0 = x1; y0 = y1; } DrawSegmentQcq( x1 + ux0, y1 + uy0, ux0 + radius, uy0, lg, layer, color, op_logic ); }