KiCad PCB EDA Suite
SHAPE_ARC Class Reference

#include <shape_arc.h>

Inheritance diagram for SHAPE_ARC:
SHAPE SHAPE_BASE

Public Member Functions

 SHAPE_ARC ()
 
 SHAPE_ARC (const VECTOR2I &aArcCenter, const VECTOR2I &aArcStartPoint, const EDA_ANGLE &aCenterAngle, int aWidth=0)
 Construct and arc using center, start, angle. More...
 
 SHAPE_ARC (const VECTOR2I &aArcStart, const VECTOR2I &aArcMid, const VECTOR2I &aArcEnd, int aWidth)
 
 SHAPE_ARC (const SEG &aSegmentA, const SEG &aSegmentB, int aRadius, int aWidth=0)
 Build a SHAPE_ARC which is tangent to two segments and a given radius. More...
 
 SHAPE_ARC (const SHAPE_ARC &aOther)
 
virtual ~SHAPE_ARC ()
 
SHAPEClone () const override
 Return a dynamically allocated copy of the shape. More...
 
SHAPE_ARCConstructFromStartEndAngle (const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
 Construct this arc from the given start, end and angle. More...
 
SHAPE_ARCConstructFromStartEndCenter (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. More...
 
const VECTOR2IGetP0 () const
 
const VECTOR2IGetP1 () const
 
const VECTOR2IGetArcMid () const
 
VECTOR2I GetCenter () const
 
const BOX2I BBox (int aClearance=0) const override
 Compute a bounding box of the shape, with a margin of aClearance a collision. More...
 
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, indicating a collision. More...
 
bool Collide (const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 Check if the boundary of shape (this) lies closer to the point aP than aClearance, indicating a collision. More...
 
bool Collide (const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
 
int IntersectLine (const SEG &aSeg, std::vector< VECTOR2I > *aIpsBuffer) const
 Find intersection points between this arc and aSeg, treating aSeg as an infinite line. More...
 
int Intersect (const SHAPE_ARC &aArc, std::vector< VECTOR2I > *aIpsBuffer) const
 Find intersection points between this arc and aArc. More...
 
bool IsClockwise () const
 
void SetWidth (int aWidth)
 
int GetWidth () const
 
bool IsSolid () const override
 
void Move (const VECTOR2I &aVector) override
 
void Rotate (const EDA_ANGLE &aAngle, const VECTOR2I &aCenter) override
 Rotate the arc by a given angle about a point. More...
 
void Mirror (bool aX=true, bool aY=false, const VECTOR2I &aVector={ 0, 0 })
 
void Mirror (const SEG &axis)
 
void Reverse ()
 
SHAPE_ARC Reversed () const
 
double GetRadius () const
 
SEG GetChord () const
 
EDA_ANGLE GetCentralAngle () const
 
EDA_ANGLE GetStartAngle () const
 
EDA_ANGLE GetEndAngle () const
 
double GetLength () const
 
const SHAPE_LINE_CHAIN ConvertToPolyline (double aAccuracy=DefaultAccuracyForPCB(), double *aEffectiveAccuracy=nullptr) const
 Construct a SHAPE_LINE_CHAIN of segments from a given arc. More...
 
bool operator== (SHAPE_ARC const &aArc) const
 
int GetClearance (const SHAPE *aOther) const
 Return the actual minimum distance between two shapes. More...
 
bool IsNull () const
 Return true if the shape is a null shape. More...
 
virtual bool Collide (const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const
 Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision. More...
 
virtual VECTOR2I Centre () const
 Compute a center-of-mass of the shape. More...
 
virtual bool Parse (std::stringstream &aStream)
 
virtual const std::string Format (bool aCplusPlus=true) const
 
FACETNewFacet ()
 
SGNODECalcShape (SGNODE *aParent, SGNODE *aColor, WRL1_ORDER aVertexOrder, float aCreaseLimit=0.74317, bool isVRML2=false)
 
SHAPE_TYPE Type () const
 Return the type of the shape. More...
 
wxString TypeName () const
 
virtual bool HasIndexableSubshapes () const
 
virtual size_t GetIndexableSubshapeCount () const
 
virtual void GetIndexableSubshapes (std::vector< const SHAPE * > &aSubshapes) const
 

Static Public Member Functions

static double DefaultAccuracyForPCB ()
 

Static Public Attributes

static const int MIN_PRECISION_IU = 4
 This is the minimum precision for all the points in a shape. More...
 

Protected Types

typedef VECTOR2I::extended_type ecoord
 

Protected Attributes

SHAPE_TYPE m_type
 < type of our shape More...
 

Private Member Functions

bool ccw (const VECTOR2I &aA, const VECTOR2I &aB, const VECTOR2I &aC) const
 
void update_bbox ()
 
bool sliceContainsPoint (const VECTOR2I &p) const
 

Private Attributes

VECTOR2I m_start
 
VECTOR2I m_mid
 
VECTOR2I m_end
 
int m_width
 
BOX2I m_bbox
 
std::list< FACET * > facets
 

Detailed Description

Definition at line 36 of file shape_arc.h.

Member Typedef Documentation

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 250 of file shape.h.

Constructor & Destructor Documentation

◆ SHAPE_ARC() [1/5]

SHAPE_ARC::SHAPE_ARC ( )
inline

Definition at line 40 of file shape_arc.h.

40 :
41 SHAPE( SH_ARC ),
42 m_width( 0 )
43 {};
int m_width
Definition: shape_arc.h:263
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:134
@ SH_ARC
circular arc
Definition: shape.h:52

Referenced by Clone(), and Reversed().

◆ SHAPE_ARC() [2/5]

SHAPE_ARC::SHAPE_ARC ( const VECTOR2I aArcCenter,
const VECTOR2I aArcStartPoint,
const EDA_ANGLE aCenterAngle,
int  aWidth = 0 
)

Construct and arc using center, start, angle.

Center and angle are used to calculate the mid and end points of the arc, and are not stored.

Parameters
aArcCenteris the arc center.
aArcStartPointis the arc start point.
aCenterAngleis the arc angle.
aWidthis the arc line thickness.

Definition at line 43 of file shape_arc.cpp.

44 :
45 SHAPE( SH_ARC ),
46 m_width( aWidth )
47{
48 m_start = aArcStartPoint;
49
50 VECTOR2D mid = aArcStartPoint;
51 VECTOR2D end = aArcStartPoint;
52 VECTOR2D center = aArcCenter;
53
54 RotatePoint( mid, center, -aCenterAngle / 2.0 );
55 RotatePoint( end, center, -aCenterAngle );
56
57 m_mid = VECTOR2I( KiROUND( mid.x ), KiROUND( mid.y ) );
58 m_end = VECTOR2I( KiROUND( end.x ), KiROUND( end.y ) );
59
61}
VECTOR2I m_mid
Definition: shape_arc.h:260
VECTOR2I m_end
Definition: shape_arc.h:261
void update_bbox()
Definition: shape_arc.cpp:313
VECTOR2I m_start
Definition: shape_arc.h:259
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
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:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590

References KiROUND(), m_end, m_mid, m_start, RotatePoint(), update_bbox(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ SHAPE_ARC() [3/5]

SHAPE_ARC::SHAPE_ARC ( const VECTOR2I aArcStart,
const VECTOR2I aArcMid,
const VECTOR2I aArcEnd,
int  aWidth 
)
Parameters
aArcStartis the arc start point.
aArcEndis the arc end point.
aArcMidis the arc mid point.
aWidthis the arc line thickness.

Definition at line 64 of file shape_arc.cpp.

65 :
66 SHAPE( SH_ARC ),
67 m_start( aArcStart ),
68 m_mid( aArcMid ),
69 m_end( aArcEnd ),
70 m_width( aWidth )
71{
73}

References update_bbox().

◆ SHAPE_ARC() [4/5]

SHAPE_ARC::SHAPE_ARC ( const SEG aSegmentA,
const SEG aSegmentB,
int  aRadius,
int  aWidth = 0 
)

Build a SHAPE_ARC which is tangent to two segments and a given radius.

Parameters
aSegmentAis the first segment
aSegmentBis the second segment
aRadiusis the arc radius
aWidthis the arc line thickness

Definition at line 76 of file shape_arc.cpp.

76 :
77 SHAPE( SH_ARC )
78{
79 m_width = aWidth;
80
81 /*
82 * Construct an arc that is tangent to two segments with a given radius.
83 *
84 * p
85 * A
86 * A \
87 * / \
88 * / . . \ segB
89 * /. .\
90 * segA / c \
91 * / B
92 * /
93 * /
94 * B
95 *
96 *
97 * segA is the fist segment (with its points A and B)
98 * segB is the second segment (with its points A and B)
99 * p is the point at which segA and segB would intersect if they were projected
100 * c is the centre of the arc to be constructed
101 * rad is the radius of the arc to be constructed
102 *
103 * We can create two vectors, between point p and segA /segB
104 * pToA = p - segA.B //< note that segA.A would also be valid as it is colinear
105 * pToB = p - segB.B //< note that segB.A would also be valid as it is colinear
106 *
107 * Let the angle formed by segA and segB be called 'alpha':
108 * alpha = angle( pToA ) - angle( pToB )
109 *
110 * The distance PC can be computed as
111 * distPC = rad / abs( sin( alpha / 2 ) )
112 *
113 * The polar angle of the vector PC can be computed as:
114 * anglePC = angle( pToA ) + alpha / 2
115 *
116 * Therefore:
117 * C.x = P.x + distPC*cos( anglePC )
118 * C.y = P.y + distPC*sin( anglePC )
119 */
120
121 OPT_VECTOR2I p = aSegmentA.Intersect( aSegmentB, true, true );
122
123 if( !p || aSegmentA.Length() == 0 || aSegmentB.Length() == 0 )
124 {
125 // Catch bugs in debug
126 wxASSERT_MSG( false, "The input segments do not intersect or one is zero length." );
127
128 // Make a 180 degree arc around aSegmentA in case we end up here in release
129 m_start = aSegmentA.A;
130 m_end = aSegmentA.B;
131 m_mid = m_start;
132
133 VECTOR2I arcCenter = aSegmentA.Center();
134 RotatePoint( m_mid, arcCenter, ANGLE_90 ); // mid point at 90 degrees
135 }
136 else
137 {
138 VECTOR2I pToA = aSegmentA.B - *p;
139 VECTOR2I pToB = aSegmentB.B - *p;
140
141 if( pToA.EuclideanNorm() == 0 )
142 pToA = aSegmentA.A - *p;
143
144 if( pToB.EuclideanNorm() == 0 )
145 pToB = aSegmentB.A - *p;
146
147 EDA_ANGLE pToAangle( pToA );
148 EDA_ANGLE pToBangle( pToB );
149
150 EDA_ANGLE alpha = ( pToAangle - pToBangle ).Normalize180();
151
152 double distPC = (double) aRadius / abs( sin( alpha.AsRadians() / 2 ) );
153 EDA_ANGLE angPC = pToAangle - alpha / 2;
154 VECTOR2I arcCenter;
155
156 arcCenter.x = p->x + KiROUND( distPC * angPC.Cos() );
157 arcCenter.y = p->y + KiROUND( distPC * angPC.Sin() );
158
159 // The end points of the arc are the orthogonal projected lines from the line segments
160 // to the center of the arc
161 m_start = aSegmentA.LineProject( arcCenter );
162 m_end = aSegmentB.LineProject( arcCenter );
163
164 //The mid point is rotated start point around center, half the angle of the arc.
165 VECTOR2I startVector = m_start - arcCenter;
166 VECTOR2I endVector = m_end - arcCenter;
167
168 EDA_ANGLE startAngle( startVector );
169 EDA_ANGLE endAngle( endVector );
170 EDA_ANGLE midPointRotAngle = ( startAngle - endAngle ).Normalize180() / 2;
171
172 m_mid = m_start;
173 RotatePoint( m_mid, arcCenter, midPointRotAngle );
174 }
175
176 update_bbox();
177}
double Sin() const
Definition: eda_angle.h:206
double AsRadians() const
Definition: eda_angle.h:153
double Cos() const
Definition: eda_angle.h:221
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
int Length() const
Return the length (this).
Definition: seg.h:326
OPT_VECTOR2I Intersect(const SEG &aSeg, bool aIgnoreEndpoints=false, bool aLines=false) const
Compute intersection point of segment (this) with segment aSeg.
Definition: seg.cpp:196
VECTOR2I Center() const
Definition: seg.h:362
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.cpp:312
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:265
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
std::optional< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:39

References SEG::A, std::abs(), ANGLE_90, EDA_ANGLE::AsRadians(), SEG::B, SEG::Center(), EDA_ANGLE::Cos(), VECTOR2< T >::EuclideanNorm(), SEG::Intersect(), KiROUND(), SEG::Length(), SEG::LineProject(), m_end, m_mid, m_start, m_width, RotatePoint(), EDA_ANGLE::Sin(), update_bbox(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ SHAPE_ARC() [5/5]

SHAPE_ARC::SHAPE_ARC ( const SHAPE_ARC aOther)

Definition at line 180 of file shape_arc.cpp.

181 : SHAPE( SH_ARC )
182{
183 m_start = aOther.m_start;
184 m_end = aOther.m_end;
185 m_mid = aOther.m_mid;
186 m_width = aOther.m_width;
187 m_bbox = aOther.m_bbox;
188}
BOX2I m_bbox
Definition: shape_arc.h:264

References m_bbox, m_end, m_mid, m_start, and m_width.

◆ ~SHAPE_ARC()

virtual SHAPE_ARC::~SHAPE_ARC ( )
inlinevirtual

Definition at line 80 of file shape_arc.h.

80{}

Member Function Documentation

◆ BBox()

const BOX2I SHAPE_ARC::BBox ( int  aClearance = 0) const
overridevirtual

Compute a bounding box of the shape, with a margin of aClearance a collision.

Parameters
aClearancehow much the bounding box is expanded wrs to the minimum enclosing rectangle for the shape.
Returns
the bounding box.

Implements SHAPE.

Definition at line 355 of file shape_arc.cpp.

356{
357 BOX2I bbox( m_bbox );
358
359 if( aClearance != 0 )
360 bbox.Inflate( aClearance );
361
362 return bbox;
363}

References BOX2< Vec >::Inflate(), and m_bbox.

Referenced by BOOST_AUTO_TEST_CASE(), CheckArcGeom(), Collide(), drawShapes(), GERBER_DRAW_ITEM::GetBoundingBox(), and playground_main_func().

◆ CalcShape()

SGNODE * SHAPE::CalcShape ( SGNODE aParent,
SGNODE aColor,
WRL1_ORDER  aVertexOrder,
float  aCreaseLimit = 0.74317,
bool  isVRML2 = false 
)
inherited

Definition at line 703 of file wrlfacet.cpp.

705{
706 if( facets.empty() || !facets.front()->HasMinPoints() )
707 return nullptr;
708
709 std::vector< std::list< FACET* > > flist;
710
711 // determine the max. index and size flist as appropriate
712 std::list< FACET* >::iterator sF = facets.begin();
713 std::list< FACET* >::iterator eF = facets.end();
714
715 int maxIdx = 0;
716 int tmi;
717 float maxV = 0.0;
718 float tV = 0.0;
719
720 while( sF != eF )
721 {
722 tV = ( *sF )->CalcFaceNormal();
723 tmi = ( *sF )->GetMaxIndex();
724
725 if( tmi > maxIdx )
726 maxIdx = tmi;
727
728 if( tV > maxV )
729 maxV = tV;
730
731 ++sF;
732 }
733
734 ++maxIdx;
735
736 if( maxIdx < 3 )
737 return nullptr;
738
739 flist.resize( maxIdx );
740
741 // create the lists of facets common to indices
742 sF = facets.begin();
743
744 while( sF != eF )
745 {
746 ( *sF )->Renormalize( tV );
747 ( *sF )->CollectVertices( flist );
748 ++sF;
749 }
750
751 // calculate the normals
752 size_t vs = flist.size();
753
754 for( size_t i = 0; i < vs; ++i )
755 {
756 sF = flist[i].begin();
757 eF = flist[i].end();
758
759 while( sF != eF )
760 {
761 ( *sF )->CalcVertexNormal( static_cast<int>( i ), flist[i], aCreaseLimit );
762 ++sF;
763 }
764 }
765
766 std::vector< WRLVEC3F > vertices;
767 std::vector< WRLVEC3F > normals;
768 std::vector< SGCOLOR > colors;
769
770 // push the facet data to the final output list
771 sF = facets.begin();
772 eF = facets.end();
773
774 while( sF != eF )
775 {
776 ( *sF )->GetData( vertices, normals, colors, aVertexOrder );
777 ++sF;
778 }
779
780 flist.clear();
781
782 if( vertices.size() < 3 )
783 return nullptr;
784
785 IFSG_SHAPE shapeNode( false );
786
787 if( !isVRML2 )
788 {
789 shapeNode.NewNode( aParent );
790
791 if( aColor )
792 {
793 if( nullptr == S3D::GetSGNodeParent( aColor ) )
794 shapeNode.AddChildNode( aColor );
795 else
796 shapeNode.AddRefNode( aColor );
797 }
798 }
799
800 std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format
801 std::vector< SGVECTOR > lCNorm; // per-vertex normals
802 vs = vertices.size();
803
804 for( size_t i = 0; i < vs; ++i )
805 {
806 SGPOINT pt;
807 pt.x = vertices[i].x;
808 pt.y = vertices[i].y;
809 pt.z = vertices[i].z;
810 lCPts.push_back( pt );
811 lCNorm.emplace_back( normals[i].x, normals[i].y, normals[i].z );
812 }
813
814 vertices.clear();
815 normals.clear();
816
817 IFSG_FACESET fsNode( false );
818
819 if( !isVRML2 )
820 fsNode.NewNode( shapeNode );
821 else
822 fsNode.NewNode( aParent );
823
824 IFSG_COORDS cpNode( fsNode );
825 cpNode.SetCoordsList( lCPts.size(), &lCPts[0] );
826 IFSG_COORDINDEX ciNode( fsNode );
827
828 for( int i = 0; i < (int)lCPts.size(); ++i )
829 ciNode.AddIndex( i );
830
831 IFSG_NORMALS nmNode( fsNode );
832 nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
833
834 if( !colors.empty() )
835 {
836 IFSG_COLORS nmColor( fsNode );
837 nmColor.SetColorList( colors.size(), &colors[0] );
838 colors.clear();
839 }
840
841 if( !isVRML2 )
842 return shapeNode.GetRawPtr();
843
844 return fsNode.GetRawPtr();
845}
IFSG_COLORS is the wrapper for SGCOLORS.
Definition: ifsg_colors.h:42
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:41
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:41
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:41
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:41
double z
Definition: sg_base.h:72
double x
Definition: sg_base.h:70
double y
Definition: sg_base.h:71
std::list< FACET * > facets
Definition: wrlfacet.h:143
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:494

References IFSG_NODE::AddChildNode(), IFSG_INDEX::AddIndex(), IFSG_NODE::AddRefNode(), SHAPE::facets, IFSG_NODE::GetRawPtr(), S3D::GetSGNodeParent(), IFSG_FACESET::NewNode(), IFSG_SHAPE::NewNode(), IFSG_COLORS::SetColorList(), IFSG_COORDS::SetCoordsList(), IFSG_NORMALS::SetNormalList(), SGPOINT::x, SGPOINT::y, and SGPOINT::z.

Referenced by WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ ccw()

bool SHAPE_ARC::ccw ( const VECTOR2I aA,
const VECTOR2I aB,
const VECTOR2I aC 
) const
inlineprivate

Definition at line 248 of file shape_arc.h.

249 {
250 return ( ecoord{ aC.y } - aA.y ) * ( ecoord{ aB.x } - aA.x ) >
251 ( ecoord{ aB.y } - aA.y ) * ( ecoord{ aC.x } - aA.x );
252 }
VECTOR2I::extended_type ecoord

References VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Collide().

◆ Centre()

virtual VECTOR2I SHAPE::Centre ( ) const
inlinevirtualinherited

Compute a center-of-mass of the shape.

Returns
the center-of-mass point

Definition at line 230 of file shape.h.

231 {
232 return BBox( 0 ).Centre(); // if nothing better is available....
233 }
Vec Centre() const
Definition: box2.h:70
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.

References SHAPE::BBox(), and BOX2< Vec >::Centre().

Referenced by Collide().

◆ Clone()

SHAPE * SHAPE_ARC::Clone ( ) const
inlineoverridevirtual

Return a dynamically allocated copy of the shape.

Return values
copyof the shape

Reimplemented from SHAPE.

Definition at line 82 of file shape_arc.h.

83 {
84 return new SHAPE_ARC( *this );
85 }
SHAPE_ARC()
Definition: shape_arc.h:40

References SHAPE_ARC().

Referenced by CheckArc().

◆ Collide() [1/4]

bool SHAPE_ARC::Collide ( const SEG aSeg,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtual

Check if the boundary of shape (this) lies closer to the segment aSeg than aClearance, indicating a collision.

Parameters
aActual[out] an optional pointer to an int to be updated with the actual distance int the event of a collision.
aLocation[out] an option pointer to a point to store a nearby location in the event of a collision.
Returns
true, if there is a collision.

Implements SHAPE.

Definition at line 241 of file shape_arc.cpp.

242{
243 if( aSeg.A == aSeg.B )
244 return Collide( aSeg.A, aClearance, aActual, aLocation );
245
246 VECTOR2I center = GetCenter();
247 CIRCLE circle( center, GetRadius() );
248
249 // Possible points of the collision are:
250 // 1. Intersetion of the segment with the full circle
251 // 2. Closest point on the segment to the center of the circle
252 // 3. Closest point on the segment to the end points of the arc
253 // 4. End points of the segment
254
255 std::vector<VECTOR2I> candidatePts = circle.Intersect( aSeg );
256
257 candidatePts.push_back( aSeg.NearestPoint( center ) );
258 candidatePts.push_back( aSeg.NearestPoint( m_start ) );
259 candidatePts.push_back( aSeg.NearestPoint( m_end ) );
260 candidatePts.push_back( aSeg.A );
261 candidatePts.push_back( aSeg.B );
262
263 for( const VECTOR2I& candidate : candidatePts )
264 {
265 if( Collide( candidate, aClearance, aActual, aLocation ) )
266 return true;
267 }
268
269 return false;
270}
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition: seg.cpp:269
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,...
Definition: shape_arc.cpp:241
double GetRadius() const
Definition: shape_arc.cpp:464
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:433

References SEG::A, SEG::B, Collide(), GetCenter(), GetRadius(), CIRCLE::Intersect(), m_end, m_start, and SEG::NearestPoint().

Referenced by BOOST_AUTO_TEST_CASE(), Collide(), Collide(), SHAPE_LINE_CHAIN::Collide(), drawShapes(), and GEOM_TEST::IsOutlineValid().

◆ Collide() [2/4]

bool SHAPE::Collide ( const SHAPE aShape,
int  aClearance,
VECTOR2I aMTV 
) const
virtualinherited

Check if the boundary of shape (this) lies closer to the shape aShape than aClearance, indicating a collision.

Parameters
aShapeshape to check collision against
aClearanceminimum clearance
aMTVminimum translation vector
aActual[out] an optional pointer to an int to store the actual distance in the event of a collision.
aLocation[out] an option pointer to a point to store a nearby location in the event of a collision.
Returns
true, if there is a collision.

Reimplemented in SHAPE_COMPOUND, SHAPE_RECT, and SHAPE_SEGMENT.

Definition at line 1109 of file shape_collisions.cpp.

1110{
1111 return collideShapes( this, aShape, aClearance, nullptr, nullptr, aMTV );
1112}
static bool collideShapes(const SHAPE *aA, const SHAPE *aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)

References collideShapes().

◆ Collide() [3/4]

bool SHAPE_ARC::Collide ( const SHAPE aShape,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
inlineoverridevirtual

Reimplemented from SHAPE.

Definition at line 125 of file shape_arc.h.

127 {
128 return SHAPE::Collide( aShape, aClearance, aActual, aLocation );
129 }
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
Definition: shape.h:179

References SHAPE::Collide().

◆ Collide() [4/4]

bool SHAPE_ARC::Collide ( const VECTOR2I aP,
int  aClearance = 0,
int *  aActual = nullptr,
VECTOR2I aLocation = nullptr 
) const
overridevirtual

Check if the boundary of shape (this) lies closer to the point aP than aClearance, indicating a collision.

Parameters
aActual[out] an optional pointer to an int to store the actual distance in the event of a collision.
aLocation[out] an option pointer to a point to store a nearby location in the event of a collision.
Returns
true, if there is a collision.

Reimplemented from SHAPE.

Definition at line 372 of file shape_arc.cpp.

374{
375 int minDist = aClearance + m_width / 2;
376 auto bbox = BBox( minDist );
377
378 // Fast check using bounding box:
379 if( !bbox.Contains( aP ) )
380 return false;
381
382 CIRCLE fullCircle( GetCenter(), GetRadius() );
383 VECTOR2I nearestPt = fullCircle.NearestPoint( aP );
384
385 int dist = ( nearestPt - aP ).EuclideanNorm();
386
387 // If not a 360 degree arc, need to use arc angles to decide if point collides
388 if( m_start != m_end )
389 {
390 bool ccw = GetCentralAngle() > ANGLE_0;
391 EDA_ANGLE angleToPt( aP - fullCircle.Center ); // Angle from center to the point
392 EDA_ANGLE rotatedPtAngle = ( angleToPt.Normalize() - GetStartAngle() ).Normalize();
393 EDA_ANGLE rotatedEndAngle = ( GetEndAngle() - GetStartAngle() ).Normalize();
394
395 if( ( ccw && rotatedPtAngle > rotatedEndAngle )
396 || ( !ccw && rotatedPtAngle < rotatedEndAngle ) )
397 {
398 int distStartpt = ( aP - m_start ).EuclideanNorm();
399 int distEndpt = ( aP - m_end ).EuclideanNorm();
400 dist = std::min( distStartpt, distEndpt );
401 }
402 }
403
404 if( dist <= minDist )
405 {
406 if( aLocation )
407 *aLocation = nearestPt;
408
409 if( aActual )
410 *aActual = std::max( 0, dist - m_width / 2 );
411
412 return true;
413 }
414
415 return false;
416}
EDA_ANGLE GetCentralAngle() const
Definition: shape_arc.cpp:448
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Definition: shape_arc.cpp:355
EDA_ANGLE GetEndAngle() const
Definition: shape_arc.cpp:426
EDA_ANGLE GetStartAngle() const
Definition: shape_arc.cpp:419
bool ccw(const VECTOR2I &aA, const VECTOR2I &aB, const VECTOR2I &aC) const
Definition: shape_arc.h:248
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:429
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129

References ANGLE_0, BBox(), ccw(), CIRCLE::Center, EuclideanNorm(), GetCenter(), GetCentralAngle(), GetEndAngle(), GetRadius(), GetStartAngle(), m_end, m_start, m_width, CIRCLE::NearestPoint(), and EDA_ANGLE::Normalize().

◆ ConstructFromStartEndAngle()

SHAPE_ARC & 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.

Parameters
aStartis the arc starting point
aEndis the arc endpoint
aAngleis the arc included angle
aWidthis the arc line thickness
Returns
this arc.

Definition at line 191 of file shape_arc.cpp.

193{
194 m_start = aStart;
195 m_mid = aStart;
196 m_end = aEnd;
197 m_width = aWidth;
198
199 VECTOR2I center( CalcArcCenter( aStart, aEnd, aAngle ) );
200
201 RotatePoint( m_mid, center, -aAngle / 2.0 );
202
203 update_bbox();
204
205 return *this;
206}
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.
Definition: trigo.cpp:458

References CalcArcCenter(), m_end, m_mid, m_start, m_width, RotatePoint(), and update_bbox().

Referenced by DIRECTION_45::BuildInitialTrace(), SCH_EAGLE_PLUGIN::loadPolyLine(), and SCH_EAGLE_PLUGIN::loadSymbolPolyLine().

◆ ConstructFromStartEndCenter()

SHAPE_ARC & 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.

Parameters
aStartis the arc starting point
aEndis the arc endpoint
aCenteris the arc center
aClockwisedetermines which of the two solutions to construct
aWidthis the arc line thickness
Returns
*this

Definition at line 209 of file shape_arc.cpp.

212{
213 VECTOR2I startLine = aStart - aCenter;
214 VECTOR2I endLine = aEnd - aCenter;
215
216 EDA_ANGLE startAngle( startLine );
217 EDA_ANGLE endAngle( endLine );
218
219 startAngle.Normalize();
220 endAngle.Normalize();
221
222 EDA_ANGLE angle = endAngle - startAngle;
223
224 if( aClockwise )
225 angle = angle.Normalize() - ANGLE_360;
226 else
227 angle = angle.Normalize();
228
229 m_start = aStart;
230 m_end = aEnd;
231 m_mid = aStart;
232
233 RotatePoint( m_mid, aCenter, -angle / 2.0 );
234
235 update_bbox();
236
237 return *this;
238}
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:435
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), ANGLE_360, m_end, m_mid, m_start, EDA_ANGLE::Normalize(), RotatePoint(), and update_bbox().

Referenced by SHAPE_LINE_CHAIN::amendArc(), BOOST_AUTO_TEST_CASE(), CADSTAR_ARCHIVE_PARSER::VERTEX::BuildArc(), DIRECTION_45::BuildInitialTrace(), SHAPE_LINE_CHAIN::Slice(), and SHAPE_LINE_CHAIN::splitArc().

◆ ConvertToPolyline()

const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline ( double  aAccuracy = DefaultAccuracyForPCB(),
double *  aEffectiveAccuracy = nullptr 
) const

Construct a SHAPE_LINE_CHAIN of segments from a given arc.

Note
The default is ARC_HIGH_DEF in Pcbnew units. This is to allow common geometry collision functions. Other programs should call this using explicit accuracy values.
Todo:
Unify KiCad internal units.
Parameters
aAccuracymaximum divergence from true arc given in internal units.
aEffectiveAccuracyis the actual divergence from true arc given. the approximation error is between -aEffectiveAccuracy/2 and +aEffectiveAccuracy/2 in internal units
Returns
a SHAPE_LINE_CHAIN.

Definition at line 470 of file shape_arc.cpp.

472{
474 double r = GetRadius();
476 VECTOR2I c = GetCenter();
478
479 int n;
480
481 // To calculate the arc to segment count, use the external radius instead of the radius.
482 // for a arc with small radius and large width, the difference can be significant
483 double external_radius = r+(m_width/2);
484 double effectiveAccuracy;
485
486 if( external_radius < aAccuracy/2 ) // Should be a very rare case
487 {
488 // In this case, the arc is approximated by one segment, with a effective error
489 // between -aAccuracy/2 and +aAccuracy/2, as expected.
490 n = 0;
491 effectiveAccuracy = external_radius;
492 }
493 else
494 {
495 n = GetArcToSegmentCount( external_radius, aAccuracy, ca );
496
497 // Recalculate the effective error of approximation, that can be < aAccuracy
498 int seg360 = n * 360.0 / fabs( ca.AsDegrees() );
499 effectiveAccuracy = CircleToEndSegmentDeltaRadius( external_radius, seg360 );
500 }
501
502 // Split the error on either side of the arc. Since we want the start and end points
503 // to be exactly on the arc, the first and last segments need to be shorter to stay within
504 // the error band (since segments normally start 1/2 the error band outside the arc).
505 r += effectiveAccuracy / 2;
506 n = n * 2;
507
508 rv.Append( m_start );
509
510 for( int i = 1; i < n ; i += 2 )
511 {
512 EDA_ANGLE a = sa;
513
514 if( n != 0 )
515 a += ( ca * i ) / n;
516
517 double x = c.x + r * a.Cos();
518 double y = c.y + r * a.Sin();
519
520 rv.Append( KiROUND( x ), KiROUND( y ) );
521 }
522
523 rv.Append( m_end );
524
525 if( aEffectiveAccuracy )
526 *aEffectiveAccuracy = effectiveAccuracy;
527
528 return rv;
529}
double AsDegrees() const
Definition: eda_angle.h:149
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.
int CircleToEndSegmentDeltaRadius(int aInnerCircleRadius, int aSegCount)
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)

References SHAPE_LINE_CHAIN::Append(), EDA_ANGLE::AsDegrees(), CircleToEndSegmentDeltaRadius(), EDA_ANGLE::Cos(), GetArcToSegmentCount(), GetCenter(), GetCentralAngle(), GetRadius(), GetStartAngle(), KiROUND(), m_end, m_start, m_width, EDA_ANGLE::Sin(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SHAPE_LINE_CHAIN::Append(), PNS::ArcHull(), BOARD_ADAPTER::createPadWithMargin(), KIGFX::PCB_PAINTER::draw(), TEARDROP_MANAGER::findAnchorPointsOnTrack(), SHAPE_LINE_CHAIN::Insert(), and SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN().

◆ DefaultAccuracyForPCB()

static double SHAPE_ARC::DefaultAccuracyForPCB ( )
inlinestatic
Note
The default is ARC_HIGH_DEF in Pcbnew units. This is to allow common geometry collision functions. Other programs should call this using explicit accuracy values.
Todo:
Unify KiCad internal units.
Returns
a default accuracy value for ConvertToPolyline() to build the polyline.

Definition at line 221 of file shape_arc.h.

221{ return 0.005 * PCB_IU_PER_MM; }
constexpr double PCB_IU_PER_MM
Definition: base_units.h:71

References PCB_IU_PER_MM.

Referenced by SHAPE_LINE_CHAIN::Append(), PNS::ArcHull(), BOOST_AUTO_TEST_CASE(), GEOM_TEST::IsOutlineValid(), and PNS::SHOVE::ShoveObstacleLine().

◆ Format()

const std::string SHAPE::Format ( bool  aCplusPlus = true) const
virtualinherited

Reimplemented in SHAPE_CIRCLE, SHAPE_COMPOUND, SHAPE_LINE_CHAIN, SHAPE_POLY_SET, SHAPE_RECT, and SHAPE_SEGMENT.

Definition at line 41 of file shape.cpp.

42{
43 std::stringstream ss;
44 ss << "shape " << m_type;
45 return ss.str();
46}
SHAPE_TYPE m_type
< type of our shape
Definition: shape.h:117

References SHAPE_BASE::m_type.

Referenced by SHAPE_CIRCLE::Format(), SHAPE_SEGMENT::Format(), and SHAPE_FILE_IO::Write().

◆ GetArcMid()

◆ GetCenter()

◆ GetCentralAngle()

EDA_ANGLE SHAPE_ARC::GetCentralAngle ( ) const
Returns
the central angle of the arc shape, normalized between 0..360 deg.

Definition at line 448 of file shape_arc.cpp.

449{
450 // Arcs with same start and end points can be 0 deg or 360 deg arcs.
451 // However, they are expected to be circles.
452 // So return 360 degrees as central arc:
453 if( m_start == m_end )
454 return ANGLE_360;
455
456 VECTOR2I center = GetCenter();
457 EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
458 EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
459
460 return angle1.Normalize180() + angle2.Normalize180();
461}
EDA_ANGLE Normalize180()
Definition: eda_angle.h:288

References ANGLE_360, GetCenter(), m_end, m_mid, m_start, and EDA_ANGLE::Normalize180().

Referenced by PNS_LOG_VIEWER_OVERLAY::Arc(), CheckArcGeom(), Collide(), ConvertToPolyline(), ROUTER_PREVIEW_ITEM::drawLineChain(), ROUTER_PREVIEW_ITEM::drawShape(), GetLength(), IsClockwise(), sliceContainsPoint(), TransformArcToPolygon(), and update_bbox().

◆ GetChord()

SEG SHAPE_ARC::GetChord ( ) const
inline

Definition at line 187 of file shape_arc.h.

188 {
189 return SEG( m_start, m_end );
190 }
Definition: seg.h:42

References m_end, and m_start.

Referenced by CheckArcGeom().

◆ GetClearance()

int SHAPE::GetClearance ( const SHAPE aOther) const
inherited

Return the actual minimum distance between two shapes.

Return values
distancein IU

Definition at line 49 of file shape.cpp.

50{
51 int actual_clearance = std::numeric_limits<int>::max();
52 std::vector<const SHAPE*> a_shapes;
53 std::vector<const SHAPE*> b_shapes;
54
55 GetIndexableSubshapes( a_shapes );
56 aOther->GetIndexableSubshapes( b_shapes );
57
58 if( GetIndexableSubshapeCount() == 0 )
59 a_shapes.push_back( this );
60
61 if( aOther->GetIndexableSubshapeCount() == 0 )
62 b_shapes.push_back( aOther );
63
64 for( const SHAPE* a : a_shapes )
65 {
66 for( const SHAPE* b : b_shapes )
67 {
68 int temp_dist = 0;
69 a->Collide( b, std::numeric_limits<int>::max() / 2, &temp_dist );
70
71 if( temp_dist < actual_clearance )
72 actual_clearance = temp_dist;
73 }
74 }
75
76 return actual_clearance;
77}
virtual size_t GetIndexableSubshapeCount() const
Definition: shape.h:111
virtual void GetIndexableSubshapes(std::vector< const SHAPE * > &aSubshapes) const
Definition: shape.h:113
An abstract shape on 2D plane.
Definition: shape.h:124

References SHAPE_BASE::GetIndexableSubshapeCount(), and SHAPE_BASE::GetIndexableSubshapes().

◆ GetEndAngle()

EDA_ANGLE SHAPE_ARC::GetEndAngle ( ) const
Returns
the end angle of the arc shape, normalized between 0..360 deg.

Definition at line 426 of file shape_arc.cpp.

427{
429 return angle.Normalize();
430}

References PNS::angle(), GetCenter(), and m_end.

Referenced by CheckArcGeom(), and Collide().

◆ GetIndexableSubshapeCount()

virtual size_t SHAPE_BASE::GetIndexableSubshapeCount ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_COMPOUND, and SHAPE_POLY_SET.

Definition at line 111 of file shape.h.

111{ return 0; }

Referenced by SHAPE::GetClearance().

◆ GetIndexableSubshapes()

virtual void SHAPE_BASE::GetIndexableSubshapes ( std::vector< const SHAPE * > &  aSubshapes) const
inlinevirtualinherited

Reimplemented in SHAPE_COMPOUND, and SHAPE_POLY_SET.

Definition at line 113 of file shape.h.

113{ }

Referenced by SHAPE_COMPOUND::AddShape(), SHAPE::GetClearance(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ GetLength()

double SHAPE_ARC::GetLength ( ) const
Returns
the length of the arc shape.

Definition at line 439 of file shape_arc.cpp.

440{
441 double radius = GetRadius();
442 EDA_ANGLE includedAngle = GetCentralAngle();
443
444 return std::abs( radius * includedAngle.AsRadians() );
445}

References std::abs(), EDA_ANGLE::AsRadians(), GetCentralAngle(), and GetRadius().

◆ GetP0()

◆ GetP1()

◆ GetRadius()

◆ GetStartAngle()

EDA_ANGLE SHAPE_ARC::GetStartAngle ( ) const
Returns
the start angle of the arc shape, normalized between 0..360 deg.

Definition at line 419 of file shape_arc.cpp.

420{
422 return angle.Normalize();
423}

References PNS::angle(), GetCenter(), and m_start.

Referenced by PNS_LOG_VIEWER_OVERLAY::Arc(), CheckArcGeom(), Collide(), ConvertToPolyline(), ROUTER_PREVIEW_ITEM::drawLineChain(), ROUTER_PREVIEW_ITEM::drawShape(), sliceContainsPoint(), TransformArcToPolygon(), and update_bbox().

◆ GetWidth()

◆ HasIndexableSubshapes()

virtual bool SHAPE_BASE::HasIndexableSubshapes ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_COMPOUND, and SHAPE_POLY_SET.

Definition at line 106 of file shape.h.

107 {
108 return false;
109 }

Referenced by SHAPE_COMPOUND::AddShape(), and ROUTER_PREVIEW_ITEM::ViewDraw().

◆ Intersect()

int SHAPE_ARC::Intersect ( const SHAPE_ARC aArc,
std::vector< VECTOR2I > *  aIpsBuffer 
) const

Find intersection points between this arc and aArc.

Ignores arc width.

Parameters
aSeg
aIpsBufferBuffer to store the resulting intersection points (if any)
Returns
Number of intersection points found

Definition at line 294 of file shape_arc.cpp.

295{
296 CIRCLE thiscirc( GetCenter(), GetRadius() );
297 CIRCLE othercirc( aArc.GetCenter(), aArc.GetRadius() );
298
299 std::vector<VECTOR2I> intersections = thiscirc.Intersect( othercirc );
300
301 size_t originalSize = aIpsBuffer->size();
302
303 for( const VECTOR2I& intersection : intersections )
304 {
305 if( sliceContainsPoint( intersection ) && aArc.sliceContainsPoint( intersection ) )
306 aIpsBuffer->push_back( intersection );
307 }
308
309 return aIpsBuffer->size() - originalSize;
310}
bool sliceContainsPoint(const VECTOR2I &p) const
Definition: shape_arc.cpp:593

References GetCenter(), GetRadius(), CIRCLE::Intersect(), and sliceContainsPoint().

Referenced by Collide(), and collideArc2Arc().

◆ IntersectLine()

int SHAPE_ARC::IntersectLine ( const SEG aSeg,
std::vector< VECTOR2I > *  aIpsBuffer 
) const

Find intersection points between this arc and aSeg, treating aSeg as an infinite line.

Ignores arc width.

Parameters
aSegLine to intersect against (treated as an infinite line)
aIpsBufferBuffer to store the resulting intersection points (if any)
Returns
Number of intersection points found

Definition at line 273 of file shape_arc.cpp.

274{
275 if( aSeg.A == aSeg.B ) // One point does not define a line....
276 return 0;
277
278 CIRCLE circ( GetCenter(), GetRadius() );
279
280 std::vector<VECTOR2I> intersections = circ.IntersectLine( aSeg );
281
282 size_t originalSize = aIpsBuffer->size();
283
284 for( const VECTOR2I& intersection : intersections )
285 {
286 if( sliceContainsPoint( intersection ) )
287 aIpsBuffer->push_back( intersection );
288 }
289
290 return aIpsBuffer->size() - originalSize;
291}

References SEG::A, SEG::B, GetCenter(), GetRadius(), CIRCLE::IntersectLine(), and sliceContainsPoint().

Referenced by PCB_GRID_HELPER::AlignToArc(), Collide(), and collideArc2Arc().

◆ IsClockwise()

bool SHAPE_ARC::IsClockwise ( ) const

◆ IsNull()

bool SHAPE::IsNull ( ) const
inlineinherited

Return true if the shape is a null shape.

Return values
trueif null :-)

Definition at line 164 of file shape.h.

165 {
166 return m_type == SH_NULL;
167 }
@ SH_NULL
empty shape (no shape...),
Definition: shape.h:53

References SHAPE_BASE::m_type, and SH_NULL.

◆ IsSolid()

bool SHAPE_ARC::IsSolid ( ) const
inlineoverridevirtual

Implements SHAPE.

Definition at line 162 of file shape_arc.h.

163 {
164 return true;
165 }

Referenced by CheckArcGeom().

◆ Mirror() [1/2]

void SHAPE_ARC::Mirror ( bool  aX = true,
bool  aY = false,
const VECTOR2I aVector = { 0, 0 } 
)

Definition at line 551 of file shape_arc.cpp.

552{
553 if( aX )
554 {
555 m_start.x = -m_start.x + 2 * aVector.x;
556 m_end.x = -m_end.x + 2 * aVector.x;
557 m_mid.x = -m_mid.x + 2 * aVector.x;
558 }
559
560 if( aY )
561 {
562 m_start.y = -m_start.y + 2 * aVector.y;
563 m_end.y = -m_end.y + 2 * aVector.y;
564 m_mid.y = -m_mid.y + 2 * aVector.y;
565 }
566
567 update_bbox();
568}

References m_end, m_mid, m_start, update_bbox(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ Mirror() [2/2]

void SHAPE_ARC::Mirror ( const SEG axis)

Definition at line 571 of file shape_arc.cpp.

572{
573 m_start = axis.ReflectPoint( m_start );
574 m_end = axis.ReflectPoint( m_end );
575 m_mid = axis.ReflectPoint( m_mid );
576
577 update_bbox();
578}
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition: seg.cpp:291

References m_end, m_mid, m_start, SEG::ReflectPoint(), and update_bbox().

◆ Move()

void SHAPE_ARC::Move ( const VECTOR2I aVector)
overridevirtual

Implements SHAPE.

Definition at line 532 of file shape_arc.cpp.

533{
534 m_start += aVector;
535 m_end += aVector;
536 m_mid += aVector;
537 update_bbox();
538}

References m_end, m_mid, m_start, and update_bbox().

Referenced by PNS::COMPONENT_DRAGGER::Drag().

◆ NewFacet()

FACET * SHAPE::NewFacet ( )
inherited

Definition at line 695 of file wrlfacet.cpp.

696{
697 FACET* fp = new FACET;
698 facets.push_back( fp );
699 return fp;
700}
Definition: wrlfacet.h:43

References SHAPE::facets.

Referenced by WRL2FACESET::TranslateToSG(), X3DIFACESET::TranslateToSG(), and WRL1FACESET::TranslateToSG().

◆ operator==()

bool SHAPE_ARC::operator== ( SHAPE_ARC const &  aArc) const
inline

Definition at line 241 of file shape_arc.h.

242 {
243 return ( aArc.m_start == m_start ) && ( aArc.m_end == m_end ) && ( aArc.m_mid == m_mid )
244 && ( aArc.m_width == m_width );
245 }

References m_end, m_mid, m_start, and m_width.

◆ Parse()

bool SHAPE::Parse ( std::stringstream &  aStream)
virtualinherited

Reimplemented in SHAPE_LINE_CHAIN, and SHAPE_POLY_SET.

Definition at line 34 of file shape.cpp.

35{
36 assert( false );
37 return false;
38}

◆ Reverse()

◆ Reversed()

SHAPE_ARC SHAPE_ARC::Reversed ( ) const

◆ Rotate()

void SHAPE_ARC::Rotate ( const EDA_ANGLE aAngle,
const VECTOR2I aCenter 
)
overridevirtual

Rotate the arc by a given angle about a point.

Parameters
aCenteris the rotation center.
aAnglerotation angle.

Implements SHAPE.

Definition at line 541 of file shape_arc.cpp.

542{
543 RotatePoint( m_start, aCenter, aAngle );
544 RotatePoint( m_end, aCenter, aAngle );
545 RotatePoint( m_mid, aCenter, aAngle );
546
547 update_bbox();
548}

References m_end, m_mid, m_start, RotatePoint(), and update_bbox().

◆ SetWidth()

void SHAPE_ARC::SetWidth ( int  aWidth)
inline

Definition at line 152 of file shape_arc.h.

153 {
154 m_width = aWidth;
155 }

References m_width.

Referenced by BOOST_AUTO_TEST_CASE(), SHAPE_LINE_CHAIN::Insert(), and PNS::ARC::SetWidth().

◆ sliceContainsPoint()

bool SHAPE_ARC::sliceContainsPoint ( const VECTOR2I p) const
private

Definition at line 593 of file shape_arc.cpp.

594{
595 VECTOR2I center = GetCenter();
596 EDA_ANGLE phi( p - center );
599 EDA_ANGLE ea;
600
601 if( ca >= ANGLE_0 )
602 {
603 ea = sa + ca;
604 }
605 else
606 {
607 ea = sa;
608 sa += ca;
609 }
610
611 return alg::within_wrapped_range( phi.AsDegrees(), sa.AsDegrees(), ea.AsDegrees(), 360.0 );
612}
bool within_wrapped_range(T __val, T __minval, T __maxval, T __wrap)
Test if __val lies within __minval and __maxval in a wrapped range.
Definition: kicad_algo.h:128

References ANGLE_0, EDA_ANGLE::AsDegrees(), GetCenter(), GetCentralAngle(), GetStartAngle(), and alg::within_wrapped_range().

Referenced by Intersect(), and IntersectLine().

◆ Type()

◆ TypeName()

wxString SHAPE_BASE::TypeName ( ) const
inlineinherited

Definition at line 101 of file shape.h.

102 {
103 return SHAPE_TYPE_asString( m_type );
104 }
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
Definition: shape.h:57

References SHAPE_BASE::m_type, and SHAPE_TYPE_asString().

Referenced by Collide().

◆ update_bbox()

void SHAPE_ARC::update_bbox ( )
private

Definition at line 313 of file shape_arc.cpp.

314{
315 std::vector<VECTOR2I> points;
316 // Put start and end points in the point list
317 points.push_back( m_start );
318 points.push_back( m_end );
319
320 EDA_ANGLE start_angle = GetStartAngle();
321 EDA_ANGLE end_angle = start_angle + GetCentralAngle();
322
323 // we always count quadrants clockwise (increasing angle)
324 if( start_angle > end_angle )
325 std::swap( start_angle, end_angle );
326
327 int quad_angle_start = std::ceil( start_angle.AsDegrees() / 90.0 );
328 int quad_angle_end = std::floor( end_angle.AsDegrees() / 90.0 );
329
330 VECTOR2I center = GetCenter();
331 const int radius = KiROUND( GetRadius() );
332
333 // count through quadrants included in arc
334 for( int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle )
335 {
336 VECTOR2I quad_pt = center;
337
338 switch( quad_angle % 4 )
339 {
340 case 0: quad_pt += { radius, 0 }; break;
341 case 1: case -3: quad_pt += { 0, radius }; break;
342 case 2: case -2: quad_pt += { -radius, 0 }; break;
343 case 3: case -1: quad_pt += { 0, -radius }; break;
344 default:
345 assert( false );
346 }
347
348 points.push_back( quad_pt );
349 }
350
351 m_bbox.Compute( points );
352}
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:82

References EDA_ANGLE::AsDegrees(), BOX2< Vec >::Compute(), GetCenter(), GetCentralAngle(), GetRadius(), GetStartAngle(), KiROUND(), m_bbox, m_end, and m_start.

Referenced by ConstructFromStartEndAngle(), ConstructFromStartEndCenter(), Mirror(), Move(), Rotate(), and SHAPE_ARC().

Member Data Documentation

◆ facets

std::list< FACET* > SHAPE::facets
privateinherited

Definition at line 143 of file wrlfacet.h.

Referenced by SHAPE::CalcShape(), and SHAPE::NewFacet().

◆ m_bbox

BOX2I SHAPE_ARC::m_bbox
private

Definition at line 264 of file shape_arc.h.

Referenced by BBox(), SHAPE_ARC(), and update_bbox().

◆ m_end

◆ m_mid

◆ m_start

◆ m_type

SHAPE_TYPE SHAPE_BASE::m_type
protectedinherited

< type of our shape

Definition at line 117 of file shape.h.

Referenced by SHAPE::Format(), SHAPE::IsNull(), SHAPE_BASE::Type(), and SHAPE_BASE::TypeName().

◆ m_width

int SHAPE_ARC::m_width
private

◆ MIN_PRECISION_IU

const int SHAPE::MIN_PRECISION_IU = 4
staticinherited

This is the minimum precision for all the points in a shape.

Definition at line 129 of file shape.h.

Referenced by BOOST_AUTO_TEST_CASE(), DIRECTION_45::BuildInitialTrace(), CompareLength(), CIRCLE::Contains(), EDIT_TOOL::FilletTracks(), and CIRCLE::IntersectLine().


The documentation for this class was generated from the following files: