34 double aCenterAngle,
int aWidth ) :
38 m_mid = aArcStartPoint;
39 m_end = aArcStartPoint;
49 const VECTOR2I& aArcEnd,
int aWidth ) :
50 SHAPE(
SH_ARC ), m_start( aArcStart ), m_mid( aArcMid ), m_end( aArcEnd ),
104 if( !p || aSegmentA.
Length() == 0 || aSegmentB.
Length() == 0 )
107 wxASSERT_MSG(
false,
"The input segments do not intersect or one is zero length." );
123 pToA = aSegmentA.
A - p.get();
126 pToB = aSegmentB.
A - p.get();
133 double distPC = (double) aRadius / abs( sin(
DECIDEG2RAD( alpha / 2 ) ) );
134 double angPC = pToAangle - alpha / 2;
150 double startAngle =
ArcTangente( startVector.
y, startVector.
x );
174 double aAngle,
double aWidth )
193 int minDist = aClearance +
m_width / 2;
203 double lambda = (double) ac.
Dot( ab ) / (double) lenAbSq;
205 if( lambda >= 0.0 && lambda <= 1.0 )
209 p.
x = (double) aSeg.
A.
x * lambda + (
double) aSeg.
B.
x * (1.0 - lambda);
210 p.
y = (double) aSeg.
A.
y * lambda + (
double) aSeg.
B.
y * (1.0 - lambda);
212 dist_sq = (
m_start - p ).SquaredEuclideanNorm();
214 if( dist_sq < closest_dist_sq )
216 closest_dist_sq = dist_sq;
220 dist_sq = (
m_end - p ).SquaredEuclideanNorm();
222 if( dist_sq < closest_dist_sq )
224 closest_dist_sq = dist_sq;
231 if( dist_sq < closest_dist_sq )
233 closest_dist_sq = dist_sq;
239 if( dist_sq < closest_dist_sq )
241 closest_dist_sq = dist_sq;
245 if( closest_dist_sq == 0 || closest_dist_sq <
SEG::Square( minDist ) )
248 *aLocation = nearest;
251 *aActual = std::max( 0, (
int) sqrt( closest_dist_sq ) -
m_width / 2 );
262 std::vector<VECTOR2I> points;
265 points.push_back(
m_end );
271 if( start_angle > end_angle )
272 std::swap( start_angle, end_angle );
274 int quad_angle_start = std::ceil( start_angle / 90.0 );
275 int quad_angle_end = std::floor( end_angle / 90.0 );
278 for(
int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle )
283 switch( quad_angle % 4 )
285 case 0: quad_pt += { radius, 0 };
break;
287 case -3: quad_pt += { 0, radius };
break;
289 case -2: quad_pt += { -radius, 0 };
break;
291 case -1: quad_pt += { 0, -radius };
break;
292 default: assert(
false );
295 points.push_back( quad_pt );
306 if( aClearance != 0 )
316 int minDist = aClearance +
m_width / 2;
317 auto bbox =
BBox( minDist );
319 if( !bbox.Contains( aP ) )
326 ecoord dist_to_edge_sq = abs( dist_sq - r_sq );
328 if( dist_to_edge_sq == 0 || dist_to_edge_sq < min_dist_sq )
334 *aActual = std::max( 0, (
int) sqrt( dist_to_edge_sq ) -
m_width / 2 );
347 auto ang = 180.0 / M_PI * atan2( d.
y, d.
x );
357 auto ang = 180.0 / M_PI * atan2( d.
y, d.
x );
411 for(
int i = 1; i < n ; i += 2 )
418 double x = c.x + r * cos( a * M_PI / 180.0 );
419 double y = c.y + r * sin( a * M_PI / 180.0 );
int Length() const
Return the length (this).
void Mirror(bool aX=true, bool aY=false, const VECTOR2I &aVector={ 0, 0 })
void Rotate(double aAngle, const VECTOR2I &aCenter) override
Function Rotate rotates the arc by a given angle about a point.
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,...
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle, double aWidth=0)
Constructs this arc from the given start, end and angle.
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
ecoord SquaredDistance(const SEG &aSeg) const
double GetStartAngle() const
void RotatePoint(int *pX, int *pY, double angle)
static SEG::ecoord Square(int a)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .. 180.0 range.
static constexpr extended_type ECOORD_MAX
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
const SHAPE_LINE_CHAIN ConvertToPolyline(double aAccuracy=0.005 *PCB_IU_PER_MM) const
Constructs a SHAPE_LINE_CHAIN of segments from a given arc.
OPT< VECTOR2I > OPT_VECTOR2I
a few functions useful in geometry calculations.
An abstract shape on 2D plane.
double GetEndAngle() const
void Move(const VECTOR2I &aVector) override
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
VECTOR2I::extended_type ecoord
double GetCentralAngle() const
double DECIDEG2RAD(double deg)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
double NormalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
SHAPE_ARC Reversed() const
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
double ArcTangente(int dy, int dx)
const VECTOR2I GetArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
VECTOR2I GetCenter() const