KiCad PCB EDA Suite
GEOM_TEST Namespace Reference

Utility functions for testing geometry functions. More...

Enumerations

enum class  QUADRANT { Q1 , Q2 , Q3 , Q4 }
 Geometric quadrants, from top-right, anti-clockwise. More...
 

Functions

template<typename T >
bool IsInQuadrant (const VECTOR2< T > &aPoint, QUADRANT aQuadrant)
 
bool SegmentCompletelyInQuadrant (const SEG &aSeg, QUADRANT aQuadrant)
 
bool SegmentEndsInQuadrant (const SEG &aSeg, QUADRANT aQuadrant)
 
bool SegmentCompletelyWithinRadius (const SEG &aSeg, const VECTOR2I &aPt, const int aRadius)
 
template<typename T >
bool IsPointAtDistance (const VECTOR2< T > &aPtA, const VECTOR2< T > &aPtB, T aExpDist, T aTol)
 Check that two points are the given distance apart, within the given tolerance. More...
 
template<typename T >
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. More...
 
template<typename T >
bool ArePerpendicular (const VECTOR2< T > &a, const VECTOR2< T > &b, const EDA_ANGLE &aTolerance)
 
SHAPE_LINE_CHAIN MakeSquarePolyLine (int aSize, const VECTOR2I &aCentre)
 construct a square polygon of given size width and centre More...
 
SHAPE_POLY_SET FilletPolySet (SHAPE_POLY_SET &aPolySet, int aRadius, int aError)
 
bool IsOutlineValid (const SHAPE_LINE_CHAIN &aChain)
 Verify that a SHAPE_LINE_CHAIN has been assembled correctly by ensuring that the arc start and end points match points on the chain and that any points inside the arcs actually collide with the arc segments (with an error margin of 5000 IU) More...
 
bool IsPolySetValid (const SHAPE_POLY_SET &aSet)
 Verify that a SHAPE_POLY_SET has been assembled correctly by verifying each of the outlines and holes contained within. More...
 

Detailed Description

Utility functions for testing geometry functions.

Enumeration Type Documentation

◆ QUADRANT

enum class GEOM_TEST::QUADRANT
strong

Geometric quadrants, from top-right, anti-clockwise.

^ y
|

Q2 | Q1 ----—> x Q3 | Q4

Enumerator
Q1 
Q2 
Q3 
Q4 

Definition at line 51 of file geom_test_utils.h.

Function Documentation

◆ ArePerpendicular()

template<typename T >
bool GEOM_TEST::ArePerpendicular ( const VECTOR2< T > &  a,
const VECTOR2< T > &  b,
const EDA_ANGLE aTolerance 
)

Definition at line 172 of file geom_test_utils.h.

173{
174 EDA_ANGLE angle = std::abs( EDA_ANGLE( a ) - EDA_ANGLE( b ) );
175
176 // Normalise: angles of 3*pi/2 are also perpendicular
177 if (angle > ANGLE_180)
178 angle -= ANGLE_180;
179
180 return KI_TEST::IsWithin( angle.AsRadians(), ANGLE_90.AsRadians(), aTolerance.AsRadians() );
181}
double AsRadians() const
Definition: eda_angle.h:153
static constexpr EDA_ANGLE & ANGLE_180
Definition: eda_angle.h:433
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
bool IsWithin(T aValue, T aNominal, T aError)
Check if a value is within a tolerance of a nominal value.
Definition: numeric.h:57
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418

References std::abs(), PNS::angle(), ANGLE_180, ANGLE_90, EDA_ANGLE::AsRadians(), and KI_TEST::IsWithin().

◆ ArePointsNearCircle()

template<typename T >
bool GEOM_TEST::ArePointsNearCircle ( const std::vector< VECTOR2< T > > &  aPoints,
const VECTOR2< T > &  aCentre,
aRad,
aTol 
)

Predicate for checking a set of points is within a certain tolerance of a circle.

Parameters
aPointsthe points to check
aCentrethe circle centre
aRadthe circle radius
aTolEndsthe tolerance for the endpoint-centre distance
Returns
true if predicate met

Definition at line 144 of file geom_test_utils.h.

146{
147 bool ok = true;
148
149 for( unsigned i = 0; i < aPoints.size(); ++i )
150 {
151 if( !IsPointAtDistance( aPoints[i], aCentre, aRad, aTol ) )
152 {
153 BOOST_TEST_INFO( "Point " << i << " " << aPoints[i] << " is not within tolerance ("
154 << aTol << ") of radius (" << aRad << ") from centre point "
155 << aCentre );
156 ok = false;
157 }
158 }
159
160 return ok;
161}
bool IsPointAtDistance(const VECTOR2< T > &aPtA, const VECTOR2< T > &aPtB, T aExpDist, T aTol)
Check that two points are the given distance apart, within the given tolerance.
#define BOOST_TEST_INFO(A)
If HAVE_EXPECTED_FAILURES is defined, this means that boost::unit_test::expected_failures is availabl...

References BOOST_TEST_INFO, and IsPointAtDistance().

Referenced by ArePolylineEndPointsNearCircle(), and ArePolylineMidPointsNearCircle().

◆ FilletPolySet()

SHAPE_POLY_SET GEOM_TEST::FilletPolySet ( SHAPE_POLY_SET aPolySet,
int  aRadius,
int  aError 
)
inline

Definition at line 208 of file geom_test_utils.h.

209{
210 SHAPE_POLY_SET filletedPolySet;
211
212 for ( int i = 0; i < aPolySet.OutlineCount(); ++i )
213 {
214 const auto filleted = aPolySet.FilletPolygon( aRadius, aError, i );
215
216 filletedPolySet.AddOutline( filleted[0] );
217 }
218
219 return filletedPolySet;
220}
Represent a set of closed polygons.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
POLYGON FilletPolygon(unsigned int aRadius, int aErrorMax, int aIndex)
Return a filleted version of the aIndex-th polygon.
int OutlineCount() const
Return the number of vertices in a given outline/hole.

References SHAPE_POLY_SET::AddOutline(), SHAPE_POLY_SET::FilletPolygon(), and SHAPE_POLY_SET::OutlineCount().

Referenced by TestConcaveSquareFillet(), and TestSquareFillet().

◆ IsInQuadrant()

template<typename T >
bool GEOM_TEST::IsInQuadrant ( const VECTOR2< T > &  aPoint,
QUADRANT  aQuadrant 
)

Definition at line 59 of file geom_test_utils.h.

60{
61 bool isInQuad = false;
62
63 switch( aQuadrant )
64 {
65 case QUADRANT::Q1:
66 isInQuad = aPoint.x >= 0 && aPoint.y >= 0;
67 break;
68 case QUADRANT::Q2:
69 isInQuad = aPoint.x <= 0 && aPoint.y >= 0;
70 break;
71 case QUADRANT::Q3:
72 isInQuad = aPoint.x <= 0 && aPoint.y <= 0;
73 break;
74 case QUADRANT::Q4:
75 isInQuad = aPoint.x >= 0 && aPoint.y <= 0;
76 break;
77 }
78
79 return isInQuad;
80}

References Q1, Q2, Q3, Q4, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SegmentCompletelyInQuadrant(), and SegmentEndsInQuadrant().

◆ IsOutlineValid()

bool GEOM_TEST::IsOutlineValid ( const SHAPE_LINE_CHAIN aChain)
inline

Verify that a SHAPE_LINE_CHAIN has been assembled correctly by ensuring that the arc start and end points match points on the chain and that any points inside the arcs actually collide with the arc segments (with an error margin of 5000 IU)

Parameters
aChainto test
Returns
true if outline is valid

Definition at line 230 of file geom_test_utils.h.

231{
232 ssize_t prevArcIdx = -1;
233 std::set<size_t> testedArcs;
234
235 for( int i = 0; i < aChain.PointCount(); i++ )
236 {
237 ssize_t arcIdx = aChain.ArcIndex( i );
238
239 if( arcIdx >= 0 )
240 {
241 // Point on arc, lets make sure it collides with the arc shape and we haven't
242 // previously seen the same arc index
243
244 if( prevArcIdx != arcIdx && testedArcs.count( arcIdx ) )
245 return false; // we've already seen this arc before, not contiguous
246
247 if( !aChain.Arc( arcIdx ).Collide( aChain.CPoint( i ),
249 {
250 return false;
251 }
252
253 testedArcs.insert( arcIdx );
254 }
255
256 if( prevArcIdx != arcIdx )
257 {
258 // we have changed arc shapes, run a few extra tests
259
260 if( prevArcIdx >= 0 )
261 {
262 // prev point on arc, test that the last arc point on the chain
263 // matches the end point of the arc
264 VECTOR2I pointToTest = aChain.CPoint( i );
265
266 if( !aChain.IsSharedPt( i ) )
267 pointToTest = aChain.CPoint( i - 1 );
268
269 SHAPE_ARC lastArc = aChain.Arc( prevArcIdx );
270
271 if( lastArc.GetP1() != pointToTest )
272 return false;
273 }
274
275 if( arcIdx >= 0 )
276 {
277 // new arc, test that the start point of the arc matches the point on the chain
278 VECTOR2I pointToTest = aChain.CPoint( i );
279 SHAPE_ARC currentArc = aChain.Arc( arcIdx );
280
281 if( currentArc.GetP0() != pointToTest )
282 return false;
283 }
284 }
285
286 prevArcIdx = arcIdx;
287 }
288
289 return true;
290}
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
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
static double DefaultAccuracyForPCB()
Definition: shape_arc.h:221
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112
const SHAPE_ARC & Arc(size_t aArc) const
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
bool IsSharedPt(size_t aIndex) const
Test if a point is shared between multiple shapes.

References SHAPE_LINE_CHAIN::Arc(), SHAPE_LINE_CHAIN::ArcIndex(), SHAPE_ARC::Collide(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_ARC::DefaultAccuracyForPCB(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), SHAPE_LINE_CHAIN::IsSharedPt(), and SHAPE_LINE_CHAIN::PointCount().

Referenced by BOOST_AUTO_TEST_CASE(), and IsPolySetValid().

◆ IsPointAtDistance()

template<typename T >
bool GEOM_TEST::IsPointAtDistance ( const VECTOR2< T > &  aPtA,
const VECTOR2< T > &  aPtB,
aExpDist,
aTol 
)

Check that two points are the given distance apart, within the given tolerance.

Template Parameters
Tthe dimension type
Parameters
aPtAthe first point
aPtBthe second point
aExpDistthe expected distance
aTolthe permitted tolerance

Definition at line 120 of file geom_test_utils.h.

121{
122 const int dist = ( aPtB - aPtA ).EuclideanNorm();
123 const bool ok = KI_TEST::IsWithin( dist, aExpDist, aTol );
124
125 if( !ok )
126 {
127 BOOST_TEST_INFO( "Points not at expected distance: distance is " << dist << ", expected "
128 << aExpDist );
129 }
130
131 return ok;
132}
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129

References BOOST_TEST_INFO, EuclideanNorm(), and KI_TEST::IsWithin().

Referenced by ArePointsNearCircle().

◆ IsPolySetValid()

bool GEOM_TEST::IsPolySetValid ( const SHAPE_POLY_SET aSet)
inline

Verify that a SHAPE_POLY_SET has been assembled correctly by verifying each of the outlines and holes contained within.

Parameters
aSetto test
Returns
true if the poly set is valid

Definition at line 299 of file geom_test_utils.h.

300{
301 for( int i = 0; i < aSet.OutlineCount(); i++ )
302 {
303 if( !IsOutlineValid( aSet.Outline( i ) ) )
304 return false;
305
306 for( int j = 0; j < aSet.HoleCount( i ); j++ )
307 {
308 if( !IsOutlineValid( aSet.CHole( i, j ) ) )
309 return false;
310 }
311 }
312
313 return true;
314}
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
const SHAPE_LINE_CHAIN & CHole(int aOutline, int aHole) const
bool IsOutlineValid(const SHAPE_LINE_CHAIN &aChain)
Verify that a SHAPE_LINE_CHAIN has been assembled correctly by ensuring that the arc start and end po...

References SHAPE_POLY_SET::CHole(), SHAPE_POLY_SET::HoleCount(), IsOutlineValid(), SHAPE_POLY_SET::Outline(), and SHAPE_POLY_SET::OutlineCount().

Referenced by BOOST_AUTO_TEST_CASE().

◆ MakeSquarePolyLine()

SHAPE_LINE_CHAIN GEOM_TEST::MakeSquarePolyLine ( int  aSize,
const VECTOR2I aCentre 
)
inline

construct a square polygon of given size width and centre

Parameters
aSizethe side width (must be divisible by 2 if want to avoid rounding)
aCentrethe centre of the square

Definition at line 189 of file geom_test_utils.h.

190{
191 SHAPE_LINE_CHAIN polyLine;
192
193 const VECTOR2I corner = aCentre + aSize / 2;
194
195 polyLine.Append( VECTOR2I( corner.x, corner.y ) );
196 polyLine.Append( VECTOR2I( -corner.x, corner.y ) ) ;
197 polyLine.Append( VECTOR2I( -corner.x, -corner.y ) );
198 polyLine.Append( VECTOR2I( corner.x, -corner.y ) );
199
200 polyLine.SetClosed( true );
201
202 return polyLine;
203}
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::SetClosed(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by TestSquareFillet().

◆ SegmentCompletelyInQuadrant()

bool GEOM_TEST::SegmentCompletelyInQuadrant ( const SEG aSeg,
QUADRANT  aQuadrant 
)
inline

Definition at line 85 of file geom_test_utils.h.

86{
87 return IsInQuadrant( aSeg.A, aQuadrant)
88 && IsInQuadrant( aSeg.B, aQuadrant );
89}
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
bool IsInQuadrant(const VECTOR2< T > &aPoint, QUADRANT aQuadrant)

References SEG::A, SEG::B, and IsInQuadrant().

Referenced by TestSquareFillet().

◆ SegmentCompletelyWithinRadius()

bool GEOM_TEST::SegmentCompletelyWithinRadius ( const SEG aSeg,
const VECTOR2I aPt,
const int  aRadius 
)
inline

Definition at line 103 of file geom_test_utils.h.

104{
105 // This is true iff both ends of the segment are within the radius
106 return ( ( aSeg.A - aPt ).EuclideanNorm() < aRadius )
107 && ( ( aSeg.B - aPt ).EuclideanNorm() < aRadius );
108}

References SEG::A, SEG::B, and EuclideanNorm().

Referenced by TestConcaveSquareFillet().

◆ SegmentEndsInQuadrant()

bool GEOM_TEST::SegmentEndsInQuadrant ( const SEG aSeg,
QUADRANT  aQuadrant 
)
inline

Definition at line 94 of file geom_test_utils.h.

95{
96 return IsInQuadrant( aSeg.A, aQuadrant )
97 || IsInQuadrant( aSeg.B, aQuadrant );
98}

References SEG::A, SEG::B, and IsInQuadrant().