KiCad PCB EDA Suite
convert_basic_shapes_to_polygon.h File Reference
#include <vector>
#include <fctsys.h>
#include <trigo.h>
#include <macros.h>
#include <geometry/shape_poly_set.h>

Go to the source code of this file.

Enumerations

enum  RECT_CHAMFER_POSITIONS : int {
  RECT_NO_CHAMFER = 0, RECT_CHAMFER_TOP_LEFT = 1, RECT_CHAMFER_TOP_RIGHT = 2, RECT_CHAMFER_BOTTOM_LEFT = 4,
  RECT_CHAMFER_BOTTOM_RIGHT = 8, RECT_CHAMFER_ALL
}
 

Functions

void TransformCircleToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
 Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines. More...
 
void TransformOvalClearanceToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aWidth, int aCircleToSegmentsCount, double aCorrectionFactor)
 convert a oblong shape to a polygon, using multiple segments It is similar to TransformRoundedEndsSegmentToPolygon, but the polygon is outside the actual oblong shape (a segment with rounded ends) It is suitable to create oblong clearance areas. More...
 
void GetRoundRectCornerCenters (wxPoint aCenters[4], int aRadius, const wxPoint &aPosition, const wxSize &aSize, double aRotation)
 Helper function GetRoundRectCornerCenters Has meaning only for rounded rect Returns the centers of the rounded corners. More...
 
void TransformRoundChamferedRectToPolygon (SHAPE_POLY_SET &aCornerBuffer, const wxPoint &aPosition, const wxSize &aSize, double aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aCircleToSegmentsCount)
 convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corners arcs to multiple straight lines More...
 
void TransformRoundedEndsSegmentToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aCircleToSegmentsCount, int aWidth)
 Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Convert arcs to multiple straight lines. More...
 
void TransformArcToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, wxPoint aStart, double aArcAngle, int aCircleToSegmentsCount, int aWidth)
 Function TransformArcToPolygon Creates a polygon from an Arc Convert arcs to multiple straight segments. More...
 
void TransformRingToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aCentre, int aRadius, int aCircleToSegmentsCount, int aWidth)
 Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segments. More...
 

Enumeration Type Documentation

◆ RECT_CHAMFER_POSITIONS

Function Documentation

◆ GetRoundRectCornerCenters()

void GetRoundRectCornerCenters ( wxPoint  aCenters[4],
int  aRadius,
const wxPoint &  aPosition,
const wxSize &  aSize,
double  aRotation 
)

Helper function GetRoundRectCornerCenters Has meaning only for rounded rect Returns the centers of the rounded corners.

Parameters
aCentersis the buffer to store the 4 coordinates.
aRadius= the radius of the of the rounded corners.
aPosition= position of the round rect
aSize= size of the of the round rect.
aRotation= rotation of the of the round rect

Definition at line 202 of file convert_basic_shapes_to_polygon.cpp.

204 {
205  wxSize size( aSize/2 );
206 
207  size.x -= aRadius;
208  size.y -= aRadius;
209 
210  // Ensure size is > 0, to avoid generating unusable shapes
211  // which can crash kicad.
212  if( size.x <= 1 )
213  size.x = 1;
214  if( size.y <= 1 )
215  size.y = 1;
216 
217  aCenters[0].x = -size.x;
218  aCenters[0].y = size.y;
219 
220  aCenters[1].x = size.x;
221  aCenters[1].y = size.y;
222 
223  aCenters[2].x = size.x;
224  aCenters[2].y = -size.y;
225 
226  aCenters[3].x = -size.x;
227  aCenters[3].y = -size.y;
228 
229  // Rotate the polygon
230  if( aRotation )
231  {
232  for( int ii = 0; ii < 4; ii++ )
233  RotatePoint( &aCenters[ii], aRotation );
234  }
235 
236  // move the polygon to the position
237  for( int ii = 0; ii < 4; ii++ )
238  aCenters[ii] += aPosition;
239 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216

References RotatePoint().

Referenced by DRC::checkClearancePadToPad(), CINFO3D_VISU::createNewPadWithClearance(), and TransformRoundChamferedRectToPolygon().

◆ TransformArcToPolygon()

void TransformArcToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aCentre,
wxPoint  aStart,
double  aArcAngle,
int  aCircleToSegmentsCount,
int  aWidth 
)

Function TransformArcToPolygon Creates a polygon from an Arc Convert arcs to multiple straight segments.

Parameters
aCornerBuffer= a buffer to store the polygon
aCentre= centre of the arc or circle
aStart= start point of the arc, or a point on the circle
aArcAngle= arc angle in 0.1 degrees. For a circle, aArcAngle = 3600
aCircleToSegmentsCount= the number of segments to approximate a circle
aWidth= width (thickness) of the line

Definition at line 422 of file convert_basic_shapes_to_polygon.cpp.

425 {
426  wxPoint arc_start, arc_end;
427  int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
428 
429  arc_end = arc_start = aStart;
430 
431  if( aArcAngle != 3600 )
432  {
433  RotatePoint( &arc_end, aCentre, -aArcAngle );
434  }
435 
436  if( aArcAngle < 0 )
437  {
438  std::swap( arc_start, arc_end );
439  aArcAngle = -aArcAngle;
440  }
441 
442  // Compute the ends of segments and creates poly
443  wxPoint curr_end = arc_start;
444  wxPoint curr_start = arc_start;
445 
446  for( int ii = delta; ii < aArcAngle; ii += delta )
447  {
448  curr_end = arc_start;
449  RotatePoint( &curr_end, aCentre, -ii );
450  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
451  aCircleToSegmentsCount, aWidth );
452  curr_start = curr_end;
453  }
454 
455  if( curr_end != arc_end )
457  curr_end, arc_end,
458  aCircleToSegmentsCount, aWidth );
459 }
void TransformRoundedEndsSegmentToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aCircleToSegmentsCount, int aWidth)
Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Conver...
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
static const int delta[8][2]
Definition: solve.cpp:112

References delta, RotatePoint(), and TransformRoundedEndsSegmentToPolygon().

Referenced by D_PAD::buildCustomPadPolygon(), and DRAWSEGMENT::TransformShapeWithClearanceToPolygon().

◆ TransformCircleToPolygon()

void TransformCircleToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aCenter,
int  aRadius,
int  aCircleToSegmentsCount 
)

Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines.

Parameters
aCornerBuffer= a buffer to store the polygon
aCenter= the center of the circle
aRadius= the radius of the circle
aCircleToSegmentsCount= the number of segments to approximate a circle Note: the polygon is inside the circle, so if you want to have the polygon outside the circle, you should give aRadius calculated with a correction factor
aCornerBuffer= a SHAPE_POLY_SET to store the polygon
aCenter= the center of the circle
aRadius= the radius of the circle
aCircleToSegmentsCount= the number of segments to approximate a circle Note: the polygon is inside the circle, so if you want to have the polygon outside the circle, you should give aRadius calculated with a correction factor

Definition at line 77 of file convert_basic_shapes_to_polygon.cpp.

80 {
81  wxPoint corner_position;
82  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
83  double halfstep = delta/2; // the starting value for rot angles
84 
85  aCornerBuffer.NewOutline();
86 
87  for( int ii = 0; ii < aCircleToSegmentsCount; ii++ )
88  {
89  corner_position.x = aRadius;
90  corner_position.y = 0;
91  double angle = (ii * delta) + halfstep;
92  RotatePoint( &corner_position, angle );
93  corner_position += aCenter;
94  aCornerBuffer.Append( corner_position.x, corner_position.y );
95  }
96 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
static const int delta[8][2]
Definition: solve.cpp:112
int NewOutline()
Creates a new empty polygon in the set and returns its index
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References PNS::angle(), SHAPE_POLY_SET::Append(), delta, SHAPE_POLY_SET::NewOutline(), and RotatePoint().

◆ TransformOvalClearanceToPolygon()

void TransformOvalClearanceToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aStart,
wxPoint  aEnd,
int  aWidth,
int  aCircleToSegmentsCount,
double  aCorrectionFactor 
)

convert a oblong shape to a polygon, using multiple segments It is similar to TransformRoundedEndsSegmentToPolygon, but the polygon is outside the actual oblong shape (a segment with rounded ends) It is suitable to create oblong clearance areas.

because multiple segments create a smaller area than the circle, the radius of the circle to approximate must be bigger ( radius*aCorrectionFactor) to create segments outside the circle.

Parameters
aCornerBuffer= a buffer to store the polygon
aStart= the first point of the segment
aEnd= the second point of the segment
aWidth= the width of the segment
aCircleToSegmentsCount= the number of segments to approximate a circle
aCorrectionFactor= the coefficient to have segments outside the circle if aCorrectionFactor = 1.0, the shape will be the same as TransformRoundedEndsSegmentToPolygon

Definition at line 98 of file convert_basic_shapes_to_polygon.cpp.

101 {
102  // To build the polygonal shape outside the actual shape, we use a bigger
103  // radius to build rounded ends.
104  // However, the width of the segment is too big.
105  // so, later, we will clamp the polygonal shape with the bounding box
106  // of the segment.
107  int radius = aWidth / 2;
108 
109  // Note if we want to compensate the radius reduction of a circle due to
110  // the segment approx, aCorrectionFactor must be calculated like this:
111  // For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
112  // aCorrectionFactor is 1 /cos( PI/s_CircleToSegmentsCount )
113 
114  radius = radius * aCorrectionFactor; // make segments outside the circles
115 
116  // end point is the coordinate relative to aStart
117  wxPoint endp = aEnd - aStart;
118  wxPoint startp = aStart;
119  wxPoint corner;
120  SHAPE_POLY_SET polyshape;
121 
122  polyshape.NewOutline();
123 
124  // normalize the position in order to have endp.x >= 0
125  // it makes calculations more easy to understand
126  if( endp.x < 0 )
127  {
128  endp = aStart - aEnd;
129  startp = aEnd;
130  }
131 
132  // delta_angle is in radian
133  double delta_angle = atan2( (double)endp.y, (double)endp.x );
134  int seg_len = KiROUND( EuclideanNorm( endp ) );
135 
136  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
137 
138  // Compute the outlines of the segment, and creates a polygon
139  // Note: the polygonal shape is built from the equivalent horizontal
140  // segment starting ar 0,0, and ending at seg_len,0
141 
142  // add right rounded end:
143  for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
144  {
145  corner = wxPoint( 0, radius );
146  RotatePoint( &corner, delta*ii );
147  corner.x += seg_len;
148  polyshape.Append( corner.x, corner.y );
149  }
150 
151  // Finish arc:
152  corner = wxPoint( seg_len, -radius );
153  polyshape.Append( corner.x, corner.y );
154 
155  // add left rounded end:
156  for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
157  {
158  corner = wxPoint( 0, -radius );
159  RotatePoint( &corner, delta*ii );
160  polyshape.Append( corner.x, corner.y );
161  }
162 
163  // Finish arc:
164  corner = wxPoint( 0, radius );
165  polyshape.Append( corner.x, corner.y );
166 
167  // Now, clamp the polygonal shape (too big) with the segment bounding box
168  // the polygonal shape bbox equivalent to the segment has a too big height,
169  // and the right width
170  if( aCorrectionFactor > 1.0 )
171  {
172  SHAPE_POLY_SET bbox;
173  bbox.NewOutline();
174  // Build the bbox (a horizontal rectangle).
175  int halfwidth = aWidth / 2; // Use the exact segment width for the bbox height
176  corner.x = -radius - 2; // use a bbox width slightly bigger to avoid
177  // creating useless corner at segment ends
178  corner.y = halfwidth;
179  bbox.Append( corner.x, corner.y );
180  corner.y = -halfwidth;
181  bbox.Append( corner.x, corner.y );
182  corner.x = radius + seg_len + 2;
183  bbox.Append( corner.x, corner.y );
184  corner.y = halfwidth;
185  bbox.Append( corner.x, corner.y );
186 
187  // Now, clamp the shape
189  // Note the final polygon is a simple, convex polygon with no hole
190  // due to the shape of initial polygons
191  }
192 
193  // Rotate and move the polygon to its right location
194  polyshape.Rotate( delta_angle, VECTOR2I( 0, 0 ) );
195  polyshape.Move( startp );
196 
197  aCornerBuffer.Append( polyshape);
198 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:121
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
static const int delta[8][2]
Definition: solve.cpp:112
void Move(const VECTOR2I &aVector) override
Class SHAPE_POLY_SET.
void BooleanIntersection(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset intersection For aFastMode meaning, see function booleanOp
int NewOutline()
Creates a new empty polygon in the set and returns its index
void Rotate(double aAngle, const VECTOR2I &aCenter)
Function Rotate rotates all vertices by a given angle.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::BooleanIntersection(), delta, EuclideanNorm(), KiROUND(), SHAPE_POLY_SET::Move(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_POLY_SET::Rotate(), and RotatePoint().

Referenced by DXF_PLOTTER::ThickSegment(), TRACK::TransformShapeWithClearanceToPolygon(), DRAWSEGMENT::TransformShapeWithClearanceToPolygon(), and D_PAD::TransformShapeWithClearanceToPolygon().

◆ TransformRingToPolygon()

void TransformRingToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aCentre,
int  aRadius,
int  aCircleToSegmentsCount,
int  aWidth 
)

Function TransformRingToPolygon Creates a polygon from a ring Convert arcs to multiple straight segments.

Parameters
aCornerBuffer= a buffer to store the polygon
aCentre= centre of the arc or circle
aRadius= radius of the circle
aCircleToSegmentsCount= the number of segments to approximate a circle
aWidth= width (thickness) of the ring

Definition at line 472 of file convert_basic_shapes_to_polygon.cpp.

475 {
476  // Compute the corners positions and creates the poly
477  wxPoint curr_point;
478  int inner_radius = aRadius - ( aWidth / 2 );
479  int outer_radius = inner_radius + aWidth;
480 
481  if( inner_radius <= 0 )
482  { //In this case, the ring is just a circle (no hole inside)
483  TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ),
484  aCircleToSegmentsCount );
485  return;
486  }
487 
488  SHAPE_POLY_SET buffer;
489 
490  TransformCircleToPolygon( buffer, aCentre, outer_radius, aCircleToSegmentsCount );
491 
492  // Build the hole:
493  buffer.NewHole();
494  TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aCircleToSegmentsCount );
495 
497  aCornerBuffer.Append( buffer );
498 }
int NewHole(int aOutline=-1)
Creates a new hole in a given outline
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Returns the reference to aHole-th hole in the aIndex-th outline
Class SHAPE_POLY_SET.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines.
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::Fracture(), SHAPE_POLY_SET::Hole(), SHAPE_POLY_SET::NewHole(), SHAPE_POLY_SET::PM_FAST, and TransformCircleToPolygon().

Referenced by D_PAD::buildCustomPadPolygon(), CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon(), AM_PRIMITIVE::DrawBasicShape(), and DRAWSEGMENT::TransformShapeWithClearanceToPolygon().

◆ TransformRoundChamferedRectToPolygon()

void TransformRoundChamferedRectToPolygon ( SHAPE_POLY_SET aCornerBuffer,
const wxPoint &  aPosition,
const wxSize &  aSize,
double  aRotation,
int  aCornerRadius,
double  aChamferRatio,
int  aChamferCorners,
int  aCircleToSegmentsCount 
)

convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corners arcs to multiple straight lines

Parameters
aCornerBuffer= a buffer to store the polygon
aPosition= the coordinate of the center of the rectangle
aSize= the size of the rectangle
aCornerRadius= radius of rounded corners (can be 0)
aRotation= rotation in 0.1 degrees of the rectangle
aChamferRatio= ratio between smaller rect size and chamfer value
aChamferCorners= identifier of the corners to chamfer: 0 = no chamfer 1 = TOP_LEFT 2 = TOP_RIGHT 4 = BOTTOM_LEFT 8 = BOTTOM_RIGHT One can have more than one chamfered corner by ORing the corner identifers
aCircleToSegmentsCount= the number of segments to approximate a circle

Definition at line 242 of file convert_basic_shapes_to_polygon.cpp.

247 {
248  // Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
249  // or in actual position/orientation for round rect only
250  wxPoint corners[4];
251  GetRoundRectCornerCenters( corners, aCornerRadius,
252  aChamferCorners ? wxPoint( 0, 0 ) : aPosition,
253  aSize, aChamferCorners ? 0.0 : aRotation );
254 
255  SHAPE_POLY_SET outline;
256  outline.NewOutline();
257 
258  for( int ii = 0; ii < 4; ++ii )
259  outline.Append( corners[ii].x, corners[ii].y );
260 
261  outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
262 
263  if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
264  {
265  // Add the outline:
266  aCornerBuffer.Append( outline );
267  return;
268  }
269 
270  // Now we have the round rect outline, in position 0,0 orientation 0.0.
271  // Chamfer the corner(s).
272  int chamfer_value = aChamferRatio * std::min( aSize.x, aSize.y );
273 
274  SHAPE_POLY_SET chamfered_corner; // corner shape for the current corner to chamfer
275 
276  int corner_id[4] =
277  {
280  };
281  // Depending on the corner position, signX[] and signY[] give the sign of chamfer
282  // coordinates relative to the corner position
283  // The first corner is the top left corner, then top right, bottom left and bottom right
284  int signX[4] = {1, -1, 1,-1 };
285  int signY[4] = {1, 1, -1,-1 };
286 
287  for( int ii = 0; ii < 4; ii++ )
288  {
289  if( (corner_id[ii] & aChamferCorners) == 0 )
290  continue;
291 
292  VECTOR2I corner_pos( -signX[ii]*aSize.x/2, -signY[ii]*aSize.y/2 );
293 
294  if( aCornerRadius )
295  {
296  // We recreate a rectangular area covering the full rounded corner (max size = aSize/2)
297  // to rebuild the corner before chamfering, to be sure the rounded corner shape does not
298  // overlap the chamfered corner shape:
299  chamfered_corner.RemoveAllContours();
300  chamfered_corner.NewOutline();
301  chamfered_corner.Append( 0, 0 );
302  chamfered_corner.Append( 0, signY[ii]*aSize.y/2 );
303  chamfered_corner.Append( signX[ii]*aSize.x/2, signY[ii]*aSize.y/2 );
304  chamfered_corner.Append( signX[ii]*aSize.x/2, 0 );
305  chamfered_corner.Move( corner_pos );
306  outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
307  }
308 
309  // Now chamfer this corner
310  chamfered_corner.RemoveAllContours();
311  chamfered_corner.NewOutline();
312  chamfered_corner.Append( 0, 0 );
313  chamfered_corner.Append( 0, signY[ii]*chamfer_value );
314  chamfered_corner.Append( signX[ii]*chamfer_value, 0 );
315  chamfered_corner.Move( corner_pos );
316  outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
317  }
318 
319  // Rotate and move the outline:
320  if( aRotation != 0.0 )
321  outline.Rotate( DECIDEG2RAD( -aRotation ), VECTOR2I( 0, 0 ) );
322 
323  outline.Move( VECTOR2I( aPosition ) );
324 
325  // Add the outline:
326  aCornerBuffer.Append( outline );
327 }
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset union For aFastMode meaning, see function booleanOp
VECTOR2< int > VECTOR2I
Definition: vector2d.h:587
void Inflate(int aFactor, int aCircleSegmentsCount)
Performs outline inflation/deflation, using round corners.
void Move(const VECTOR2I &aVector) override
Class SHAPE_POLY_SET.
int NewOutline()
Creates a new empty polygon in the set and returns its index
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
double DECIDEG2RAD(double deg)
Definition: trigo.h:212
void GetRoundRectCornerCenters(wxPoint aCenters[4], int aRadius, const wxPoint &aPosition, const wxSize &aSize, double aRotation)
Helper function GetRoundRectCornerCenters Has meaning only for rounded rect Returns the centers of th...
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp
void Rotate(double aAngle, const VECTOR2I &aCenter)
Function Rotate rotates all vertices by a given angle.
#define min(a, b)
Definition: auxiliary.h:85
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References SHAPE_POLY_SET::Append(), SHAPE_POLY_SET::BooleanAdd(), SHAPE_POLY_SET::BooleanSubtract(), DECIDEG2RAD(), GetRoundRectCornerCenters(), SHAPE_POLY_SET::Inflate(), min, SHAPE_POLY_SET::Move(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, RECT_CHAMFER_BOTTOM_LEFT, RECT_CHAMFER_BOTTOM_RIGHT, RECT_CHAMFER_TOP_LEFT, RECT_CHAMFER_TOP_RIGHT, RECT_NO_CHAMFER, SHAPE_POLY_SET::RemoveAllContours(), and SHAPE_POLY_SET::Rotate().

Referenced by DRC::checkClearancePadToPad(), DRC::checkClearanceSegmToPad(), CINFO3D_VISU::createNewPadWithClearance(), KIGFX::PCB_PAINTER::draw(), D_PAD::DrawShape(), export_vrml_padshape(), HPGL_PLOTTER::FlashPadRoundRect(), PSLIKE_PLOTTER::FlashPadRoundRect(), GERBER_PLOTTER::FlashPadRoundRect(), DXF_PLOTTER::FlashPadRoundRect(), D_PAD::HitTest(), DSN::SPECCTRA_DB::makePADSTACK(), BRDITEMS_PLOTTER::PlotPad(), and D_PAD::TransformShapeWithClearanceToPolygon().

◆ TransformRoundedEndsSegmentToPolygon()

void TransformRoundedEndsSegmentToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aStart,
wxPoint  aEnd,
int  aCircleToSegmentsCount,
int  aWidth 
)

Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Convert arcs to multiple straight lines.

Parameters
aCornerBuffer= a buffer to store the polygon
aStart= the segment start point coordinate
aEnd= the segment end point coordinate
aCircleToSegmentsCount= the number of segments to approximate a circle
aWidth= the segment width Note: the polygon is inside the arc ends, so if you want to have the polygon outside the circle, you should give aStart and aEnd calculated with a correction factor

Definition at line 342 of file convert_basic_shapes_to_polygon.cpp.

346 {
347  int radius = aWidth / 2;
348  wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
349  wxPoint startp = aStart;
350  wxPoint corner;
351  VECTOR2I polypoint;
352 
353  aCornerBuffer.NewOutline();
354 
355  // normalize the position in order to have endp.x >= 0;
356  if( endp.x < 0 )
357  {
358  endp = aStart - aEnd;
359  startp = aEnd;
360  }
361 
362  double delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
363  int seg_len = KiROUND( EuclideanNorm( endp ) );
364 
365  int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
366 
367  // Compute the outlines of the segment, and creates a polygon
368  // add right rounded end:
369  for( int ii = 0; ii < 1800; ii += delta )
370  {
371  corner = wxPoint( 0, radius );
372  RotatePoint( &corner, ii );
373  corner.x += seg_len;
374  RotatePoint( &corner, -delta_angle );
375  corner += startp;
376  polypoint.x = corner.x;
377  polypoint.y = corner.y;
378  aCornerBuffer.Append( polypoint.x, polypoint.y );
379  }
380 
381  // Finish arc:
382  corner = wxPoint( seg_len, -radius );
383  RotatePoint( &corner, -delta_angle );
384  corner += startp;
385  polypoint.x = corner.x;
386  polypoint.y = corner.y;
387  aCornerBuffer.Append( polypoint.x, polypoint.y );
388 
389  // add left rounded end:
390  for( int ii = 0; ii < 1800; ii += delta )
391  {
392  corner = wxPoint( 0, -radius );
393  RotatePoint( &corner, ii );
394  RotatePoint( &corner, -delta_angle );
395  corner += startp;
396  polypoint.x = corner.x;
397  polypoint.y = corner.y;
398  aCornerBuffer.Append( polypoint.x, polypoint.y );
399  }
400 
401  // Finish arc:
402  corner = wxPoint( 0, radius );
403  RotatePoint( &corner, -delta_angle );
404  corner += startp;
405  polypoint.x = corner.x;
406  polypoint.y = corner.y;
407  aCornerBuffer.Append( polypoint.x, polypoint.y );
408 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:121
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:118
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
static const int delta[8][2]
Definition: solve.cpp:112
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
int NewOutline()
Creates a new empty polygon in the set and returns its index
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)

References SHAPE_POLY_SET::Append(), ArcTangente(), delta, EuclideanNorm(), KiROUND(), SHAPE_POLY_SET::NewOutline(), RotatePoint(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by addTextSegmToPoly(), D_PAD::buildCustomPadPolygon(), D_PAD::BuildPadDrillShapePolygon(), CINFO3D_VISU::buildPadShapeThickOutlineAsPolygon(), DXF_PLOTTER::PlotPoly(), TransformArcToPolygon(), DRAWSEGMENT::TransformShapeWithClearanceToPolygon(), and ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet().