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 {
  RECT_NO_CHAMFER = 0, RECT_CHAMFER_TOP_LEFT = 1, RECT_CHAMFER_TOP_RIGHT = 2, RECT_CHAMFER_BOTTOM_LEFT = 4,
  RECT_CHAMFER_BOTTOM_RIGHT = 8
}
 

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

Enumerator
RECT_NO_CHAMFER 
RECT_CHAMFER_TOP_LEFT 
RECT_CHAMFER_TOP_RIGHT 
RECT_CHAMFER_BOTTOM_LEFT 
RECT_CHAMFER_BOTTOM_RIGHT 

Definition at line 44 of file convert_basic_shapes_to_polygon.h.

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 171 of file convert_basic_shapes_to_polygon.cpp.

173 {
174  wxSize size( aSize/2 );
175 
176  size.x -= aRadius;
177  size.y -= aRadius;
178 
179  // Ensure size is > 0, to avoid generating unusable shapes
180  // which can crash kicad.
181  if( size.x <= 1 )
182  size.x = 1;
183  if( size.y <= 1 )
184  size.y = 1;
185 
186  aCenters[0].x = -size.x;
187  aCenters[0].y = size.y;
188 
189  aCenters[1].x = size.x;
190  aCenters[1].y = size.y;
191 
192  aCenters[2].x = size.x;
193  aCenters[2].y = -size.y;
194 
195  aCenters[3].x = -size.x;
196  aCenters[3].y = -size.y;
197 
198  // Rotate the polygon
199  if( aRotation )
200  {
201  for( int ii = 0; ii < 4; ii++ )
202  RotatePoint( &aCenters[ii], aRotation );
203  }
204 
205  // move the polygon to the position
206  for( int ii = 0; ii < 4; ii++ )
207  aCenters[ii] += aPosition;
208 }
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 391 of file convert_basic_shapes_to_polygon.cpp.

394 {
395  wxPoint arc_start, arc_end;
396  int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
397 
398  arc_end = arc_start = aStart;
399 
400  if( aArcAngle != 3600 )
401  {
402  RotatePoint( &arc_end, aCentre, -aArcAngle );
403  }
404 
405  if( aArcAngle < 0 )
406  {
407  std::swap( arc_start, arc_end );
408  aArcAngle = -aArcAngle;
409  }
410 
411  // Compute the ends of segments and creates poly
412  wxPoint curr_end = arc_start;
413  wxPoint curr_start = arc_start;
414 
415  for( int ii = delta; ii < aArcAngle; ii += delta )
416  {
417  curr_end = arc_start;
418  RotatePoint( &curr_end, aCentre, -ii );
419  TransformRoundedEndsSegmentToPolygon( aCornerBuffer, curr_start, curr_end,
420  aCircleToSegmentsCount, aWidth );
421  curr_start = curr_end;
422  }
423 
424  if( curr_end != arc_end )
426  curr_end, arc_end,
427  aCircleToSegmentsCount, aWidth );
428 }
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

Definition at line 46 of file convert_basic_shapes_to_polygon.cpp.

49 {
50  wxPoint corner_position;
51  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
52  double halfstep = delta/2; // the starting value for rot angles
53 
54  aCornerBuffer.NewOutline();
55 
56  for( int ii = 0; ii < aCircleToSegmentsCount; ii++ )
57  {
58  corner_position.x = aRadius;
59  corner_position.y = 0;
60  double angle = (ii * delta) + halfstep;
61  RotatePoint( &corner_position, angle );
62  corner_position += aCenter;
63  aCornerBuffer.Append( corner_position.x, corner_position.y );
64  }
65 }
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().

Referenced by addHoleToPolygon(), D_PAD::buildCustomPadPolygon(), D_PAD::BuildPadDrillShapePolygon(), ConvertOutlineToPolygon(), D_CODE::ConvertShapeToPolygon(), CINFO3D_VISU::createLayers(), AM_PRIMITIVE::DrawBasicShape(), D_PAD::MergePrimitivesAsPolygon(), TransformRingToPolygon(), TRACK::TransformShapeWithClearanceToPolygon(), and D_PAD::TransformShapeWithClearanceToPolygon().

◆ 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 67 of file convert_basic_shapes_to_polygon.cpp.

70 {
71  // To build the polygonal shape outside the actual shape, we use a bigger
72  // radius to build rounded ends.
73  // However, the width of the segment is too big.
74  // so, later, we will clamp the polygonal shape with the bounding box
75  // of the segment.
76  int radius = aWidth / 2;
77 
78  // Note if we want to compensate the radius reduction of a circle due to
79  // the segment approx, aCorrectionFactor must be calculated like this:
80  // For a circle the min radius is radius * cos( 2PI / s_CircleToSegmentsCount / 2)
81  // aCorrectionFactor is 1 /cos( PI/s_CircleToSegmentsCount )
82 
83  radius = radius * aCorrectionFactor; // make segments outside the circles
84 
85  // end point is the coordinate relative to aStart
86  wxPoint endp = aEnd - aStart;
87  wxPoint startp = aStart;
88  wxPoint corner;
89  SHAPE_POLY_SET polyshape;
90 
91  polyshape.NewOutline();
92 
93  // normalize the position in order to have endp.x >= 0
94  // it makes calculations more easy to understand
95  if( endp.x < 0 )
96  {
97  endp = aStart - aEnd;
98  startp = aEnd;
99  }
100 
101  // delta_angle is in radian
102  double delta_angle = atan2( (double)endp.y, (double)endp.x );
103  int seg_len = KiROUND( EuclideanNorm( endp ) );
104 
105  double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
106 
107  // Compute the outlines of the segment, and creates a polygon
108  // Note: the polygonal shape is built from the equivalent horizontal
109  // segment starting ar 0,0, and ending at seg_len,0
110 
111  // add right rounded end:
112  for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
113  {
114  corner = wxPoint( 0, radius );
115  RotatePoint( &corner, delta*ii );
116  corner.x += seg_len;
117  polyshape.Append( corner.x, corner.y );
118  }
119 
120  // Finish arc:
121  corner = wxPoint( seg_len, -radius );
122  polyshape.Append( corner.x, corner.y );
123 
124  // add left rounded end:
125  for( int ii = 0; ii < aCircleToSegmentsCount/2; ii++ )
126  {
127  corner = wxPoint( 0, -radius );
128  RotatePoint( &corner, delta*ii );
129  polyshape.Append( corner.x, corner.y );
130  }
131 
132  // Finish arc:
133  corner = wxPoint( 0, radius );
134  polyshape.Append( corner.x, corner.y );
135 
136  // Now, clamp the polygonal shape (too big) with the segment bounding box
137  // the polygonal shape bbox equivalent to the segment has a too big height,
138  // and the right width
139  if( aCorrectionFactor > 1.0 )
140  {
141  SHAPE_POLY_SET bbox;
142  bbox.NewOutline();
143  // Build the bbox (a horizontal rectangle).
144  int halfwidth = aWidth / 2; // Use the exact segment width for the bbox height
145  corner.x = -radius - 2; // use a bbox width slightly bigger to avoid
146  // creating useless corner at segment ends
147  corner.y = halfwidth;
148  bbox.Append( corner.x, corner.y );
149  corner.y = -halfwidth;
150  bbox.Append( corner.x, corner.y );
151  corner.x = radius + seg_len + 2;
152  bbox.Append( corner.x, corner.y );
153  corner.y = halfwidth;
154  bbox.Append( corner.x, corner.y );
155 
156  // Now, clamp the shape
158  // Note the final polygon is a simple, convex polygon with no hole
159  // due to the shape of initial polygons
160  }
161 
162  // Rotate and move the polygon to its right location
163  polyshape.Rotate( delta_angle, VECTOR2I( 0, 0 ) );
164  polyshape.Move( startp );
165 
166  aCornerBuffer.Append( polyshape);
167 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
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 441 of file convert_basic_shapes_to_polygon.cpp.

444 {
445  // Compute the corners positions and creates the poly
446  wxPoint curr_point;
447  int inner_radius = aRadius - ( aWidth / 2 );
448  int outer_radius = inner_radius + aWidth;
449 
450  if( inner_radius <= 0 )
451  { //In this case, the ring is just a circle (no hole inside)
452  TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ),
453  aCircleToSegmentsCount );
454  return;
455  }
456 
457  aCornerBuffer.NewOutline();
458 
459  // Draw the inner circle of the ring
460  int delta = 3600 / aCircleToSegmentsCount; // rotate angle in 0.1 degree
461 
462  for( int ii = 0; ii < 3600; ii += delta )
463  {
464  curr_point.x = inner_radius;
465  curr_point.y = 0;
466  RotatePoint( &curr_point, ii );
467  curr_point += aCentre;
468  aCornerBuffer.Append( curr_point.x, curr_point.y );
469  }
470 
471  // Draw the last point of inner circle
472  aCornerBuffer.Append( aCentre.x + inner_radius, aCentre.y );
473 
474  // Draw the outer circle of the ring
475  // the first point creates also a segment from the inner to the outer polygon
476  for( int ii = 0; ii < 3600; ii += delta )
477  {
478  curr_point.x = outer_radius;
479  curr_point.y = 0;
480  RotatePoint( &curr_point, -ii );
481  curr_point += aCentre;
482  aCornerBuffer.Append( curr_point.x, curr_point.y );
483  }
484 
485  // Draw the last point of outer circle
486  aCornerBuffer.Append( aCentre.x + outer_radius, aCentre.y );
487 
488  // And connect the outer polygon to the inner polygon,.
489  // because a segment from inner to the outer polygon was already created,
490  // the final polygon is the inner and the outer outlines connected by
491  // 2 overlapping segments
492  aCornerBuffer.Append( aCentre.x + inner_radius, aCentre.y );
493 }
void TransformCircleToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aCenter, int aRadius, int aCircleToSegmentsCount)
Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines.
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
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(), delta, SHAPE_POLY_SET::NewOutline(), RotatePoint(), 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 211 of file convert_basic_shapes_to_polygon.cpp.

216 {
217  // Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
218  // or in actual position/orientation for round rect only
219  wxPoint corners[4];
220  GetRoundRectCornerCenters( corners, aCornerRadius,
221  aChamferCorners ? wxPoint( 0, 0 ) : aPosition,
222  aSize, aChamferCorners ? 0.0 : aRotation );
223 
224  SHAPE_POLY_SET outline;
225  outline.NewOutline();
226 
227  for( int ii = 0; ii < 4; ++ii )
228  outline.Append( corners[ii].x, corners[ii].y );
229 
230  outline.Inflate( aCornerRadius, aCircleToSegmentsCount );
231 
232  if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
233  {
234  // Add the outline:
235  aCornerBuffer.Append( outline );
236  return;
237  }
238 
239  // Now we have the round rect outline, in position 0,0 orientation 0.0.
240  // Chamfer the corner(s).
241  int chamfer_value = aChamferRatio * std::min( aSize.x, aSize.y );
242 
243  SHAPE_POLY_SET chamfered_corner; // corner shape for the current corner to chamfer
244 
245  int corner_id[4] =
246  {
249  };
250  // Depending on the corner position, signX[] and signY[] give the sign of chamfer
251  // coordinates relative to the corner position
252  // The first corner is the top left corner, then top right, bottom left and bottom right
253  int signX[4] = {1, -1, 1,-1 };
254  int signY[4] = {1, 1, -1,-1 };
255 
256  for( int ii = 0; ii < 4; ii++ )
257  {
258  if( (corner_id[ii] & aChamferCorners) == 0 )
259  continue;
260 
261  VECTOR2I corner_pos( -signX[ii]*aSize.x/2, -signY[ii]*aSize.y/2 );
262 
263  if( aCornerRadius )
264  {
265  // We recreate a rectangular area covering the full rounded corner (max size = aSize/2)
266  // to rebuild the corner before chamfering, to be sure the rounded corner shape does not
267  // overlap the chamfered corner shape:
268  chamfered_corner.RemoveAllContours();
269  chamfered_corner.NewOutline();
270  chamfered_corner.Append( 0, 0 );
271  chamfered_corner.Append( 0, signY[ii]*aSize.y/2 );
272  chamfered_corner.Append( signX[ii]*aSize.x/2, signY[ii]*aSize.y/2 );
273  chamfered_corner.Append( signX[ii]*aSize.x/2, 0 );
274  chamfered_corner.Move( corner_pos );
275  outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
276  }
277 
278  // Now chamfer this corner
279  chamfered_corner.RemoveAllContours();
280  chamfered_corner.NewOutline();
281  chamfered_corner.Append( 0, 0 );
282  chamfered_corner.Append( 0, signY[ii]*chamfer_value );
283  chamfered_corner.Append( signX[ii]*chamfer_value, 0 );
284  chamfered_corner.Move( corner_pos );
285  outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
286  }
287 
288  // Rotate and move the outline:
289  if( aRotation != 0.0 )
290  outline.Rotate( DECIDEG2RAD( -aRotation ), VECTOR2I( 0, 0 ) );
291 
292  outline.Move( VECTOR2I( aPosition ) );
293 
294  // Add the outline:
295  aCornerBuffer.Append( outline );
296 }
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:203
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 311 of file convert_basic_shapes_to_polygon.cpp.

315 {
316  int radius = aWidth / 2;
317  wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
318  wxPoint startp = aStart;
319  wxPoint corner;
320  VECTOR2I polypoint;
321 
322  aCornerBuffer.NewOutline();
323 
324  // normalize the position in order to have endp.x >= 0;
325  if( endp.x < 0 )
326  {
327  endp = aStart - aEnd;
328  startp = aEnd;
329  }
330 
331  double delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
332  int seg_len = KiROUND( EuclideanNorm( endp ) );
333 
334  int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
335 
336  // Compute the outlines of the segment, and creates a polygon
337  // add right rounded end:
338  for( int ii = 0; ii < 1800; ii += delta )
339  {
340  corner = wxPoint( 0, radius );
341  RotatePoint( &corner, ii );
342  corner.x += seg_len;
343  RotatePoint( &corner, -delta_angle );
344  corner += startp;
345  polypoint.x = corner.x;
346  polypoint.y = corner.y;
347  aCornerBuffer.Append( polypoint.x, polypoint.y );
348  }
349 
350  // Finish arc:
351  corner = wxPoint( seg_len, -radius );
352  RotatePoint( &corner, -delta_angle );
353  corner += startp;
354  polypoint.x = corner.x;
355  polypoint.y = corner.y;
356  aCornerBuffer.Append( polypoint.x, polypoint.y );
357 
358  // add left rounded end:
359  for( int ii = 0; ii < 1800; ii += delta )
360  {
361  corner = wxPoint( 0, -radius );
362  RotatePoint( &corner, ii );
363  RotatePoint( &corner, -delta_angle );
364  corner += startp;
365  polypoint.x = corner.x;
366  polypoint.y = corner.y;
367  aCornerBuffer.Append( polypoint.x, polypoint.y );
368  }
369 
370  // Finish arc:
371  corner = wxPoint( 0, radius );
372  RotatePoint( &corner, -delta_angle );
373  corner += startp;
374  polypoint.x = corner.x;
375  polypoint.y = corner.y;
376  aCornerBuffer.Append( polypoint.x, polypoint.y );
377 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:121
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().