KiCad PCB EDA Suite
test_shape_poly_set_distance.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2017 CERN
5 * @author Alejandro GarcĂ­a Montoro <[email protected]>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
26
28
31
33
35constexpr static double IU_PER_MM = 1e3;
36
37constexpr static inline int Millimeter2iu( double mm )
38{
39 return (int) ( mm < 0 ? mm * IU_PER_MM - 0.5 : mm * IU_PER_MM + 0.5 );
40}
41
42
46BOOST_AUTO_TEST_SUITE( SPSDistance )
47
49{
50 std::string m_case_name;
51
54
58
61};
62
63static std::vector<SPS_DISTANCE_TO_SEG_CASE> GetSPSSegDistCases()
64{
65 namespace KT = KI_TEST;
66 std::vector<SPS_DISTANCE_TO_SEG_CASE> cases;
67
68 // Single 10mm square at origin
69 const SHAPE_POLY_SET square_10mm_0_0 = KT::BuildPolyset( {
71 } );
72
73 // Double square: 10mm each, one at (0, 0), one at (10, 0)
74 const SHAPE_POLY_SET squares_10mm_0_0_and_20_0 = KT::BuildPolyset( {
77 { Millimeter2iu( 20 ), Millimeter2iu( 0 ) } ),
78 } );
79
80 // Hollow square: 10mm hole in 20mm square, at origin
81 const SHAPE_POLY_SET hollow_square_20_10_at_0_0 =
83
84 cases.push_back( {
85 "Square poly -> 1D segment",
86 square_10mm_0_0,
88 Millimeter2iu( 0 ), // 1-d segment
89 Millimeter2iu( 10 ),
90 } );
91
92 cases.push_back( {
93 "Square poly -> 2D (thick) segment",
94 square_10mm_0_0,
96 Millimeter2iu( 2 ), // thick segment
97 Millimeter2iu( 9 ),
98 } );
99
100 cases.push_back( {
101 "Two Squares poly -> 2D segment (nearest second square)", squares_10mm_0_0_and_20_0,
102 KT::BuildHSeg( { Millimeter2iu( 15 ), Millimeter2iu( 15 ) }, Millimeter2iu( 10 ) ),
103 Millimeter2iu( 2 ), // thick segment
104 Millimeter2iu( 9 ), // from line to second square
105 } );
106
107 cases.push_back( {
108 "Square poly -> one intersect", square_10mm_0_0,
109 KT::BuildHSeg( { Millimeter2iu( -5 ), Millimeter2iu( 0 ) }, Millimeter2iu( 10 ) ),
110 Millimeter2iu( 0 ), // 1-d segment
111 Millimeter2iu( 0 ), // intersect
112 } );
113
114 cases.push_back( {
115 "Square poly -> multiple intersection", square_10mm_0_0,
116 KT::BuildHSeg( { Millimeter2iu( -5 ), Millimeter2iu( 0 ) }, Millimeter2iu( 20 ) ),
117 Millimeter2iu( 0 ), // 1-d segment
118 Millimeter2iu( 0 ), // intersect
119 } );
120
121 cases.push_back( {
122 "Square poly -> 1D seg touching", square_10mm_0_0,
123 // touch left side at (-5, 0)
124 KT::BuildHSeg( { Millimeter2iu( -10 ), Millimeter2iu( 0 ) }, Millimeter2iu( 5 ) ),
125 Millimeter2iu( 0 ), // 2D segment
126 Millimeter2iu( 0 ), // intersect
127 } );
128
129 cases.push_back( {
130 "Square poly -> 2D seg (end cap is nearest)", square_10mm_0_0,
131 KT::BuildHSeg( { Millimeter2iu( -20 ), Millimeter2iu( 0 ) }, Millimeter2iu( 10 ) ),
132 Millimeter2iu( 2 ), // 2D segment, 1mm cap radius
133 Millimeter2iu( 4 ), // 4mm short, 5mm to wire end, -1mm radius
134 } );
135
136 return cases;
137};
138
143{
144 for( const auto& c : GetSPSSegDistCases() )
145 {
146 BOOST_TEST_CONTEXT( c.m_case_name )
147 {
148 SHAPE_POLY_SET polyset = c.m_polyset;
149
150 int dist = sqrt( polyset.SquaredDistance( c.m_seg ) ) - ( c.m_seg_width / 2 );
151
152 // right answer?
153 BOOST_CHECK_PREDICATE( KI_TEST::IsWithin<int>, ( dist )( c.m_exp_dist )( 1 ) );
154 }
155 }
156}
157
158BOOST_AUTO_TEST_SUITE_END()
Definition: seg.h:42
Represent a set of closed polygons.
SEG::ecoord SquaredDistance(VECTOR2I aPoint, VECTOR2I *aNearest=nullptr) const
Compute the minimum distance squared between aPoint and all the polygons in the set.
SHAPE_POLY_SET BuildHollowSquare(int aOuterSize, int aInnerSize, const VECTOR2I &aCentre)
Build a SHAPE_POLY_SET in the shape of a square outline, with a square hole, both centred at the give...
SHAPE_LINE_CHAIN BuildSquareChain(int aSize, const VECTOR2I &aCentre)
Builds a square SHAPE_LINE_CHAIN of a certain size at a certain centre.
SHAPE_POLY_SET BuildPolyset(const std::vector< SHAPE_LINE_CHAIN > &aOutlines)
Construct a SHAPE_POLY_SET from a list of points for each of outlines (no holes)
SEG BuildHSeg(const VECTOR2I &aStart, int aLength)
Build a horizontal segment from a point with a length.
Utilities for creating useful polygon shapes that are commonly found in QA utilities and tests.
Utilities for creating useful line chain idioms commonly founds in QA utilities and tests.
Declares the Boost test suite fixture.
SEG m_seg
the segment to check distance to
SHAPE_POLY_SET m_polyset
list of lists of polygon points
static constexpr int Millimeter2iu(double mm)
static constexpr double IU_PER_MM
Mock up a conversion function.
BOOST_AUTO_TEST_CASE(SegDistance)
Check segment distances.
static std::vector< SPS_DISTANCE_TO_SEG_CASE > GetSPSSegDistCases()
#define BOOST_TEST_CONTEXT(A)