38 aStream <<
"Arc( P0=" << aArc.
GetP0() <<
" P1=" << aArc.
GetP1() <<
" Mid=" << aArc.
GetArcMid()
39 <<
" Width=" << aArc.
GetWidth() <<
" )";
45 const EDA_ANGLE& aCenterAngle,
int aWidth ) :
66 const VECTOR2I& aArcEnd,
int aWidth ) :
124 if( !p || aSegmentA.
Length() == 0 || aSegmentB.
Length() == 0 )
127 wxASSERT_MSG(
false,
"The input segments do not intersect or one is zero length." );
143 pToA = aSegmentA.
A - *p;
146 pToB = aSegmentB.
A - *p;
151 EDA_ANGLE alpha = ( pToAangle - pToBangle ).Normalize180();
153 double distPC = (double) aRadius / abs( sin( alpha.
AsRadians() / 2 ) );
157 arcCenter.
x = p->x +
KiROUND( distPC * angPC.
Cos() );
158 arcCenter.
y = p->y +
KiROUND( distPC * angPC.
Sin() );
171 EDA_ANGLE midPointRotAngle = ( startAngle - endAngle ).Normalize180() / 2;
211 const VECTOR2I& aCenter,
bool aClockwise,
214 VECTOR2I startLine = aStart - aCenter;
244 if( aSeg.
A == aSeg.
B )
245 return Collide( aSeg.
A, aClearance, aActual, aLocation );
256 std::vector<VECTOR2I> candidatePts = circle.
Intersect( aSeg );
261 candidatePts.push_back( aSeg.
A );
262 candidatePts.push_back( aSeg.
B );
264 for(
const VECTOR2I& candidate : candidatePts )
266 if(
Collide( candidate, aClearance, aActual, aLocation ) )
276 if( aSeg.
A == aSeg.
B )
281 std::vector<VECTOR2I> intersections = circ.
IntersectLine( aSeg );
283 size_t originalSize = aIpsBuffer->size();
285 for(
const VECTOR2I& intersection : intersections )
288 aIpsBuffer->push_back( intersection );
291 return aIpsBuffer->size() - originalSize;
300 std::vector<VECTOR2I> intersections = thiscirc.
Intersect( othercirc );
302 size_t originalSize = aIpsBuffer->size();
304 for(
const VECTOR2I& intersection : intersections )
307 aIpsBuffer->push_back( intersection );
310 return aIpsBuffer->size() - originalSize;
316 std::vector<VECTOR2I> points;
319 points.push_back(
m_end );
325 if( start_angle > end_angle )
326 std::swap( start_angle, end_angle );
328 int quad_angle_start = std::ceil( start_angle.
AsDegrees() / 90.0 );
329 int quad_angle_end = std::floor( end_angle.
AsDegrees() / 90.0 );
335 for(
int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle )
339 switch( quad_angle % 4 )
341 case 0: quad_pt += { radius, 0 };
break;
342 case 1:
case -3: quad_pt += { 0, radius };
break;
343 case 2:
case -2: quad_pt += { -radius, 0 };
break;
344 case 3:
case -1: quad_pt += { 0, -radius };
break;
349 points.push_back( quad_pt );
360 if( aClearance != 0 )
376 int minDist = aClearance +
m_width / 2;
377 auto bbox =
BBox( minDist );
380 if( !bbox.Contains( aP ) )
396 if( (
ccw && rotatedPtAngle > rotatedEndAngle )
397 || ( !
ccw && rotatedPtAngle < rotatedEndAngle ) )
401 dist = std::min( distStartpt, distEndpt );
405 if( dist <= minDist )
408 *aLocation = nearestPt;
411 *aActual = std::max( 0, dist -
m_width / 2 );
472 double* aEffectiveAccuracy )
const
484 double external_radius = r+(
m_width/2);
485 double effectiveAccuracy;
487 if( external_radius < aAccuracy/2 )
492 effectiveAccuracy = external_radius;
499 int seg360 = n * 360.0 / fabs( ca.
AsDegrees() );
506 r += effectiveAccuracy / 2;
511 for(
int i = 1; i < n ; i += 2 )
518 double x = c.
x + r * a.
Cos();
519 double y = c.
y + r * a.
Sin();
526 if( aEffectiveAccuracy )
527 *aEffectiveAccuracy = effectiveAccuracy;
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Represent basic circle geometry with utility geometry functions.
VECTOR2I Center
Public to make access simpler.
std::vector< VECTOR2I > Intersect(const CIRCLE &aCircle) const
Compute the intersection points between this circle and aCircle.
std::vector< VECTOR2I > IntersectLine(const SEG &aLine) const
Compute the intersection points between this circle and aLine.
VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute the point on the circumference of the circle that is the closest to aP.
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
int Length() const
Return the length (this).
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
EDA_ANGLE GetCentralAngle() const
const VECTOR2I & GetArcMid() const
void Move(const VECTOR2I &aVector) override
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
EDA_ANGLE GetEndAngle() const
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter) override
Rotate the arc by a given angle about a point.
bool sliceContainsPoint(const VECTOR2I &p) const
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
SHAPE_ARC Reversed() const
const VECTOR2I & GetP1() const
int IntersectLine(const SEG &aSeg, std::vector< VECTOR2I > *aIpsBuffer) const
Find intersection points between this arc and aSeg, treating aSeg as an infinite line.
bool Collide(const SEG &aSeg, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance,...
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
int Intersect(const SHAPE_ARC &aArc, std::vector< VECTOR2I > *aIpsBuffer) const
Find intersection points between this arc and aArc.
EDA_ANGLE GetStartAngle() const
void TransformToPolygon(SHAPE_POLY_SET &aBuffer, int aError, ERROR_LOC aErrorLoc) const override
Fills a SHAPE_POLY_SET with a polygon representation of this shape.
VECTOR2I GetCenter() const
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aVector={ 0, 0 })
bool ccw(const VECTOR2I &aA, const VECTOR2I &aB, const VECTOR2I &aC) const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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.
An abstract shape on 2D plane.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
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.
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & ANGLE_90
static constexpr EDA_ANGLE & ANGLE_0
a few functions useful in geometry calculations.
int CircleToEndSegmentDeltaRadius(int aInnerCircleRadius, int aSegCount)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
bool within_wrapped_range(T __val, T __minval, T __maxval, T __wrap)
Test if __val lies within __minval and __maxval in a wrapped range.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
std::optional< VECTOR2I > OPT_VECTOR2I
std::ostream & operator<<(std::ostream &aStream, const SHAPE_ARC &aArc)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
double EuclideanNorm(const VECTOR2I &vector)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".