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, double 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, double 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 (double 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
 
double GetCentralAngle () const
 
double GetStartAngle () const
 
double 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
 
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 () 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...
 
virtual bool HasIndexableSubshapes () const
 
virtual size_t GetIndexableSubshapeCount () const
 
virtual void GetIndexableSubshapes (std::vector< SHAPE * > &aSubshapes)
 

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
 

Detailed Description

Definition at line 35 of file shape_arc.h.

Member Typedef Documentation

◆ ecoord

typedef VECTOR2I::extended_type SHAPE::ecoord
protectedinherited

Definition at line 236 of file shape.h.

Constructor & Destructor Documentation

◆ SHAPE_ARC() [1/5]

SHAPE_ARC::SHAPE_ARC ( )
inline

Definition at line 39 of file shape_arc.h.

39  :
40  SHAPE( SH_ARC ),
41  m_width( 0 )
42  {};
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
circular arc
Definition: shape.h:50
int m_width
Definition: shape_arc.h:262

Referenced by Clone(), and Reversed().

◆ SHAPE_ARC() [2/5]

SHAPE_ARC::SHAPE_ARC ( const VECTOR2I aArcCenter,
const VECTOR2I aArcStartPoint,
double  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 in degrees.
aWidthis the arc line thickness.

Definition at line 43 of file shape_arc.cpp.

44  :
45  SHAPE( SH_ARC ), m_width( aWidth )
46 {
47  m_start = aArcStartPoint;
48  m_mid = aArcStartPoint;
49  m_end = aArcStartPoint;
50 
51  RotatePoint( m_mid, aArcCenter, -aCenterAngle * 10.0 / 2.0 );
52  RotatePoint( m_end, aArcCenter, -aCenterAngle * 10.0 );
53 
54  update_bbox();
55 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
VECTOR2I m_end
Definition: shape_arc.h:260
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
VECTOR2I m_mid
Definition: shape_arc.h:259
circular arc
Definition: shape.h:50
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258
int m_width
Definition: shape_arc.h:262

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

◆ 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 58 of file shape_arc.cpp.

59  :
60  SHAPE( SH_ARC ), m_start( aArcStart ), m_mid( aArcMid ), m_end( aArcEnd ),
61  m_width( aWidth )
62 {
63  update_bbox();
64 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
circular arc
Definition: shape.h:50
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258
int m_width
Definition: shape_arc.h:262

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 67 of file shape_arc.cpp.

68  : SHAPE( SH_ARC )
69 {
70  m_width = aWidth;
71 
72  /*
73  * Construct an arc that is tangent to two segments with a given radius.
74  *
75  * p
76  * A
77  * A \
78  * / \
79  * / . . \ segB
80  * /. .\
81  * segA / c \
82  * / B
83  * /
84  * /
85  * B
86  *
87  *
88  * segA is the fist segment (with its points A and B)
89  * segB is the second segment (with its points A and B)
90  * p is the point at which segA and segB would intersect if they were projected
91  * c is the centre of the arc to be constructed
92  * rad is the radius of the arc to be constructed
93  *
94  * We can create two vectors, between point p and segA /segB
95  * pToA = p - segA.B //< note that segA.A would also be valid as it is colinear
96  * pToB = p - segB.B //< note that segB.A would also be valid as it is colinear
97  *
98  * Let the angle formed by segA and segB be called 'alpha':
99  * alpha = angle( pToA ) - angle( pToB )
100  *
101  * The distance PC can be computed as
102  * distPC = rad / abs( sin( alpha / 2 ) )
103  *
104  * The polar angle of the vector PC can be computed as:
105  * anglePC = angle( pToA ) + alpha / 2
106  *
107  * Therefore:
108  * C.x = P.x + distPC*cos( anglePC )
109  * C.y = P.y + distPC*sin( anglePC )
110  */
111 
112  OPT_VECTOR2I p = aSegmentA.Intersect( aSegmentB, true, true );
113 
114  if( !p || aSegmentA.Length() == 0 || aSegmentB.Length() == 0 )
115  {
116  // Catch bugs in debug
117  wxASSERT_MSG( false, "The input segments do not intersect or one is zero length." );
118 
119  // Make a 180 degree arc around aSegmentA in case we end up here in release
120  m_start = aSegmentA.A;
121  m_end = aSegmentA.B;
122  m_mid = m_start;
123 
124  VECTOR2I arcCenter = aSegmentA.Center();
125  RotatePoint( m_mid, arcCenter, 900.0 ); // mid point at 90 degrees
126  }
127  else
128  {
129  VECTOR2I pToA = aSegmentA.B - p.get();
130  VECTOR2I pToB = aSegmentB.B - p.get();
131 
132  if( pToA.EuclideanNorm() == 0 )
133  pToA = aSegmentA.A - p.get();
134 
135  if( pToB.EuclideanNorm() == 0 )
136  pToB = aSegmentB.A - p.get();
137 
138  double pToAangle = ArcTangente( pToA.y, pToA.x );
139  double pToBangle = ArcTangente( pToB.y, pToB.x );
140 
141  double alpha = NormalizeAngle180( pToAangle - pToBangle );
142 
143  double distPC = (double) aRadius / abs( sin( DECIDEG2RAD( alpha / 2 ) ) );
144  double angPC = pToAangle - alpha / 2;
145 
146  VECTOR2I arcCenter;
147 
148  arcCenter.x = p.get().x + KiROUND( distPC * cos( DECIDEG2RAD( angPC ) ) );
149  arcCenter.y = p.get().y + KiROUND( distPC * sin( DECIDEG2RAD( angPC ) ) );
150 
151  // The end points of the arc are the orthogonal projected lines from the line segments
152  // to the center of the arc
153  m_start = aSegmentA.LineProject( arcCenter );
154  m_end = aSegmentB.LineProject( arcCenter );
155 
156  //The mid point is rotated start point around center, half the angle of the arc.
157  VECTOR2I startVector = m_start - arcCenter;
158  VECTOR2I endVector = m_end - arcCenter;
159 
160  double startAngle = ArcTangente( startVector.y, startVector.x );
161  double endAngle = ArcTangente( endVector.y, endVector.x );
162 
163  double midPointRotAngle = NormalizeAngle180( startAngle - endAngle ) / 2;
164  m_mid = m_start;
165  RotatePoint( m_mid, arcCenter, midPointRotAngle );
166  }
167 
168  update_bbox();
169 }
int Length() const
Return the length (this).
Definition: seg.h:350
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
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:154
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
VECTOR2I Center() const
Definition: seg.h:386
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .. 180.0 range.
Definition: trigo.h:387
VECTOR2I m_mid
Definition: shape_arc.h:259
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:268
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:38
circular arc
Definition: shape.h:50
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258
VECTOR2I A
Definition: seg.h:48
double DECIDEG2RAD(double deg)
Definition: trigo.h:233
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:73
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:183
int m_width
Definition: shape_arc.h:262
VECTOR2I B
Definition: seg.h:49

References SEG::A, ArcTangente(), SEG::B, SEG::Center(), DECIDEG2RAD(), VECTOR2< T >::EuclideanNorm(), SEG::Intersect(), KiROUND(), SEG::Length(), SEG::LineProject(), m_end, m_mid, m_start, m_width, NormalizeAngle180(), RotatePoint(), update_bbox(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ SHAPE_ARC() [5/5]

SHAPE_ARC::SHAPE_ARC ( const SHAPE_ARC aOther)

Definition at line 172 of file shape_arc.cpp.

173  : SHAPE( SH_ARC )
174 {
175  m_start = aOther.m_start;
176  m_end = aOther.m_end;
177  m_mid = aOther.m_mid;
178  m_width = aOther.m_width;
179  m_bbox = aOther.m_bbox;
180 }
SHAPE(SHAPE_TYPE aType)
Create an empty shape of type aType.
Definition: shape.h:127
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
circular arc
Definition: shape.h:50
VECTOR2I m_start
Definition: shape_arc.h:258
int m_width
Definition: shape_arc.h:262
BOX2I m_bbox
Definition: shape_arc.h:263

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

◆ ~SHAPE_ARC()

virtual SHAPE_ARC::~SHAPE_ARC ( )
inlinevirtual

Definition at line 79 of file shape_arc.h.

79 {}

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 380 of file shape_arc.cpp.

381 {
382  BOX2I bbox( m_bbox );
383 
384  if( aClearance != 0 )
385  bbox.Inflate( aClearance );
386 
387  return bbox;
388 }
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:41
BOX2I m_bbox
Definition: shape_arc.h:263

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

Referenced by BOOST_AUTO_TEST_CASE(), CheckArcGeom(), Collide(), 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 }
double x
Definition: sg_base.h:70
IFSG_COORDS is the wrapper for SGCOORDS.
Definition: ifsg_coords.h:40
IFSG_COORDINDEX is the wrapper for SGCOORDINDEX.
IFSG_COLORS is the wrapper for SGCOLORS.
Definition: ifsg_colors.h:41
SGLIB_API SGNODE * GetSGNodeParent(SGNODE *aNode)
Definition: ifsg_api.cpp:492
double y
Definition: sg_base.h:71
IFSG_NORMALS is the wrapper for the SGNORMALS class.
Definition: ifsg_normals.h:40
std::list< FACET * > facets
Definition: wrlfacet.h:143
IFSG_FACESET is the wrapper for the SGFACESET class.
Definition: ifsg_faceset.h:40
double z
Definition: sg_base.h:72
IFSG_SHAPE is the wrapper for the SGSHAPE class.
Definition: ifsg_shape.h:40

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 WRL1FACESET::TranslateToSG(), WRL2FACESET::TranslateToSG(), and X3DIFACESET::TranslateToSG().

◆ ccw()

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

Definition at line 247 of file shape_arc.h.

248  {
249  return ( ecoord{ aC.y } - aA.y ) * ( ecoord{ aB.x } - aA.x ) >
250  ( ecoord{ aB.y } - aA.y ) * ( ecoord{ aC.x } - aA.x );
251  }
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 216 of file shape.h.

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

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 81 of file shape_arc.h.

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

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 229 of file shape_arc.cpp.

230 {
231  if( aSeg.A == aSeg.B )
232  return Collide( aSeg.A, aClearance, aActual, aLocation );
233 
234  int minDist = aClearance + m_width / 2;
235  VECTOR2I center = GetCenter();
236  ecoord dist_sq;
237  ecoord closest_dist_sq = VECTOR2I::ECOORD_MAX;
238  VECTOR2I nearest;
239 
240  VECTOR2I ab = ( aSeg.B - aSeg.A );
241  VECTOR2I ac = ( center - aSeg.A );
242 
243  ecoord lenAbSq = ab.SquaredEuclideanNorm();
244  double lambda = (double) ac.Dot( ab ) / (double) lenAbSq;
245 
246  if( lambda >= 0.0 && lambda <= 1.0 )
247  {
248  VECTOR2I p;
249 
250  p.x = (double) aSeg.A.x * lambda + (double) aSeg.B.x * (1.0 - lambda);
251  p.y = (double) aSeg.A.y * lambda + (double) aSeg.B.y * (1.0 - lambda);
252 
253  dist_sq = ( m_start - p ).SquaredEuclideanNorm();
254 
255  if( dist_sq < closest_dist_sq )
256  {
257  closest_dist_sq = dist_sq;
258  nearest = p;
259  }
260 
261  dist_sq = ( m_end - p ).SquaredEuclideanNorm();
262 
263  if( dist_sq < closest_dist_sq )
264  {
265  closest_dist_sq = dist_sq;
266  nearest = p;
267  }
268  }
269 
270  dist_sq = aSeg.SquaredDistance( m_start );
271 
272  if( dist_sq < closest_dist_sq )
273  {
274  closest_dist_sq = dist_sq;
275  nearest = m_start;
276  }
277 
278  dist_sq = aSeg.SquaredDistance( m_end );
279 
280  if( dist_sq < closest_dist_sq )
281  {
282  closest_dist_sq = dist_sq;
283  nearest = m_end;
284  }
285 
286  if( closest_dist_sq == 0 || closest_dist_sq < SEG::Square( minDist ) )
287  {
288  if( aLocation )
289  *aLocation = nearest;
290 
291  if( aActual )
292  *aActual = std::max( 0, (int) sqrt( closest_dist_sq ) - m_width / 2 );
293 
294  return true;
295  }
296 
297  return false;
298 }
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:229
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:300
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:39
static SEG::ecoord Square(int a)
Definition: seg.h:122
static constexpr extended_type ECOORD_MAX
Definition: vector2d.h:79
VECTOR2I::extended_type ecoord
extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Definition: vector2d.h:521
VECTOR2I m_start
Definition: shape_arc.h:258
VECTOR2I A
Definition: seg.h:48
int m_width
Definition: shape_arc.h:262
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464
VECTOR2I B
Definition: seg.h:49

References SEG::A, SEG::B, VECTOR2< T >::Dot(), VECTOR2< T >::ECOORD_MAX, GetCenter(), m_end, m_start, m_width, SEG::Square(), SEG::SquaredDistance(), VECTOR2< T >::SquaredEuclideanNorm(), VECTOR2< T >::x, and VECTOR2< T >::y.

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

◆ Collide() [2/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 397 of file shape_arc.cpp.

399 {
400  int minDist = aClearance + m_width / 2;
401  auto bbox = BBox( minDist );
402 
403  // Fast check using bounding box:
404  if( !bbox.Contains( aP ) )
405  return false;
406 
407  VECTOR2I center = GetCenter();
408  VECTOR2I vec = aP - center;
409 
410  int dist = abs( vec.EuclideanNorm() - GetRadius() );
411 
412  // If not a 360 degree arc, need to use arc angles to decide if point collides
413  if( m_start != m_end )
414  {
415  bool ccw = GetCentralAngle() > 0.0;
416  double rotatedVecAngle = NormalizeAngleDegreesPos( NormalizeAngleDegreesPos( RAD2DEG( vec.Angle() ) )
417  - GetStartAngle() );
418  double rotatedEndAngle = NormalizeAngleDegreesPos( GetEndAngle() - GetStartAngle() );
419 
420  if( ( ccw && rotatedVecAngle > rotatedEndAngle )
421  || ( !ccw && rotatedVecAngle < rotatedEndAngle ) )
422  {
423  int distStartpt = ( aP - m_start ).EuclideanNorm();
424  int distEndpt = ( aP - m_end ).EuclideanNorm();
425  dist = std::min( distStartpt, distEndpt );
426  }
427  }
428 
429  if( dist <= minDist )
430  {
431  if( aLocation )
432  *aLocation = ( aP + GetCenter() ) / 2;
433 
434  if( aActual )
435  *aActual = std::max( 0, dist - m_width / 2 );
436 
437  return true;
438  }
439 
440  return false;
441 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
double GetRadius() const
Definition: shape_arc.cpp:492
VECTOR2I m_end
Definition: shape_arc.h:260
double RAD2DEG(double rad)
Definition: trigo.h:230
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool ccw(const VECTOR2I &aA, const VECTOR2I &aB, const VECTOR2I &aC) const
Definition: shape_arc.h:247
double GetStartAngle() const
Definition: shape_arc.cpp:444
double NormalizeAngleDegreesPos(double Angle)
Normalize angle to be in the 0.0 .. 360.0 range: angle is in degrees.
Definition: trigo.h:297
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
double GetEndAngle() const
Definition: shape_arc.cpp:454
VECTOR2I m_start
Definition: shape_arc.h:258
double GetCentralAngle() const
Definition: shape_arc.cpp:479
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:380
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
int m_width
Definition: shape_arc.h:262
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References VECTOR2< T >::Angle(), BBox(), ccw(), VECTOR2< T >::EuclideanNorm(), EuclideanNorm(), GetCenter(), GetCentralAngle(), GetEndAngle(), GetRadius(), GetStartAngle(), m_end, m_start, m_width, NormalizeAngleDegreesPos(), and RAD2DEG().

◆ 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 124 of file shape_arc.h.

126  {
127  return SHAPE::Collide( aShape, aClearance, aActual, aLocation );
128  }
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:165

References SHAPE::Collide().

◆ Collide() [4/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_RECT, SHAPE_SEGMENT, and SHAPE_COMPOUND.

Definition at line 1024 of file shape_collisions.cpp.

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

References collideShapes().

◆ ConstructFromStartEndAngle()

SHAPE_ARC & SHAPE_ARC::ConstructFromStartEndAngle ( const VECTOR2I aStart,
const VECTOR2I aEnd,
double  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 183 of file shape_arc.cpp.

185 {
186  m_start = aStart;
187  m_mid = aStart;
188  m_end = aEnd;
189  m_width = aWidth;
190 
191  VECTOR2I center( CalcArcCenter( aStart, aEnd, aAngle ) );
192 
193  RotatePoint( m_mid, center, -aAngle * 10.0 / 2.0 );
194 
195  update_bbox();
196 
197  return *this;
198 }
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
VECTOR2I m_mid
Definition: shape_arc.h:259
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258
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:454
int m_width
Definition: shape_arc.h:262

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

Referenced by DIRECTION_45::BuildInitialTrace().

◆ 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 201 of file shape_arc.cpp.

204 {
205  VECTOR2I startLine = aStart - aCenter;
206  VECTOR2I endLine = aEnd - aCenter;
207 
208  double startangle = NormalizeAnglePos(RAD2DECIDEG( startLine.Angle() ));
209  double endangle = NormalizeAnglePos(RAD2DECIDEG( endLine.Angle() ));
210  double angle = endangle - startangle;
211 
212  if( aClockwise )
214  else
216 
217  m_start = aStart;
218  m_end = aEnd;
219  m_mid = aStart;
220 
221  RotatePoint( m_mid, aCenter, -angle / 2.0 );
222 
223  update_bbox();
224 
225  return *this;
226 }
T NormalizeAngleNeg(T Angle)
Normalize angle to be in the 0.0 .. -360.0 range: angle is in 1/10 degrees.
Definition: trigo.h:268
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
double RAD2DECIDEG(double rad)
Definition: trigo.h:234
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
VECTOR2I m_mid
Definition: shape_arc.h:259
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258
T NormalizeAnglePos(T Angle)
Normalize angle to be in the 0.0 .. 360.0 range: angle is in 1/10 degrees.
Definition: trigo.h:281
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), VECTOR2< T >::Angle(), m_end, m_mid, m_start, NormalizeAngleNeg(), NormalizeAnglePos(), RAD2DECIDEG(), RotatePoint(), and update_bbox().

Referenced by SHAPE_LINE_CHAIN::amendArc(), BOOST_AUTO_TEST_CASE(), 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 498 of file shape_arc.cpp.

500 {
501  SHAPE_LINE_CHAIN rv;
502  double r = GetRadius();
503  double sa = GetStartAngle();
504  VECTOR2I c = GetCenter();
505  double ca = GetCentralAngle();
506 
507  int n;
508 
509  // To calculate the arc to segment count, use the external radius instead of the radius.
510  // for a arc with small radius and large width, the difference can be significant
511  double external_radius = r+(m_width/2);
512  double effectiveAccuracy;
513 
514  if( external_radius < aAccuracy/2 ) // Should be a very rare case
515  {
516  // In this case, the arc is approximated by one segment, with a effective error
517  // between -aAccuracy/2 and +aAccuracy/2, as expected.
518  n = 0;
519  effectiveAccuracy = external_radius;
520  }
521  else
522  {
523  double arc_angle = std::abs( ca );
524  n = GetArcToSegmentCount( external_radius, aAccuracy, arc_angle );
525 
526  // Recalculate the effective error of approximation, that can be < aAccuracy
527  int seg360 = n * 360.0 / arc_angle;
528  effectiveAccuracy = CircleToEndSegmentDeltaRadius( external_radius, seg360 );
529  }
530 
531  // Split the error on either side of the arc. Since we want the start and end points
532  // to be exactly on the arc, the first and last segments need to be shorter to stay within
533  // the error band (since segments normally start 1/2 the error band outside the arc).
534  r += effectiveAccuracy / 2;
535  n = n * 2;
536 
537  rv.Append( m_start );
538 
539  for( int i = 1; i < n ; i += 2 )
540  {
541  double a = sa;
542 
543  if( n != 0 )
544  a += ( ca * i ) / n;
545 
546  double x = c.x + r * cos( a * M_PI / 180.0 );
547  double y = c.y + r * sin( a * M_PI / 180.0 );
548 
549  rv.Append( KiROUND( x ), KiROUND( y ) );
550  }
551 
552  rv.Append( m_end );
553 
554  if( aEffectiveAccuracy )
555  *aEffectiveAccuracy = effectiveAccuracy;
556 
557  return rv;
558 }
int CircleToEndSegmentDeltaRadius(int aInnerCircleRadius, int aSegCount)
double GetRadius() const
Definition: shape_arc.cpp:492
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
double GetStartAngle() const
Definition: shape_arc.cpp:444
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
E_SERIE r
Definition: eserie.cpp:41
Represent a polyline (an zero-thickness chain of connected line segments).
VECTOR2I m_start
Definition: shape_arc.h:258
double GetCentralAngle() const
Definition: shape_arc.cpp:479
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:73
int m_width
Definition: shape_arc.h:262
int GetArcToSegmentCount(int aRadius, int aErrorMax, double aArcAngleDegree)
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

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

Referenced by SHAPE_LINE_CHAIN::Append(), PNS::ArcHull(), Collide(), BOARD_ADAPTER::createPadWithClearance(), SHAPE_LINE_CHAIN::Insert(), CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(), EDA_SHAPE::MakeEffectiveShapes(), SHAPE_LINE_CHAIN::SHAPE_LINE_CHAIN(), and TransformArcToPolygon().

◆ 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 220 of file shape_arc.h.

220 { return 0.005 * PCB_IU_PER_MM; }
constexpr double PCB_IU_PER_MM

References PCB_IU_PER_MM.

Referenced by BOOST_AUTO_TEST_CASE(), and TransformArcToPolygon().

◆ Format()

const std::string SHAPE::Format ( ) const
virtualinherited

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

Definition at line 35 of file shape.cpp.

36 {
37  assert( false );
38  return std::string( "" );
39 }

Referenced by SHAPE_FILE_IO::Write().

◆ GetArcMid()

const VECTOR2I& SHAPE_ARC::GetArcMid ( ) const
inline

◆ GetCenter()

VECTOR2I SHAPE_ARC::GetCenter ( ) const

Definition at line 464 of file shape_arc.cpp.

465 {
466  return CalcArcCenter( m_start, m_mid, m_end );
467 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
VECTOR2I m_start
Definition: shape_arc.h:258
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:454

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

Referenced by PNS_LOG_VIEWER_OVERLAY::Arc(), PLOTTER::Arc(), CheckArcGeom(), Collide(), Collide(), collideArc2Arc(), ConvertToPolyline(), ROUTER_PREVIEW_ITEM::drawLineChain(), ROUTER_PREVIEW_ITEM::drawShape(), GetCentralAngle(), GetEndAngle(), GetRadius(), GetStartAngle(), Intersect(), IntersectLine(), GERBER_PLOTTER::plotArc(), SHAPE_LINE_CHAIN::Slice(), sliceContainsPoint(), SHAPE_LINE_CHAIN::splitArc(), TransformArcToPolygon(), and update_bbox().

◆ GetCentralAngle()

double SHAPE_ARC::GetCentralAngle ( ) const
Returns
the central angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.

Definition at line 479 of file shape_arc.cpp.

480 {
481  VECTOR2I center = GetCenter();
482  VECTOR2I p0 = m_start - center;
483  VECTOR2I p1 = m_mid - center;
484  VECTOR2I p2 = m_end - center;
485  double angle1 = ArcTangente( p1.y, p1.x ) - ArcTangente( p0.y, p0.x );
486  double angle2 = ArcTangente( p2.y, p2.x ) - ArcTangente( p1.y, p1.x );
487 
488  return ( NormalizeAngle180( angle1 ) + NormalizeAngle180( angle2 ) ) / 10.0;
489 }
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .. 180.0 range.
Definition: trigo.h:387
VECTOR2I m_mid
Definition: shape_arc.h:259
VECTOR2I m_start
Definition: shape_arc.h:258
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:183
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

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

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

◆ GetChord()

SEG SHAPE_ARC::GetChord ( ) const
inline

Definition at line 186 of file shape_arc.h.

187  {
188  return SEG( m_start, m_end );
189  }
VECTOR2I m_end
Definition: shape_arc.h:260
Definition: seg.h:40
VECTOR2I m_start
Definition: shape_arc.h:258

References m_end, and m_start.

Referenced by CheckArcGeom().

◆ GetEndAngle()

double SHAPE_ARC::GetEndAngle ( ) const
Returns
the end angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.

Definition at line 454 of file shape_arc.cpp.

455 {
456  VECTOR2D d( m_end - GetCenter() );
457 
458  auto ang = 180.0 / M_PI * atan2( d.y, d.x );
459 
460  return NormalizeAngleDegrees( ang, 0.0, 360.0 );
461 }
VECTOR2I m_end
Definition: shape_arc.h:260
double NormalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
Definition: trigo.h:327
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References GetCenter(), m_end, NormalizeAngleDegrees(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PLOTTER::Arc(), CheckArcGeom(), Collide(), GERBER_PLOTTER::plotArc(), and TransformArcToPolygon().

◆ GetIndexableSubshapeCount()

virtual size_t SHAPE_BASE::GetIndexableSubshapeCount ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 104 of file shape.h.

104 { return 0; }

◆ GetIndexableSubshapes()

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

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 106 of file shape.h.

106 { }

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

◆ GetLength()

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

Definition at line 470 of file shape_arc.cpp.

471 {
472  double radius = GetRadius();
473  double includedAngle = std::abs( GetCentralAngle() );
474 
475  return radius * M_PI * includedAngle / 180.0;
476 }
double GetRadius() const
Definition: shape_arc.cpp:492
double GetCentralAngle() const
Definition: shape_arc.cpp:479

References GetCentralAngle(), and GetRadius().

◆ GetP0()

◆ GetP1()

◆ GetRadius()

double SHAPE_ARC::GetRadius ( ) const

◆ GetStartAngle()

double SHAPE_ARC::GetStartAngle ( ) const
Returns
the start angle of the arc shape in degrees, normalized between 0.0, 360.0 deg.

Definition at line 444 of file shape_arc.cpp.

445 {
446  VECTOR2D d( m_start - GetCenter() );
447 
448  auto ang = 180.0 / M_PI * atan2( d.y, d.x );
449 
450  return NormalizeAngleDegrees( ang, 0.0, 360.0 );
451 }
VECTOR2I m_start
Definition: shape_arc.h:258
double NormalizeAngleDegrees(double Angle, double aMin, double aMax)
Normalize angle to be aMin < angle <= aMax angle is in degrees.
Definition: trigo.h:327
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References GetCenter(), m_start, NormalizeAngleDegrees(), VECTOR2< T >::x, and VECTOR2< T >::y.

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

◆ GetWidth()

◆ HasIndexableSubshapes()

virtual bool SHAPE_BASE::HasIndexableSubshapes ( ) const
inlinevirtualinherited

Reimplemented in SHAPE_POLY_SET, and SHAPE_COMPOUND.

Definition at line 99 of file shape.h.

100  {
101  return false;
102  }

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 319 of file shape_arc.cpp.

320 {
321  CIRCLE thiscirc( GetCenter(), GetRadius() );
322  CIRCLE othercirc( aArc.GetCenter(), aArc.GetRadius() );
323 
324  std::vector<VECTOR2I> intersections = thiscirc.Intersect( othercirc );
325 
326  size_t originalSize = aIpsBuffer->size();
327 
328  for( const VECTOR2I& intersection : intersections )
329  {
330  if( sliceContainsPoint( intersection ) && aArc.sliceContainsPoint( intersection ) )
331  aIpsBuffer->push_back( intersection );
332  }
333 
334  return aIpsBuffer->size() - originalSize;
335 }
double GetRadius() const
Definition: shape_arc.cpp:492
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool sliceContainsPoint(const VECTOR2I &p) const
Definition: shape_arc.cpp:630
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
std::vector< VECTOR2I > Intersect(const CIRCLE &aCircle) const
Compute the intersection points between this circle and aCircle.
Definition: circle.cpp:209
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

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 301 of file shape_arc.cpp.

302 {
303  CIRCLE circ( GetCenter(), GetRadius() );
304 
305  std::vector<VECTOR2I> intersections = circ.IntersectLine( aSeg );
306 
307  size_t originalSize = aIpsBuffer->size();
308 
309  for( const VECTOR2I& intersection : intersections )
310  {
311  if( sliceContainsPoint( intersection ) )
312  aIpsBuffer->push_back( intersection );
313  }
314 
315  return aIpsBuffer->size() - originalSize;
316 }
double GetRadius() const
Definition: shape_arc.cpp:492
Define a general 2D-vector/point.
Definition: vector2d.h:61
bool sliceContainsPoint(const VECTOR2I &p) const
Definition: shape_arc.cpp:630
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:32
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

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

Referenced by Collide(), and collideArc2Arc().

◆ IsClockwise()

bool SHAPE_ARC::IsClockwise ( ) const

Definition at line 391 of file shape_arc.cpp.

392 {
393  return GetCentralAngle() < 0;
394 }
double GetCentralAngle() const
Definition: shape_arc.cpp:479

References GetCentralAngle().

Referenced by SHAPE_LINE_CHAIN::Slice(), and SHAPE_LINE_CHAIN::splitArc().

◆ IsNull()

bool SHAPE::IsNull ( ) const
inlineinherited

Return true if the shape is a null shape.

Return values
trueif null :-)

Definition at line 150 of file shape.h.

151  {
152  return m_type == SH_NULL;
153  }
SHAPE_TYPE m_type
< type of our shape
Definition: shape.h:110
empty shape (no shape...),
Definition: shape.h:51

References SHAPE_BASE::m_type, and SH_NULL.

◆ IsSolid()

bool SHAPE_ARC::IsSolid ( ) const
inlineoverridevirtual

Implements SHAPE.

Definition at line 161 of file shape_arc.h.

162  {
163  return true;
164  }

Referenced by CheckArcGeom().

◆ Mirror() [1/2]

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

Definition at line 588 of file shape_arc.cpp.

589 {
590  if( aX )
591  {
592  m_start.x = -m_start.x + 2 * aVector.x;
593  m_end.x = -m_end.x + 2 * aVector.x;
594  m_mid.x = -m_mid.x + 2 * aVector.x;
595  }
596 
597  if( aY )
598  {
599  m_start.y = -m_start.y + 2 * aVector.y;
600  m_end.y = -m_end.y + 2 * aVector.y;
601  m_mid.y = -m_mid.y + 2 * aVector.y;
602  }
603 
604  update_bbox();
605 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258

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 608 of file shape_arc.cpp.

609 {
610  m_start = axis.ReflectPoint( m_start );
611  m_end = axis.ReflectPoint( m_end );
612  m_mid = axis.ReflectPoint( m_mid );
613 
614  update_bbox();
615 }
VECTOR2I m_end
Definition: shape_arc.h:260
const VECTOR2I ReflectPoint(const VECTOR2I &aP) const
Reflect a point using this segment as axis.
Definition: seg.cpp:249
VECTOR2I m_mid
Definition: shape_arc.h:259
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258

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 561 of file shape_arc.cpp.

562 {
563  m_start += aVector;
564  m_end += aVector;
565  m_mid += aVector;
566  update_bbox();
567 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2I m_start
Definition: shape_arc.h:258

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:42
std::list< FACET * > facets
Definition: wrlfacet.h:143

References SHAPE::facets.

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

◆ operator==()

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

Definition at line 240 of file shape_arc.h.

241  {
242  return ( aArc.m_start == m_start ) && ( aArc.m_end == m_end ) && ( aArc.m_mid == m_mid )
243  && ( aArc.m_width == m_width );
244  }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
VECTOR2I m_start
Definition: shape_arc.h:258
int m_width
Definition: shape_arc.h:262

References m_end, m_mid, m_start, and m_width.

◆ Parse()

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

Reimplemented in SHAPE_POLY_SET, and SHAPE_LINE_CHAIN.

Definition at line 28 of file shape.cpp.

29 {
30  assert( false );
31  return false;
32 }

◆ Reverse()

void SHAPE_ARC::Reverse ( )

Definition at line 618 of file shape_arc.cpp.

619 {
620  std::swap( m_start, m_end );
621 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_start
Definition: shape_arc.h:258

References m_end, and m_start.

Referenced by SHAPE_LINE_CHAIN::Reverse().

◆ Reversed()

SHAPE_ARC SHAPE_ARC::Reversed ( ) const

Definition at line 624 of file shape_arc.cpp.

625 {
626  return SHAPE_ARC( m_end, m_mid, m_start, m_width );
627 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
VECTOR2I m_start
Definition: shape_arc.h:258
SHAPE_ARC()
Definition: shape_arc.h:39
int m_width
Definition: shape_arc.h:262

References m_end, m_mid, m_start, m_width, and SHAPE_ARC().

Referenced by PNS::NODE::AssembleLine(), BOOST_AUTO_TEST_CASE(), and CONVERT_TOOL::makePolysFromSegs().

◆ Rotate()

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

Rotate the arc by a given angle about a point.

Parameters
aCenteris the rotation center.
aAnglerotation angle in radians.

Implements SHAPE.

Definition at line 570 of file shape_arc.cpp.

571 {
572  m_start -= aCenter;
573  m_end -= aCenter;
574  m_mid -= aCenter;
575 
576  m_start = m_start.Rotate( aAngle );
577  m_end = m_end.Rotate( aAngle );
578  m_mid = m_mid.Rotate( aAngle );
579 
580  m_start += aCenter;
581  m_end += aCenter;
582  m_mid += aCenter;
583 
584  update_bbox();
585 }
VECTOR2I m_end
Definition: shape_arc.h:260
VECTOR2I m_mid
Definition: shape_arc.h:259
void update_bbox()
Definition: shape_arc.cpp:338
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371
VECTOR2I m_start
Definition: shape_arc.h:258

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

◆ SetWidth()

void SHAPE_ARC::SetWidth ( int  aWidth)
inline

Definition at line 151 of file shape_arc.h.

152  {
153  m_width = aWidth;
154  }
int m_width
Definition: shape_arc.h:262

References m_width.

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

◆ sliceContainsPoint()

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

Definition at line 630 of file shape_arc.cpp.

631 {
632  VECTOR2I center = GetCenter();
633  double phi = 180.0 / M_PI * atan2( p.y - center.y, p.x - center.x );
634  double ca = GetCentralAngle();
635  double sa = GetStartAngle();
636  double ea;
637 
638  if( ca >= 0 )
639  {
640  ea = sa + ca;
641  }
642  else
643  {
644  ea = sa;
645  sa += ca;
646  }
647 
648  return alg::within_wrapped_range( phi, sa, ea, 360.0 );
649 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
double GetStartAngle() const
Definition: shape_arc.cpp:444
double GetCentralAngle() const
Definition: shape_arc.cpp:479
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464
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 GetCenter(), GetCentralAngle(), GetStartAngle(), alg::within_wrapped_range(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Intersect(), and IntersectLine().

◆ Type()

SHAPE_TYPE SHAPE_BASE::Type ( ) const
inlineinherited

◆ update_bbox()

void SHAPE_ARC::update_bbox ( )
private

Definition at line 338 of file shape_arc.cpp.

339 {
340  std::vector<VECTOR2I> points;
341  // Put start and end points in the point list
342  points.push_back( m_start );
343  points.push_back( m_end );
344 
345  double start_angle = GetStartAngle();
346  double end_angle = start_angle + GetCentralAngle();
347 
348  // we always count quadrants clockwise (increasing angle)
349  if( start_angle > end_angle )
350  std::swap( start_angle, end_angle );
351 
352  int quad_angle_start = std::ceil( start_angle / 90.0 );
353  int quad_angle_end = std::floor( end_angle / 90.0 );
354 
355  // count through quadrants included in arc
356  for( int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle )
357  {
358  const int radius = KiROUND( GetRadius() );
359  VECTOR2I quad_pt = GetCenter();
360 
361  switch( quad_angle % 4 )
362  {
363  case 0: quad_pt += { radius, 0 }; break;
364  case 1:
365  case -3: quad_pt += { 0, radius }; break;
366  case 2:
367  case -2: quad_pt += { -radius, 0 }; break;
368  case 3:
369  case -1: quad_pt += { 0, -radius }; break;
370  default: assert( false );
371  }
372 
373  points.push_back( quad_pt );
374  }
375 
376  m_bbox.Compute( points );
377 }
double GetRadius() const
Definition: shape_arc.cpp:492
VECTOR2I m_end
Definition: shape_arc.h:260
Define a general 2D-vector/point.
Definition: vector2d.h:61
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:75
double GetStartAngle() const
Definition: shape_arc.cpp:444
VECTOR2I m_start
Definition: shape_arc.h:258
double GetCentralAngle() const
Definition: shape_arc.cpp:479
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:73
BOX2I m_bbox
Definition: shape_arc.h:263
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:464

References 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

◆ m_bbox

BOX2I SHAPE_ARC::m_bbox
private

Definition at line 263 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 110 of file shape.h.

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

◆ 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 122 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: