KiCad PCB EDA Suite
test_shape_arc.cpp File Reference

Go to the source code of this file.

Classes

struct  ARC_PROPERTIES
 All properties of an arc (depending on how it's constructed, some of these might be the same as the constructor params) More...
 
struct  ARC_CENTRE_PT_ANGLE
 Info to set up an arc by centre, start point and angle. More...
 
struct  ARC_CPA_CASE
 
struct  ARC_TAN_TAN_RADIUS
 Info to set up an arc by tangent to two segments and a radius. More...
 
struct  ARC_TTR_CASE
 
struct  ARC_PT_COLLIDE_CASE
 
struct  ARC_TO_POLYLINE_CASE
 

Functions

static void CheckArcGeom (const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
 Check a SHAPE_ARC against a given set of geometric properties. More...
 
static void CheckArc (const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
 Check an arcs geometry and other class functions. More...
 
 BOOST_AUTO_TEST_CASE (NullCtor)
 Check correct handling of filter strings (as used by WX) More...
 
 BOOST_AUTO_TEST_CASE (BasicCPAGeom)
 
 BOOST_AUTO_TEST_CASE (BasicTTRGeom)
 
 BOOST_AUTO_TEST_CASE (CollidePt)
 
bool ArePolylineEndPointsNearCircle (const SHAPE_LINE_CHAIN &aPolyline, const VECTOR2I &aCentre, int aRad, int aTolerance)
 Predicate for checking a polyline has all the points on (near) a circle of given centre and radius. More...
 
bool ArePolylineMidPointsNearCircle (const SHAPE_LINE_CHAIN &aPolyline, const VECTOR2I &aCentre, int aRad, int aTolerance)
 Predicate for checking a polyline has all the segment mid points on (near) a circle of given centre and radius. More...
 
 BOOST_AUTO_TEST_CASE (ArcToPolyline)
 

Variables

static const std::vector< ARC_CPA_CASEarc_cases
 
static const std::vector< ARC_TTR_CASEarc_ttr_cases
 
static const std::vector< ARC_PT_COLLIDE_CASEarc_pt_collide_cases
 

Function Documentation

◆ ArePolylineEndPointsNearCircle()

bool ArePolylineEndPointsNearCircle ( const SHAPE_LINE_CHAIN aPolyline,
const VECTOR2I aCentre,
int  aRad,
int  aTolerance 
)

Predicate for checking a polyline has all the points on (near) a circle of given centre and radius.

Parameters
aPolylinethe polyline to check
aCentrethe circle centre
aRadthe circle radius
aTolerancethe tolerance for the endpoint-centre distance
Returns
true if predicate met

Definition at line 587 of file test_shape_arc.cpp.

589 {
590  std::vector<VECTOR2I> points;
591 
592  for( int i = 0; i < aPolyline.PointCount(); ++i )
593  {
594  points.push_back( aPolyline.CPoint( i ) );
595  }
596 
597  return GEOM_TEST::ArePointsNearCircle( points, aCentre, aRad, aTolerance );
598 }
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
bool ArePointsNearCircle(const std::vector< VECTOR2< T >> &aPoints, const VECTOR2< T > &aCentre, T aRad, T aTol)
Predicate for checking a set of points is within a certain tolerance of a circle.

References GEOM_TEST::ArePointsNearCircle(), SHAPE_LINE_CHAIN::CPoint(), and SHAPE_LINE_CHAIN::PointCount().

Referenced by BOOST_AUTO_TEST_CASE().

◆ ArePolylineMidPointsNearCircle()

bool ArePolylineMidPointsNearCircle ( const SHAPE_LINE_CHAIN aPolyline,
const VECTOR2I aCentre,
int  aRad,
int  aTolerance 
)

Predicate for checking a polyline has all the segment mid points on (near) a circle of given centre and radius.

Parameters
aPolylinethe polyline to check
aCentrethe circle centre
aRadthe circle radius
aTolEndsthe tolerance for the midpoint-centre distance
Returns
true if predicate met

Definition at line 610 of file test_shape_arc.cpp.

612 {
613  std::vector<VECTOR2I> points;
614 
615  for( int i = 0; i < aPolyline.PointCount() - 1; ++i )
616  {
617  const VECTOR2I mid_pt = ( aPolyline.CPoint( i ) + aPolyline.CPoint( i + 1 ) ) / 2;
618  points.push_back( mid_pt );
619  }
620 
621  return GEOM_TEST::ArePointsNearCircle( points, aCentre, aRad, aTolerance );
622 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
int PointCount() const
Function PointCount()
const VECTOR2I & CPoint(int aIndex) const
Function Point()
bool ArePointsNearCircle(const std::vector< VECTOR2< T >> &aPoints, const VECTOR2< T > &aCentre, T aRad, T aTol)
Predicate for checking a set of points is within a certain tolerance of a circle.

References GEOM_TEST::ArePointsNearCircle(), SHAPE_LINE_CHAIN::CPoint(), and SHAPE_LINE_CHAIN::PointCount().

Referenced by BOOST_AUTO_TEST_CASE().

◆ BOOST_AUTO_TEST_CASE() [1/5]

BOOST_AUTO_TEST_CASE ( NullCtor  )

Check correct handling of filter strings (as used by WX)

Definition at line 127 of file test_shape_arc.cpp.

128 {
129  auto arc = SHAPE_ARC();
130 
131  BOOST_CHECK_EQUAL( arc.GetWidth(), 0 );
132 
133  static ARC_PROPERTIES null_props{
134  { 0, 0 },
135  { 0, 0 },
136  { 0, 0 },
137  0,
138  0,
139  0,
140  0,
141  };
142 
143  CheckArc( arc, null_props );
144 }
All properties of an arc (depending on how it's constructed, some of these might be the same as the c...
static void CheckArc(const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
Check an arcs geometry and other class functions.

References CheckArc().

◆ BOOST_AUTO_TEST_CASE() [2/5]

BOOST_AUTO_TEST_CASE ( BasicCPAGeom  )

Definition at line 321 of file test_shape_arc.cpp.

322 {
323  for( const auto& c : arc_cases )
324  {
325  BOOST_TEST_CONTEXT( c.m_ctx_name )
326  {
327 
328  const auto this_arc = SHAPE_ARC{ c.m_geom.m_center_point, c.m_geom.m_start_point,
329  c.m_geom.m_center_angle, c.m_width };
330 
331  CheckArc( this_arc, c.m_properties );
332  }
333  }
334 }
static void CheckArc(const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
Check an arcs geometry and other class functions.
#define BOOST_TEST_CONTEXT(A)
int m_width
Definition: shape_arc.h:177
static const std::vector< ARC_CPA_CASE > arc_cases

References arc_cases, BOOST_TEST_CONTEXT, CheckArc(), and SHAPE_ARC::m_width.

◆ BOOST_AUTO_TEST_CASE() [3/5]

BOOST_AUTO_TEST_CASE ( BasicTTRGeom  )

Definition at line 428 of file test_shape_arc.cpp.

429 {
430  for( const auto& c : arc_ttr_cases )
431  {
432  BOOST_TEST_CONTEXT( c.m_ctx_name )
433  {
434  for( int testCase = 0; testCase < 8; ++testCase )
435  {
436  SEG seg1 = c.m_geom.m_segment_1;
437  SEG seg2 = c.m_geom.m_segment_2;
438  ARC_PROPERTIES props = c.m_properties;
439 
440  if( testCase > 3 )
441  {
442  //Swap input segments.
443  seg1 = c.m_geom.m_segment_2;
444  seg2 = c.m_geom.m_segment_1;
445 
446  //The result should swap start and end points and invert the angles:
447  props.m_end_point = c.m_properties.m_start_point;
448  props.m_start_point = c.m_properties.m_end_point;
449  props.m_start_angle = c.m_properties.m_end_angle;
450  props.m_end_angle = c.m_properties.m_start_angle;
451  props.m_center_angle = -c.m_properties.m_center_angle;
452  }
453 
454  //Test all combinations of start and end points for the segments
455  if( ( testCase % 4 ) == 1 || ( testCase % 4 ) == 3 )
456  {
457  //Swap start and end points for seg1
458  VECTOR2I temp = seg1.A;
459  seg1.A = seg1.B;
460  seg1.B = temp;
461  }
462 
463  if( ( testCase % 4 ) == 2 || ( testCase % 4 ) == 3 )
464  {
465  //Swap start and end points for seg2
466  VECTOR2I temp = seg2.A;
467  seg2.A = seg2.B;
468  seg2.B = temp;
469  }
470 
471  const auto this_arc = SHAPE_ARC{ seg1, seg2,
472  c.m_geom.m_radius, c.m_width };
473 
474  // Error of 4 IU permitted for the center and radius calculation
475  CheckArc( this_arc, props, SHAPE_ARC::MIN_PRECISION_IU );
476  }
477  }
478  }
479 }
All properties of an arc (depending on how it's constructed, some of these might be the same as the c...
VECTOR2I m_start_point
static void CheckArc(const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
Check an arcs geometry and other class functions.
Define a general 2D-vector/point.
Definition: vector2d.h:61
VECTOR2I m_end_point
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Definition: shape.h:122
#define BOOST_TEST_CONTEXT(A)
static const std::vector< ARC_TTR_CASE > arc_ttr_cases
Definition: seg.h:41
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, arc_ttr_cases, SEG::B, BOOST_TEST_CONTEXT, CheckArc(), ARC_PROPERTIES::m_center_angle, ARC_PROPERTIES::m_end_angle, ARC_PROPERTIES::m_end_point, ARC_PROPERTIES::m_start_angle, ARC_PROPERTIES::m_start_point, and SHAPE::MIN_PRECISION_IU.

◆ BOOST_AUTO_TEST_CASE() [4/5]

BOOST_AUTO_TEST_CASE ( CollidePt  )

Definition at line 536 of file test_shape_arc.cpp.

537 {
538  for( const auto& c : arc_pt_collide_cases )
539  {
540  BOOST_TEST_CONTEXT( c.m_ctx_name )
541  {
542  SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point,
543  c.m_geom.m_center_angle );
544 
545  // Test a zero width arc (distance should equal the clearance)
546  BOOST_TEST_CONTEXT( "Test Clearance" )
547  {
548  int dist = -1;
549  BOOST_CHECK_EQUAL( arc.Collide( c.m_point, c.m_arc_clearance, &dist ),
550  c.m_exp_result );
551  BOOST_CHECK_EQUAL( dist, c.m_exp_distance );
552  }
553 
554  // Test by changing the width of the arc (distance should equal zero)
555  BOOST_TEST_CONTEXT( "Test Width" )
556  {
557  int dist = -1;
558  arc.SetWidth( c.m_arc_clearance * 2 );
559  BOOST_CHECK_EQUAL( arc.Collide( c.m_point, 0, &dist ), c.m_exp_result );
560 
561  if( c.m_exp_result )
562  BOOST_CHECK_EQUAL( dist, 0 );
563  else
564  BOOST_CHECK_EQUAL( dist, -1 );
565  }
566  }
567  }
568 }
static const std::vector< ARC_PT_COLLIDE_CASE > arc_pt_collide_cases
#define BOOST_TEST_CONTEXT(A)

References arc_pt_collide_cases, BOOST_TEST_CONTEXT, SHAPE_ARC::Collide(), and SHAPE_ARC::SetWidth().

◆ BOOST_AUTO_TEST_CASE() [5/5]

BOOST_AUTO_TEST_CASE ( ArcToPolyline  )

Definition at line 625 of file test_shape_arc.cpp.

626 {
627  const std::vector<ARC_TO_POLYLINE_CASE> cases = {
628  {
629  "Zero rad",
630  {
631  { 0, 0 },
632  { 0, 0 },
633  180,
634  },
635  },
636  {
637  "Semicircle",
638  {
639  { 0, 0 },
640  { -1000000, 0 },
641  180,
642  },
643  },
644  {
645  // check that very small circles don't fall apart and that reverse angles
646  // work too
647  "Extremely small semicircle",
648  {
649  { 0, 0 },
650  { -1000, 0 },
651  -180,
652  },
653  },
654  {
655  // Make sure it doesn't only work for "easy" angles
656  "Non-round geometry",
657  {
658  { 0, 0 },
659  { 1234567, 0 },
660  42.22,
661  },
662  },
663  };
664 
665  const int width = 0;
666 
667  // Note: do not expect accuracies around 1 to work. We use integers internally so we're
668  // liable to rounding errors. In PCBNew accuracy defaults to 5000 and we don't recommend
669  // anything lower than 1000 (for performance reasons).
670  const int accuracy = 100;
671  const int epsilon = 1;
672 
673  for( const auto& c : cases )
674  {
675  BOOST_TEST_CONTEXT( c.m_ctx_name )
676  {
677  const SHAPE_ARC this_arc{ c.m_geom.m_center_point, c.m_geom.m_start_point,
678  c.m_geom.m_center_angle, width };
679 
680  const SHAPE_LINE_CHAIN chain = this_arc.ConvertToPolyline( accuracy );
681 
682  BOOST_TEST_MESSAGE( "Polyline has " << chain.PointCount() << " points" );
683 
684  // Start point (exactly) where expected
685  BOOST_CHECK_EQUAL( chain.CPoint( 0 ), c.m_geom.m_start_point );
686 
687  // End point (exactly) where expected
688  BOOST_CHECK_EQUAL( chain.CPoint( -1 ), this_arc.GetP1() );
689 
690  int radius = ( c.m_geom.m_center_point - c.m_geom.m_start_point ).EuclideanNorm();
691 
692  // Other points within accuracy + epsilon (for rounding) of where they should be
693  BOOST_CHECK_PREDICATE( ArePolylineEndPointsNearCircle,
694  ( chain )( c.m_geom.m_center_point )( radius )( accuracy + epsilon ) );
695 
696  BOOST_CHECK_PREDICATE( ArePolylineMidPointsNearCircle,
697  ( chain )( c.m_geom.m_center_point )( radius )( accuracy + epsilon ) );
698  }
699  }
700 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
bool ArePolylineMidPointsNearCircle(const SHAPE_LINE_CHAIN &aPolyline, const VECTOR2I &aCentre, int aRad, int aTolerance)
Predicate for checking a polyline has all the segment mid points on (near) a circle of given centre a...
int PointCount() const
Function PointCount()
bool ArePolylineEndPointsNearCircle(const SHAPE_LINE_CHAIN &aPolyline, const VECTOR2I &aCentre, int aRad, int aTolerance)
Predicate for checking a polyline has all the points on (near) a circle of given centre and radius.
const VECTOR2I & CPoint(int aIndex) const
Function Point()
#define BOOST_TEST_CONTEXT(A)
SHAPE_LINE_CHAIN.

References ArePolylineEndPointsNearCircle(), ArePolylineMidPointsNearCircle(), BOOST_TEST_CONTEXT, SHAPE_LINE_CHAIN::CPoint(), EuclideanNorm(), and SHAPE_LINE_CHAIN::PointCount().

◆ CheckArc()

static void CheckArc ( const SHAPE_ARC aArc,
const ARC_PROPERTIES aProps,
const int  aSynErrIU = 1 
)
static

Check an arcs geometry and other class functions.

Parameters
aArcArc to test
aPropsProperties to test against
aSynErrIUPermitted error for synthetic points and dimensions (currently radius and center)

Should have identical geom props

Definition at line 106 of file test_shape_arc.cpp.

107 {
108  // Check the original arc
109  CheckArcGeom( aArc, aProps, aSynErrIU );
110 
111  // Test the Clone function (also tests copy-ctor)
112  std::unique_ptr<SHAPE> new_shape{ aArc.Clone() };
113 
114  BOOST_CHECK_EQUAL( new_shape->Type(), SH_ARC );
115 
116  SHAPE_ARC* new_arc = dynamic_cast<SHAPE_ARC*>( new_shape.get() );
117 
118  BOOST_REQUIRE( new_arc != nullptr );
119 
121  CheckArcGeom( *new_arc, aProps, aSynErrIU );
122 }
circular arc
Definition: shape.h:50
static void CheckArcGeom(const SHAPE_ARC &aArc, const ARC_PROPERTIES &aProps, const int aSynErrIU=1)
Check a SHAPE_ARC against a given set of geometric properties.
SHAPE * Clone() const override
Return a dynamically allocated copy of the shape.
Definition: shape_arc.h:79

References CheckArcGeom(), SHAPE_ARC::Clone(), and SH_ARC.

Referenced by BOOST_AUTO_TEST_CASE().

◆ CheckArcGeom()

static void CheckArcGeom ( const SHAPE_ARC aArc,
const ARC_PROPERTIES aProps,
const int  aSynErrIU = 1 
)
static

Check a SHAPE_ARC against a given set of geometric properties.

Parameters
aArcArc to test
aPropsProperties to test against
aSynErrIUPermitted error for synthetic points and dimensions (currently radius and center)

Check the chord agrees

All arcs are solid

Collisions will be checked elsewhere.

Definition at line 58 of file test_shape_arc.cpp.

59 {
60  // Angular error - note this can get quite large for very small arcs,
61  // as the integral position rounding has a relatively greater effect
62  const double angle_tol_deg = 1.0;
63 
64  // Position error - rounding to nearest integer
65  const int pos_tol = 1;
66 
67  BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
68  ( aProps.m_start_point )( aProps.m_start_point )( pos_tol ) );
69  BOOST_CHECK_PREDICATE(
70  KI_TEST::IsVecWithinTol<VECTOR2I>, ( aArc.GetP1() )( aProps.m_end_point )( pos_tol ) );
71  BOOST_CHECK_PREDICATE( KI_TEST::IsVecWithinTol<VECTOR2I>,
72  ( aArc.GetCenter() )( aProps.m_center_point )( aSynErrIU ) );
73  BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
74  ( aArc.GetCentralAngle() )( aProps.m_center_angle )( 360.0 )( angle_tol_deg ) );
75  BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
76  ( aArc.GetStartAngle() )( aProps.m_start_angle )( 360.0 )( angle_tol_deg ) );
77  BOOST_CHECK_PREDICATE( KI_TEST::IsWithinWrapped<double>,
78  ( aArc.GetEndAngle() )( aProps.m_end_angle )( 360.0 )( angle_tol_deg ) );
79  BOOST_CHECK_PREDICATE(
80  KI_TEST::IsWithin<double>, ( aArc.GetRadius() )( aProps.m_radius )( aSynErrIU ) );
81 
83  const auto chord = aArc.GetChord();
84 
85  BOOST_CHECK_PREDICATE(
86  KI_TEST::IsVecWithinTol<VECTOR2I>, ( chord.A )( aProps.m_start_point )( pos_tol ) );
87  BOOST_CHECK_PREDICATE(
88  KI_TEST::IsVecWithinTol<VECTOR2I>, ( chord.B )( aProps.m_end_point )( pos_tol ) );
89 
91  BOOST_CHECK_EQUAL( aArc.IsSolid(), true );
92 
93  BOOST_CHECK_PREDICATE(
94  KI_TEST::IsBoxWithinTol<BOX2I>, ( aArc.BBox() )( aProps.m_bbox )( pos_tol ) );
95 
97 }
VECTOR2I m_start_point
double GetRadius() const
Definition: shape_arc.cpp:402
double GetStartAngle() const
Definition: shape_arc.cpp:363
VECTOR2I m_end_point
VECTOR2I m_center_point
SEG GetChord() const
Definition: shape_arc.h:142
double GetEndAngle() const
Definition: shape_arc.cpp:373
bool IsSolid() const override
Definition: shape_arc.h:117
double GetCentralAngle() const
Definition: shape_arc.cpp:389
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:305
const VECTOR2I & GetP1() const
Definition: shape_arc.h:96
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:383

References SHAPE_ARC::BBox(), SHAPE_ARC::GetCenter(), SHAPE_ARC::GetCentralAngle(), SHAPE_ARC::GetChord(), SHAPE_ARC::GetEndAngle(), SHAPE_ARC::GetP1(), SHAPE_ARC::GetRadius(), SHAPE_ARC::GetStartAngle(), SHAPE_ARC::IsSolid(), ARC_PROPERTIES::m_bbox, ARC_PROPERTIES::m_center_angle, ARC_PROPERTIES::m_center_point, ARC_PROPERTIES::m_end_angle, ARC_PROPERTIES::m_end_point, ARC_PROPERTIES::m_radius, ARC_PROPERTIES::m_start_angle, and ARC_PROPERTIES::m_start_point.

Referenced by CheckArc().

Variable Documentation

◆ arc_cases

const std::vector<ARC_CPA_CASE> arc_cases
static

Definition at line 176 of file test_shape_arc.cpp.

Referenced by BOOST_AUTO_TEST_CASE().

◆ arc_pt_collide_cases

const std::vector<ARC_PT_COLLIDE_CASE> arc_pt_collide_cases
static

Definition at line 493 of file test_shape_arc.cpp.

Referenced by BOOST_AUTO_TEST_CASE().

◆ arc_ttr_cases

const std::vector<ARC_TTR_CASE> arc_ttr_cases
static

Definition at line 365 of file test_shape_arc.cpp.

Referenced by BOOST_AUTO_TEST_CASE().