39                               int aError, 
ERROR_LOC aErrorLoc, 
int aMinSegCount )
 
   43    numSegs = std::max( aMinSegCount, numSegs );
 
   46    numSegs = ( numSegs + 7 ) / 8 * 8;
 
   63        corner_position.
y = 0;
 
   65        corner_position += aCenter;
 
   66        aBuffer.
Append( corner_position.
x, corner_position.
y );
 
 
   74                               int aError, 
ERROR_LOC aErrorLoc, 
int aMinSegCount )
 
   78    numSegs = std::max( aMinSegCount, numSegs );
 
   81    numSegs = ( numSegs + 7 ) / 8 * 8;
 
  100        corner_position.
y = 0;
 
  102        corner_position += aCenter;
 
  103        aBuffer.
Append( corner_position.
x, corner_position.
y );
 
  108    corner_position.
y = 0;
 
  110    corner_position += aCenter;
 
  111    aBuffer.
Append( corner_position.
x, corner_position.
y );
 
 
  116                             int aWidth, 
int aError, 
ERROR_LOC aErrorLoc, 
int aMinSegCount )
 
  125    numSegs = std::max( aMinSegCount, numSegs );
 
  128    numSegs = ( numSegs + 7 ) / 8 * 8;
 
  154        endp    = aStart - aEnd;
 
  169    polyshape.
Append( corner.
x, corner.
y );
 
  176        polyshape.
Append( corner.
x, corner.
y );
 
  181    polyshape.
Append( corner.
x, corner.
y );
 
  185    polyshape.
Append( corner.
x, corner.
y );
 
  192        polyshape.
Append( corner.
x, corner.
y );
 
  197    polyshape.
Append( corner.
x, corner.
y );
 
  204    int halfwidth = aWidth / 2;     
 
  207    corner.
y = halfwidth;
 
  209    corner.
y = -halfwidth;
 
  211    corner.
x = 
radius + seg_len + 2;
 
  213    corner.
y = halfwidth;
 
  222    polyshape.
Rotate( -delta_angle );
 
  223    polyshape.
Move( startp );
 
  225    aBuffer.
Append( polyshape);
 
 
  240                          int aInflate, 
int aError, 
ERROR_LOC aErrorLoc )
 
  242    assert( aInflate >= 0 );
 
  244    VECTOR2I incoming = aCorners[0].m_position - aCorners.back().m_position;
 
  246    for( 
int n = 0, count = aCorners.size(); n < count; n++ )
 
  263            if( ( incoming.
x == 0 && outgoing.y == 0 ) || ( incoming.
y == 0 && outgoing.x == 0 ) )
 
  270                double cosNum = (double) incoming.
x * outgoing.x + (
double) incoming.
y * outgoing.y;
 
  271                double cosDen = (double) incoming.
EuclideanNorm() * outgoing.EuclideanNorm();
 
  272                double angle = acos( cosNum / cosDen );
 
  273                tanAngle2 = tan( ( 
M_PI - angle ) / 2 );
 
  277            if( aInflate && tanAngle2 )
 
  280                cornerPosition += incoming.
Resize( aInflate / tanAngle2 )
 
  291                while( lastSeg > angDelta )
 
  296                while( lastSeg < -angDelta )
 
  300            EDA_ANGLE angPos = lastSeg.
IsZero() ? angDelta : ( angDelta + lastSeg ) / 2;
 
  302            double   arcTransitionDistance = ( tanAngle2 > 0 ) ? ( 
radius / tanAngle2 ) : 0;
 
  303            VECTOR2I arcStart = cornerPosition - incoming.
Resize( arcTransitionDistance );
 
  310                arcStartOrigin = arcStart - arcCenter;
 
  311                outline.
Append( arcStart );
 
  319                arcStartOrigin = arcStart - arcCenter;
 
  323                SEG      outlineIn( cornerPosition - incoming, cornerPosition );
 
  325                arcEnd = cornerPosition; 
 
  327                while( angPos < endAngle )
 
  334                    if( outlineIn.
Side( pt ) > 0 )
 
  338                        wxCHECK_RET( 
intersect, wxT( 
"No solutions exist!" ) );
 
  345                    endAngle -= angDelta; 
 
  350            for( ; angPos < endAngle; angPos += angDelta )
 
  354                outline.
Append( pt + arcCenter );
 
 
  367    VECTOR2I prev = aCorners[0].m_position;
 
  369    for( 
int pos = aCorners.size() - 1; pos >= 0; pos-- )
 
  371        if( aCorners[pos].m_position == prev )
 
  372            aCorners.erase( aCorners.begin() + pos );
 
  374            prev = aCorners[pos].m_position;
 
 
  381                                  int aDeltaY, 
int aInflate, 
int aError, 
ERROR_LOC aErrorLoc )
 
  385    std::vector<ROUNDED_CORNER> corners;
 
  389        if( !aDeltaX && !aDeltaY ) 
 
  391            size.
x = std::max( 1, size.
x + aInflate );
 
  392            size.
y = std::max( 1, size.
y + aInflate );
 
  396            double slope = (double) aDeltaX / size.
x;
 
  397            int    yShrink = 
KiROUND( ( std::hypot( size.
x, aDeltaX ) * aInflate ) / size.
x );
 
  398            size.
y = std::max( 1, size.
y + yShrink );
 
  399            size.
x = std::max( 1, size.
x + aInflate );
 
  400            aDeltaX = 
KiROUND( size.
x * slope );
 
  402            if( aDeltaX > size.
y ) 
 
  404                corners.reserve( 3 );
 
  405                corners.emplace_back( -size.
x, -size.
y - aDeltaX );
 
  406                corners.emplace_back( 
KiROUND( size.
y / slope ), 0 );
 
  407                corners.emplace_back( -size.
x, size.
y + aDeltaX );
 
  412            double slope = (double) aDeltaY / size.
y;
 
  413            int    xShrink = 
KiROUND( ( std::hypot( size.
y, aDeltaY ) * aInflate ) / size.
y );
 
  414            size.
x = std::max( 1, size.
x + xShrink );
 
  415            size.
y = std::max( 1, size.
y + aInflate );
 
  416            aDeltaY = 
KiROUND( size.
y * slope );
 
  418            if( aDeltaY > size.
x )
 
  420                corners.reserve( 3 );
 
  421                corners.emplace_back( 0, -
KiROUND( size.
x / slope ) );
 
  422                corners.emplace_back( size.
x + aDeltaY, size.
y );
 
  423                corners.emplace_back( -size.
x - aDeltaY, size.
y );
 
  430    if( corners.empty() )
 
  432        corners.reserve( 4 );
 
  433        corners.emplace_back( -size.
x + aDeltaY, -size.
y - aDeltaX );
 
  434        corners.emplace_back( size.
x - aDeltaY, -size.
y + aDeltaX );
 
  435        corners.emplace_back( size.
x + aDeltaY, size.
y - aDeltaX );
 
  436        corners.emplace_back( -size.
x - aDeltaY, size.
y + aDeltaX );
 
  445        outline.
Rotate( aRotation );
 
  448    aBuffer.
Append( outline );
 
 
  454                                           int aCornerRadius, 
double aChamferRatio,
 
  455                                           int aChamferCorners, 
int aInflate, 
int aError,
 
  460    int            chamferCnt = std::bitset<8>( aChamferCorners ).count();
 
  461    double         chamferDeduct = 0;
 
  465        size.
x = std::max( 1, size.
x + aInflate );
 
  466        size.
y = std::max( 1, size.
y + aInflate );
 
  467        chamferDeduct = aInflate * ( 2.0 - M_SQRT2 );
 
  468        aCornerRadius = std::max( 0, aCornerRadius + aInflate );
 
  472    std::vector<ROUNDED_CORNER> corners;
 
  473    corners.reserve( 4 + chamferCnt );
 
  474    corners.emplace_back( -size.
x, -size.
y, aCornerRadius );
 
  475    corners.emplace_back( size.
x, -size.
y, aCornerRadius );
 
  476    corners.emplace_back( size.
x, size.
y, aCornerRadius );
 
  477    corners.emplace_back( -size.
x, size.
y, aCornerRadius );
 
  479    if( aChamferCorners )
 
  481        int shorterSide = std::min( aSize.
x, aSize.
y );
 
  482        int chamfer = std::max( 0, 
KiROUND( aChamferRatio * shorterSide + chamferDeduct ) );
 
  485        int sign[8] = { 0, 1, -1, 0, 0, -1, 1, 0 };
 
  487        for( 
int cc = 0, pos = 0; cc < 4; cc++, pos++ )
 
  489            if( !( aChamferCorners & chamId[cc] ) )
 
  492            corners[pos].m_radius = 0;
 
  497            corners.insert( corners.begin() + pos + 1, corners[pos] );
 
  498            corners[pos].m_position.x += 
sign[( 2 * cc ) & 7] * 
chamfer;
 
  499            corners[pos].m_position.y += 
sign[( 2 * cc - 2 ) & 7] * 
chamfer;
 
  500            corners[pos + 1].m_position.x += 
sign[( 2 * cc + 1 ) & 7] * 
chamfer;
 
  501            corners[pos + 1].m_position.y += 
sign[( 2 * cc - 1 ) & 7] * 
chamfer;
 
  505        if( chamferCnt > 1 && 2 * 
chamfer >= shorterSide )
 
  512        outline.
Rotate( aRotation );
 
  514    outline.
Move( aPosition );
 
  515    aBuffer.
Append( outline );
 
 
  525    if( aRadius >= aAccuracy )
 
  537        for( 
int i = 0; i <= n; i++, rot += 
delta )
 
  539            double x = aCenter.
x + aRadius * rot.
Cos();
 
  540            double y = aCenter.
y + aRadius * rot.
Sin();
 
  553        int errorRadius = aRadius + actual_delta_radius;
 
  555        double x = aCenter.
x + aRadius * aStartAngle.
Cos();
 
  556        double y = aCenter.
y + aRadius * aStartAngle.
Sin();
 
  562        for( 
int i = 0; i < n; i++, rot += 
delta )
 
  564            x = aCenter.
x + errorRadius * rot.
Cos();
 
  565            y = aCenter.
y + errorRadius * rot.
Sin();
 
  570        x = aCenter.
x + aRadius * ( aStartAngle + aArcAngle ).Cos();
 
  571        y = aCenter.
y + aRadius * ( aStartAngle + aArcAngle ).Sin();
 
 
  583    SEG startToEnd( aStart, aEnd );
 
  584    int distanceToMid = startToEnd.
Distance( aMid );
 
  586    if( distanceToMid <= 1 )
 
  596    SHAPE_ARC arc( aStart, aMid, aEnd, aWidth );
 
  599    EDA_ANGLE arc_angle_end = arc_angle_start + arc_angle;
 
  603        std::swap( arc_angle_start, arc_angle_end );
 
  604        arc = 
SHAPE_ARC( aEnd, aMid, aStart, aWidth );
 
  605        arc_angle = -arc_angle;
 
  608    int       radial_offset = arc.
GetWidth() / 2;
 
  609    int       arc_outer_radius = arc.
GetRadius() + radial_offset;
 
  610    int       arc_inner_radius = arc.
GetRadius() - radial_offset;
 
  625                          aError, errorLocOuter );
 
  632    if( arc_inner_radius > 0 )
 
  635                              -arc_angle, aError, errorLocInner );
 
  638    aBuffer.
Append( polyshape );
 
 
  643                             int aWidth, 
int aError, 
ERROR_LOC aErrorLoc )
 
  645    int inner_radius = aRadius - ( aWidth / 2 );
 
  646    int outer_radius = inner_radius + aWidth;
 
  648    if( inner_radius <= 0 )
 
  664                              aError, inner_err_loc );
 
 
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
 
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
 
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
 
int Side(const VECTOR2I &aP) const
Determine on which side of directed line passing via segment ends point aP lies.
 
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
 
int GetWidth() const override
 
const VECTOR2I & GetP1() const
 
EDA_ANGLE GetStartAngle() const
 
const VECTOR2I & GetP0() const
 
const VECTOR2I & GetCenter() const
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
 
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
 
Represent a set of closed polygons.
 
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
 
void Fracture()
Convert a set of polygons with holes to a single 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)
 
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
 
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the reference to aHole-th hole in the aIndex-th outline.
 
int NewOutline()
Creates a new empty polygon in the set and returns its index.
 
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
 
int NewHole(int aOutline=-1)
Creates a new hole in a given outline.
 
void Move(const VECTOR2I &aVector) override
 
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
 
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
 
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
 
void CornerListToPolygon(SHAPE_POLY_SET &outline, std::vector< ROUNDED_CORNER > &aCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
 
void TransformRingToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arcs to multiple straight segments.
 
int ConvertArcToPolyline(SHAPE_LINE_CHAIN &aPolyline, VECTOR2I aCenter, int aRadius, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aArcAngle, double aAccuracy, ERROR_LOC aErrorLoc)
Generate a polyline to approximate a arc.
 
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
 
void CornerListRemoveDuplicates(std::vector< ROUNDED_CORNER > &aCorners)
 
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount)
Convert a oblong shape to a polygon, using multiple segments.
 
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
 
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount)
Convert a circle to a polygon, using multiple straight lines.
 
void TransformTrapezoidToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aDeltaX, int aDeltaY, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle or trapezoid to a polygon.
 
@ RECT_CHAMFER_BOTTOM_RIGHT
 
@ RECT_CHAMFER_BOTTOM_LEFT
 
static constexpr EDA_ANGLE ANGLE_0
 
static constexpr EDA_ANGLE ANGLE_90
 
static constexpr EDA_ANGLE FULL_CIRCLE
 
static constexpr EDA_ANGLE ANGLE_360
 
static constexpr EDA_ANGLE ANGLE_180
 
a few functions useful in geometry calculations.
 
int GetCircleToPolyCorrection(int aMaxError)
 
int CircleToEndSegmentDeltaRadius(int aInnerCircleRadius, int aSegCount)
 
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
static bool intersect(const SEGMENT_WITH_NORMALS &aSeg, const SFVEC2F &aStart, const SFVEC2F &aEnd)
 
constexpr double correction
 
std::optional< VECTOR2I > OPT_VECTOR2I
 
ROUNDED_CORNER(int x, int y, int radius)
 
ROUNDED_CORNER(int x, int y)
 
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
 
constexpr int sign(T val)
 
VECTOR2< int32_t > VECTOR2I