KiCad PCB EDA Suite
convert_basic_shapes_to_polygon.h File Reference
#include <geometry/shape_poly_set.h>
#include <wx/gdicmn.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 aError)
 Function TransformCircleToPolygon convert a circle to a polygon, using multiple straight lines. More...
 
void TransformOvalToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aWidth, int aError)
 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 aApproxErrorMax, int aMinSegPerCircleCount=16)
 convert a rectangle with rounded corners and/or chamfered corners to a polygon Convert rounded corners arcs to multiple straight lines More...
 
void TransformSegmentToPolygon (SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aError, 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 aError, 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 aError, 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 189 of file convert_basic_shapes_to_polygon.cpp.

191 {
192  wxSize size( aSize/2 );
193 
194  size.x -= aRadius;
195  size.y -= aRadius;
196 
197  // Ensure size is > 0, to avoid generating unusable shapes
198  // which can crash kicad.
199  if( size.x <= 1 )
200  size.x = 1;
201  if( size.y <= 1 )
202  size.y = 1;
203 
204  aCenters[0].x = -size.x;
205  aCenters[0].y = size.y;
206 
207  aCenters[1].x = size.x;
208  aCenters[1].y = size.y;
209 
210  aCenters[2].x = size.x;
211  aCenters[2].y = -size.y;
212 
213  aCenters[3].x = -size.x;
214  aCenters[3].y = -size.y;
215 
216  // Rotate the polygon
217  if( aRotation )
218  {
219  for( int ii = 0; ii < 4; ii++ )
220  RotatePoint( &aCenters[ii], aRotation );
221  }
222 
223  // move the polygon to the position
224  for( int ii = 0; ii < 4; ii++ )
225  aCenters[ii] += aPosition;
226 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208

References RotatePoint(), wxPoint::x, and wxPoint::y.

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

◆ TransformArcToPolygon()

void TransformArcToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aCentre,
wxPoint  aStart,
double  aArcAngle,
int  aError,
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
aError= the IU allowed for error in approximation
aWidth= width (thickness) of the line

Definition at line 389 of file convert_basic_shapes_to_polygon.cpp.

392 {
393  wxPoint arc_start, arc_end;
394  int dist = EuclideanNorm( aCentre - aStart );
395  int numSegs = std::max( GetArcToSegmentCount( dist, aError, 360.0 ), 6 );
396  int delta = 3600 / numSegs; // 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  TransformSegmentToPolygon( aCornerBuffer, curr_start, curr_end, aError,
420  aWidth );
421  curr_start = curr_end;
422  }
423 
424  if( curr_end != arc_end )
425  TransformSegmentToPolygon( aCornerBuffer, curr_end, arc_end, aError, aWidth );
426 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
static const int dist[10][10]
Definition: ar_matrix.cpp:326
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
void TransformSegmentToPolygon(SHAPE_POLY_SET &aCornerBuffer, wxPoint aStart, wxPoint aEnd, int aError, int aWidth)
Function TransformRoundedEndsSegmentToPolygon convert a segment with rounded ends to a polygon Conver...
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)

References dist, EuclideanNorm(), GetArcToSegmentCount(), RotatePoint(), and TransformSegmentToPolygon().

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

◆ TransformCircleToPolygon()

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

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
aError= the IU allowed for error in approximation 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 66 of file convert_basic_shapes_to_polygon.cpp.

68 {
69  wxPoint corner_position;
70  int numSegs = std::max( GetArcToSegmentCount( aRadius, aError, 360.0 ), 6 );
71  int delta = 3600 / numSegs; // rotate angle in 0.1 degree
72  double correction = GetCircletoPolyCorrectionFactor( numSegs );
73  int radius = aRadius * correction; // make segments outside the circles
74  double halfstep = delta/2.0; // the starting value for rot angles
75 
76  aCornerBuffer.NewOutline();
77 
78  for( int ii = 0; ii < numSegs; ii++ )
79  {
80  corner_position.x = radius;
81  corner_position.y = 0;
82  double angle = (ii * delta) + halfstep;
83  RotatePoint( &corner_position, angle );
84  corner_position += aCenter;
85  aCornerBuffer.Append( corner_position.x, corner_position.y );
86  }
87 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
double GetCircletoPolyCorrectionFactor(int aSegCountforCircle)
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 GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
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(), GetArcToSegmentCount(), GetCircletoPolyCorrectionFactor(), SHAPE_POLY_SET::NewOutline(), RotatePoint(), wxPoint::x, and wxPoint::y.

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

◆ TransformOvalToPolygon()

void TransformOvalToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aStart,
wxPoint  aEnd,
int  aWidth,
int  aError 
)

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
aError= the IU allowed for error in approximation

Definition at line 90 of file convert_basic_shapes_to_polygon.cpp.

92 {
93  // To build the polygonal shape outside the actual shape, we use a bigger
94  // radius to build rounded ends.
95  // However, the width of the segment is too big.
96  // so, later, we will clamp the polygonal shape with the bounding box
97  // of the segment.
98  int radius = aWidth / 2;
99  int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
100  int delta = 3600 / numSegs; // rotate angle in 0.1 degree
101  double correction = GetCircletoPolyCorrectionFactor( numSegs );
102 
103  radius = radius * correction; // make segments outside the circles
104 
105  // end point is the coordinate relative to aStart
106  wxPoint endp = aEnd - aStart;
107  wxPoint startp = aStart;
108  wxPoint corner;
109  SHAPE_POLY_SET polyshape;
110 
111  polyshape.NewOutline();
112 
113  // normalize the position in order to have endp.x >= 0
114  // it makes calculations more easy to understand
115  if( endp.x < 0 )
116  {
117  endp = aStart - aEnd;
118  startp = aEnd;
119  }
120 
121  // delta_angle is in radian
122  double delta_angle = atan2( (double)endp.y, (double)endp.x );
123  int seg_len = KiROUND( EuclideanNorm( endp ) );
124 
125 
126  // Compute the outlines of the segment, and creates a polygon
127  // Note: the polygonal shape is built from the equivalent horizontal
128  // segment starting ar 0,0, and ending at seg_len,0
129 
130  // add right rounded end:
131  for( int ii = 0; ii < numSegs / 2; ii++ )
132  {
133  corner = wxPoint( 0, radius );
134  RotatePoint( &corner, delta * ii );
135  corner.x += seg_len;
136  polyshape.Append( corner.x, corner.y );
137  }
138 
139  // Finish arc:
140  corner = wxPoint( seg_len, -radius );
141  polyshape.Append( corner.x, corner.y );
142 
143  // add left rounded end:
144  for( int ii = 0; ii < numSegs / 2; ii++ )
145  {
146  corner = wxPoint( 0, -radius );
147  RotatePoint( &corner, delta * ii );
148  polyshape.Append( corner.x, corner.y );
149  }
150 
151  // Finish arc:
152  corner = wxPoint( 0, radius );
153  polyshape.Append( corner.x, corner.y );
154 
155  // Now, clamp the polygonal shape (too big) with the segment bounding box
156  // the polygonal shape bbox equivalent to the segment has a too big height,
157  // and the right width
158  if( correction > 1.0 )
159  {
160  SHAPE_POLY_SET bbox;
161  bbox.NewOutline();
162  // Build the bbox (a horizontal rectangle).
163  int halfwidth = aWidth / 2; // Use the exact segment width for the bbox height
164  corner.x = -radius - 2; // use a bbox width slightly bigger to avoid
165  // creating useless corner at segment ends
166  corner.y = halfwidth;
167  bbox.Append( corner.x, corner.y );
168  corner.y = -halfwidth;
169  bbox.Append( corner.x, corner.y );
170  corner.x = radius + seg_len + 2;
171  bbox.Append( corner.x, corner.y );
172  corner.y = halfwidth;
173  bbox.Append( corner.x, corner.y );
174 
175  // Now, clamp the shape
177  // Note the final polygon is a simple, convex polygon with no hole
178  // due to the shape of initial polygons
179  }
180 
181  // Rotate and move the polygon to its right location
182  polyshape.Rotate( delta_angle, VECTOR2I( 0, 0 ) );
183  polyshape.Move( startp );
184 
185  aCornerBuffer.Append( polyshape);
186 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 })
Function Rotate rotates all vertices by a given angle.
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void Move(const VECTOR2I &aVector) override
double GetCircletoPolyCorrectionFactor(int aSegCountforCircle)
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
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
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(), EuclideanNorm(), GetArcToSegmentCount(), GetCircletoPolyCorrectionFactor(), KiROUND(), SHAPE_POLY_SET::Move(), SHAPE_POLY_SET::NewOutline(), SHAPE_POLY_SET::PM_STRICTLY_SIMPLE, SHAPE_POLY_SET::Rotate(), RotatePoint(), wxPoint::x, and wxPoint::y.

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  aError,
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
aError= the IU allowed for error in approximation
aWidth= width (thickness) of the ring

Definition at line 429 of file convert_basic_shapes_to_polygon.cpp.

432 {
433  // Compute the corners positions and creates the poly
434  wxPoint curr_point;
435  int inner_radius = aRadius - ( aWidth / 2 );
436  int outer_radius = inner_radius + aWidth;
437 
438  if( inner_radius <= 0 )
439  { //In this case, the ring is just a circle (no hole inside)
440  TransformCircleToPolygon( aCornerBuffer, aCentre, aRadius + ( aWidth / 2 ), aError );
441  return;
442  }
443 
444  SHAPE_POLY_SET buffer;
445 
446  TransformCircleToPolygon( buffer, aCentre, outer_radius, aError );
447 
448  // Build the hole:
449  buffer.NewHole();
450  TransformCircleToPolygon( buffer.Hole( 0, 0 ), aCentre, inner_radius, aError );
451 
453  aCornerBuffer.Append( buffer );
454 }
int NewHole(int aOutline=-1)
Creates a new hole in a given outline
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, wxPoint aCenter, int aRadius, int aError)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Returns the reference to aHole-th hole in the aIndex-th outline
SHAPE_POLY_SET.
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  aApproxErrorMax,
int  aMinSegPerCircleCount = 16 
)

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
aApproxErrorMax= the IU allowed for error in approximation
aMinSegPerCircleCount= the minimal segments per circle count in approximation (aApproxErrorMax can generate must more seg count than aMinSegPerCircleCount) To allow a reasonable good shape even for very small shapes, the min count is 16 (must be a multiple of 4 becauseusually arcs are 90 deg.

Definition at line 229 of file convert_basic_shapes_to_polygon.cpp.

234 {
235  // Build the basic shape in orientation 0.0, position 0,0 for chamfered corners
236  // or in actual position/orientation for round rect only
237  wxPoint corners[4];
238  GetRoundRectCornerCenters( corners, aCornerRadius,
239  aChamferCorners ? wxPoint( 0, 0 ) : aPosition,
240  aSize, aChamferCorners ? 0.0 : aRotation );
241 
242  SHAPE_POLY_SET outline;
243  outline.NewOutline();
244 
245  for( int ii = 0; ii < 4; ++ii )
246  outline.Append( corners[ii].x, corners[ii].y );
247 
248  int numSegs = std::max( GetArcToSegmentCount( aCornerRadius, aApproxErrorMax, 360.0 ),
249  aMinSegPerCircleCount );
250  outline.Inflate( aCornerRadius, numSegs );
251 
252  if( aChamferCorners == RECT_NO_CHAMFER ) // no chamfer
253  {
254  // Add the outline:
255  aCornerBuffer.Append( outline );
256  return;
257  }
258 
259  // Now we have the round rect outline, in position 0,0 orientation 0.0.
260  // Chamfer the corner(s).
261  int chamfer_value = aChamferRatio * std::min( aSize.x, aSize.y );
262 
263  SHAPE_POLY_SET chamfered_corner; // corner shape for the current corner to chamfer
264 
265  int corner_id[4] =
266  {
269  };
270  // Depending on the corner position, signX[] and signY[] give the sign of chamfer
271  // coordinates relative to the corner position
272  // The first corner is the top left corner, then top right, bottom left and bottom right
273  int signX[4] = {1, -1, 1,-1 };
274  int signY[4] = {1, 1, -1,-1 };
275 
276  for( int ii = 0; ii < 4; ii++ )
277  {
278  if( (corner_id[ii] & aChamferCorners) == 0 )
279  continue;
280 
281  VECTOR2I corner_pos( -signX[ii]*aSize.x/2, -signY[ii]*aSize.y/2 );
282 
283  if( aCornerRadius )
284  {
285  // We recreate a rectangular area covering the full rounded corner (max size = aSize/2)
286  // to rebuild the corner before chamfering, to be sure the rounded corner shape does not
287  // overlap the chamfered corner shape:
288  chamfered_corner.RemoveAllContours();
289  chamfered_corner.NewOutline();
290  chamfered_corner.Append( 0, 0 );
291  chamfered_corner.Append( 0, signY[ii] * aSize.y / 2 );
292  chamfered_corner.Append( signX[ii] * aSize.x / 2, signY[ii] * aSize.y / 2 );
293  chamfered_corner.Append( signX[ii] * aSize.x / 2, 0 );
294  chamfered_corner.Move( corner_pos );
295  outline.BooleanAdd( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
296  }
297 
298  // Now chamfer this corner
299  chamfered_corner.RemoveAllContours();
300  chamfered_corner.NewOutline();
301  chamfered_corner.Append( 0, 0 );
302  chamfered_corner.Append( 0, signY[ii] * chamfer_value );
303  chamfered_corner.Append( signX[ii] * chamfer_value, 0 );
304  chamfered_corner.Move( corner_pos );
305  outline.BooleanSubtract( chamfered_corner, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
306  }
307 
308  // Rotate and move the outline:
309  if( aRotation != 0.0 )
310  outline.Rotate( DECIDEG2RAD( -aRotation ), VECTOR2I( 0, 0 ) );
311 
312  outline.Move( VECTOR2I( aPosition ) );
313 
314  // Add the outline:
315  aCornerBuffer.Append( outline );
316 }
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 })
Function Rotate rotates all vertices by a given angle.
void BooleanAdd(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset union For aFastMode meaning, see function booleanOp
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
void Inflate(int aAmount, int aCircleSegmentsCount, CORNER_STRATEGY aCornerStrategy=ROUND_ALL_CORNERS)
Performs outline inflation/deflation.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void Move(const VECTOR2I &aVector) override
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:214
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
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
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(), GetArcToSegmentCount(), GetRoundRectCornerCenters(), SHAPE_POLY_SET::Inflate(), 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(), SHAPE_POLY_SET::Rotate(), wxPoint::x, and wxPoint::y.

Referenced by DRC::checkClearancePadToPad(), DRC::checkClearanceSegmToPad(), CINFO3D_VISU::createNewPadWithClearance(), 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(), D_PAD::PrintShape(), and D_PAD::TransformShapeWithClearanceToPolygon().

◆ TransformSegmentToPolygon()

void TransformSegmentToPolygon ( SHAPE_POLY_SET aCornerBuffer,
wxPoint  aStart,
wxPoint  aEnd,
int  aError,
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
aError= the IU allowed for error in approximation
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 319 of file convert_basic_shapes_to_polygon.cpp.

322 {
323  int radius = aWidth / 2;
324  wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
325  wxPoint startp = aStart;
326  wxPoint corner;
327  VECTOR2I polypoint;
328  int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
329  double correction = GetCircletoPolyCorrectionFactor( numSegs );
330  int delta = 3600 / numSegs; // rotate angle in 0.1 degree
331 
332  radius = KiROUND( radius * correction );
333  aCornerBuffer.NewOutline();
334 
335  // normalize the position in order to have endp.x >= 0;
336  if( endp.x < 0 )
337  {
338  endp = aStart - aEnd;
339  startp = aEnd;
340  }
341 
342  double delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
343  int seg_len = KiROUND( EuclideanNorm( endp ) );
344 
345  // Compute the outlines of the segment, and creates a polygon
346  // add right rounded end:
347  for( int ii = 0; ii < 1800; ii += delta )
348  {
349  corner = wxPoint( 0, radius );
350  RotatePoint( &corner, ii );
351  corner.x += seg_len;
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 
359  // Finish arc:
360  corner = wxPoint( seg_len, -radius );
361  RotatePoint( &corner, -delta_angle );
362  corner += startp;
363  polypoint.x = corner.x;
364  polypoint.y = corner.y;
365  aCornerBuffer.Append( polypoint.x, polypoint.y );
366 
367  // add left rounded end:
368  for( int ii = 0; ii < 1800; ii += delta )
369  {
370  corner = wxPoint( 0, -radius );
371  RotatePoint( &corner, ii );
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  }
378 
379  // Finish arc:
380  corner = wxPoint( 0, radius );
381  RotatePoint( &corner, -delta_angle );
382  corner += startp;
383  polypoint.x = corner.x;
384  polypoint.y = corner.y;
385  aCornerBuffer.Append( polypoint.x, polypoint.y );
386 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:123
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
double GetCircletoPolyCorrectionFactor(int aSegCountforCircle)
int NewOutline()
Creates a new empty polygon in the set and returns its index
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:61
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:162
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
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(), EuclideanNorm(), GetArcToSegmentCount(), GetCircletoPolyCorrectionFactor(), KiROUND(), SHAPE_POLY_SET::NewOutline(), RotatePoint(), wxPoint::x, VECTOR2< T >::x, wxPoint::y, 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().