KiCad PCB EDA Suite
test_fillet.cpp File Reference
#include <boost/test/unit_test.hpp>
#include <unit_test_utils/unit_test_utils.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_line_chain.h>
#include <algorithm>
#include "geom_test_utils.h"

Go to the source code of this file.

Classes

struct  FilletFixture
 
struct  SquareFilletTestCase
 

Functions

void TestFilletSegmentConstraints (const SEG &aSeg, VECTOR2I aRadCentre, int aRadius, int aError)
 Declares the FilletFixture struct as the boost test fixture. More...
 
void TestSquareFillet (int aSquareSize, int aRadius, int aError)
 : Create a square, fillet it, and check a corner for correctness More...
 
void TestConcaveSquareFillet (int aSquareSize, int aRadius, int aError)
 : Create a square concave corner, fillet and check correctness More...
 
 BOOST_AUTO_TEST_CASE (SquareFillet)
 Tests the SHAPE_POLY_SET::FilletPolygon method against certain geometric constraints. More...
 
 BOOST_AUTO_TEST_CASE (SquareConcaveFillet)
 

Variables

const std::vector< SquareFilletTestCasesquareFilletCases
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/2]

BOOST_AUTO_TEST_CASE ( SquareFillet  )

Tests the SHAPE_POLY_SET::FilletPolygon method against certain geometric constraints.

Definition at line 193 of file test_fillet.cpp.

194 {
195  for ( const auto& testCase : squareFilletCases )
196  {
197  TestSquareFillet( testCase.squareSize, testCase.radius, testCase.error );
198  }
199 }
void TestSquareFillet(int aSquareSize, int aRadius, int aError)
: Create a square, fillet it, and check a corner for correctness
Definition: test_fillet.cpp:79
const std::vector< SquareFilletTestCase > squareFilletCases

References squareFilletCases, and TestSquareFillet().

◆ BOOST_AUTO_TEST_CASE() [2/2]

BOOST_AUTO_TEST_CASE ( SquareConcaveFillet  )

Definition at line 201 of file test_fillet.cpp.

202 {
203  for ( const auto& testCase : squareFilletCases )
204  {
205  TestConcaveSquareFillet( testCase.squareSize, testCase.radius, testCase.error );
206  }
207 }
void TestConcaveSquareFillet(int aSquareSize, int aRadius, int aError)
: Create a square concave corner, fillet and check correctness
const std::vector< SquareFilletTestCase > squareFilletCases

References squareFilletCases, and TestConcaveSquareFillet().

◆ TestConcaveSquareFillet()

void TestConcaveSquareFillet ( int  aSquareSize,
int  aRadius,
int  aError 
)

: Create a square concave corner, fillet and check correctness

Definition at line 117 of file test_fillet.cpp.

118 {
119  using namespace GEOM_TEST;
120 
121  SHAPE_POLY_SET polySet;
122  SHAPE_LINE_CHAIN polyLine;
123 
124  /*
125  * L-shape:
126  * ----
127  * | |
128  * ---- |
129  * | |
130  * --------
131  */
132 
133  polyLine.Append( VECTOR2I{ 0, 0 } );
134  polyLine.Append( VECTOR2I{ 0, aSquareSize / 2 } );
135  polyLine.Append( VECTOR2I{ aSquareSize / 2 , aSquareSize / 2 } );
136  polyLine.Append( VECTOR2I{ aSquareSize / 2 , aSquareSize } );
137  polyLine.Append( VECTOR2I{ aSquareSize, aSquareSize } );
138  polyLine.Append( VECTOR2I{ aSquareSize, 0 } );
139 
140  polyLine.SetClosed( true );
141 
142  polySet.AddOutline( polyLine );
143 
144  SHAPE_POLY_SET filleted = FilletPolySet(polySet, aRadius, aError);
145 
146  // expect a single filleted polygon
147  BOOST_CHECK_EQUAL( filleted.OutlineCount(), 1 );
148 
149  auto segIter = filleted.IterateSegments();
150 
151  const VECTOR2I radCentre { aSquareSize / 2 - aRadius,
152  aSquareSize / 2 + aRadius };
153 
154  int checked = 0;
155 
156  for( ; segIter; segIter++ )
157  {
158  // Only check segments around the concave corner
159  if ( SegmentCompletelyWithinRadius( *segIter, radCentre, aRadius + 1) )
160  {
161  TestFilletSegmentConstraints( *segIter, radCentre, aRadius, aError );
162  checked++;
163  }
164  }
165 
166  // we expect there to be at least one segment in the fillet
167  BOOST_CHECK( checked > 0 );
168 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
SHAPE_POLY_SET FilletPolySet(SHAPE_POLY_SET &aPolySet, int aRadius, int aError)
BOOST_CHECK(v2.Cross(v1)==1)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
void SetClosed(bool aClosed)
Function SetClosed()
bool SegmentCompletelyWithinRadius(const SEG &aSeg, const VECTOR2I &aPt, const int aRadius)
Represent a set of closed polygons.
void TestFilletSegmentConstraints(const SEG &aSeg, VECTOR2I aRadCentre, int aRadius, int aError)
Declares the FilletFixture struct as the boost test fixture.
Definition: test_fillet.cpp:52
Utility functions for testing geometry functions.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
SHAPE_LINE_CHAIN.
SEGMENT_ITERATOR IterateSegments(int aFirst, int aLast, bool aIterateHoles=false)
Return an iterator object, for iterating between aFirst and aLast outline, with or without holes (def...

References SHAPE_POLY_SET::AddOutline(), SHAPE_LINE_CHAIN::Append(), BOOST_CHECK(), GEOM_TEST::FilletPolySet(), SHAPE_POLY_SET::IterateSegments(), SHAPE_POLY_SET::OutlineCount(), GEOM_TEST::SegmentCompletelyWithinRadius(), SHAPE_LINE_CHAIN::SetClosed(), and TestFilletSegmentConstraints().

Referenced by BOOST_AUTO_TEST_CASE().

◆ TestFilletSegmentConstraints()

void TestFilletSegmentConstraints ( const SEG aSeg,
VECTOR2I  aRadCentre,
int  aRadius,
int  aError 
)

Declares the FilletFixture struct as the boost test fixture.

Definition at line 52 of file test_fillet.cpp.

54 {
55  const auto diffA = aRadCentre - aSeg.A;
56  const auto diffB = aRadCentre - aSeg.B;
57  const auto diffC = aRadCentre - aSeg.Center();
58 
59  // Check 1: radii (error of 1 for rounding)
60  BOOST_CHECK_PREDICATE(
61  KI_TEST::IsWithinAndBelow<int>, ( diffA.EuclideanNorm() )( aRadius )( 1 ) );
62  BOOST_CHECK_PREDICATE(
63  KI_TEST::IsWithinAndBelow<int>, ( diffB.EuclideanNorm() )( aRadius )( 1 ) );
64 
65  // Check 2: Mid-point error
66  BOOST_CHECK_PREDICATE(
67  KI_TEST::IsWithinAndBelow<int>, ( diffC.EuclideanNorm() )( aRadius )( aError + 1 ) );
68 
69  // Check 3: Mid-point -> radius centre perpendicular
70  const auto perpendularityMaxError = ( M_PI / 2 ) / 10;
71  BOOST_CHECK_PREDICATE( GEOM_TEST::ArePerpendicular<int>,
72  ( diffC )( aSeg.A - aSeg.B )( perpendularityMaxError ) );
73 }
VECTOR2I Center() const
Definition: seg.h:391
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

Referenced by TestConcaveSquareFillet(), and TestSquareFillet().

◆ TestSquareFillet()

void TestSquareFillet ( int  aSquareSize,
int  aRadius,
int  aError 
)

: Create a square, fillet it, and check a corner for correctness

Definition at line 79 of file test_fillet.cpp.

80 {
81  using namespace GEOM_TEST;
82 
83  SHAPE_POLY_SET squarePolySet;
84 
85  squarePolySet.AddOutline( MakeSquarePolyLine(aSquareSize, VECTOR2I(0, 0) ) );
86 
87  SHAPE_POLY_SET filleted = FilletPolySet(squarePolySet, aRadius, aError);
88 
89  // expect a single filleted polygon
90  BOOST_CHECK_EQUAL( filleted.OutlineCount(), 1 );
91 
92  auto segIter = filleted.IterateSegments();
93 
94  const VECTOR2I radCentre { aSquareSize / 2 - aRadius,
95  aSquareSize / 2 - aRadius };
96 
97  int checked = 0;
98 
99  for( ; segIter; segIter++ )
100  {
101  // Only check the first Quadrant
102  if ( SegmentCompletelyInQuadrant( *segIter, QUADRANT::Q1 ) )
103  {
104  TestFilletSegmentConstraints( *segIter, radCentre, aRadius, aError );
105  checked++;
106  }
107  }
108 
109  // we expect there to be at least one segment in the fillet
110  BOOST_CHECK( checked > 0 );
111 }
int OutlineCount() const
Return the number of vertices in a given outline/hole.
SHAPE_POLY_SET FilletPolySet(SHAPE_POLY_SET &aPolySet, int aRadius, int aError)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
BOOST_CHECK(v2.Cross(v1)==1)
Represent a set of closed polygons.
SHAPE_LINE_CHAIN MakeSquarePolyLine(int aSize, const VECTOR2I &aCentre)
construct a square polygon of given size width and centre
void TestFilletSegmentConstraints(const SEG &aSeg, VECTOR2I aRadCentre, int aRadius, int aError)
Declares the FilletFixture struct as the boost test fixture.
Definition: test_fillet.cpp:52
Utility functions for testing geometry functions.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
bool SegmentCompletelyInQuadrant(const SEG &aSeg, QUADRANT aQuadrant)
SEGMENT_ITERATOR IterateSegments(int aFirst, int aLast, bool aIterateHoles=false)
Return an iterator object, for iterating between aFirst and aLast outline, with or without holes (def...

References SHAPE_POLY_SET::AddOutline(), BOOST_CHECK(), GEOM_TEST::FilletPolySet(), SHAPE_POLY_SET::IterateSegments(), GEOM_TEST::MakeSquarePolyLine(), SHAPE_POLY_SET::OutlineCount(), GEOM_TEST::Q1, GEOM_TEST::SegmentCompletelyInQuadrant(), and TestFilletSegmentConstraints().

Referenced by BOOST_AUTO_TEST_CASE().

Variable Documentation

◆ squareFilletCases

const std::vector<SquareFilletTestCase> squareFilletCases
Initial value:
{
{ 1000, 120, 10 },
{ 1000, 10, 1 },
{ 1000, 10, 5 },
{ 70000, 1000, 1 },
}

Definition at line 178 of file test_fillet.cpp.

Referenced by BOOST_AUTO_TEST_CASE().