KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_half_line.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) 2023 KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <geometry/half_line.h>
28
29#include "geom_test_utils.h"
30
31
33{
34};
35
37{
38 std::string Description;
41 std::optional<SEG> ExpectedClippedSeg;
42};
43
45{
46 std::string Description;
49 std::optional<VECTOR2I> ExpectedIntersection;
50};
51
53{
54 std::string Description;
58};
59
60BOOST_FIXTURE_TEST_SUITE( HalfLine, HalfLineFixture )
61
62
64{
65 const std::vector<HalfLineContainsPointCase> cases{
66 {
67 "Point on the ray",
68 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
69 VECTOR2I( 50, 50 ),
70 true,
71 },
72 {
73 "Point on the ray start",
74 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
75 VECTOR2I( 0, 0 ),
76 true,
77 },
78 {
79 "Point on the ray end",
80 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
81 VECTOR2I( 100, 100 ),
82 true,
83 },
84 {
85 "Point on the ray, past the end",
86 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
87 VECTOR2I( 150, 150 ),
88 true,
89 },
90 {
91 "Point on the infinite line, but on the wrong side",
92 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
93 VECTOR2I( -50, -50 ),
94 false,
95 },
96 {
97 "Point to one side",
98 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
99 VECTOR2I( 50, 0 ),
100 false,
101 }
102 };
103
104 for( const auto& c : cases )
105 {
106 BOOST_TEST_INFO( c.Description );
107
108 const bool contains = c.Hl.Contains( c.Point );
109
110 BOOST_TEST( contains == c.ExpectedContains );
111 }
112}
113
114
116{
117 const std::vector<HalfLineHalfLineIntersectionCase> cases{
118 {
119 "Simple cross",
120 HALF_LINE( SEG( VECTOR2I( -100, -100 ), VECTOR2I( 0, 0 ) ) ),
121 HALF_LINE( SEG( VECTOR2I( 100, -100 ), VECTOR2I( 0, 0 ) ) ),
122 VECTOR2I( 0, 0 ),
123 },
124 {
125 "Parallel, no intersection",
126 HALF_LINE( SEG( VECTOR2I( -100, 0 ), VECTOR2I( -100, 100 ) ) ),
127 HALF_LINE( SEG( VECTOR2I( 100, 0 ), VECTOR2I( 100, 100 ) ) ),
128 std::nullopt,
129 }
130 };
131
132 for( const auto& c : cases )
133 {
134 BOOST_TEST_INFO( c.Description );
135
136 std::optional<VECTOR2I> intersection = c.HlA.Intersect( c.HlB );
137
138 BOOST_REQUIRE( intersection.has_value() == c.ExpectedIntersection.has_value() );
139
140 if( !intersection )
141 continue;
142
143 BOOST_TEST( *intersection == *c.ExpectedIntersection );
144 }
145}
146
147
149{
150 const std::vector<HalfLineBoxClipCase> cases{
151 {
152 "Center to right edge",
153 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 0 ) ) ),
154 BOX2I{ VECTOR2{ -1000, -1000 }, VECTOR2{ 2000, 2000 } },
155 SEG( VECTOR2I( 0, 0 ), VECTOR2I( 1000, 0 ) ),
156 },
157 {
158 "Centre to corner",
159 HALF_LINE( SEG( VECTOR2I( 0, 0 ), VECTOR2I( 100, 100 ) ) ),
160 BOX2I{ VECTOR2{ -1000, -1000 }, VECTOR2{ 2000, 2000 } },
161 SEG( VECTOR2I( 0, 0 ), VECTOR2I( 1000, 1000 ) ),
162 },
163 {
164 "Ray not in the box",
165 HALF_LINE( SEG( VECTOR2I( 1500, 0 ), VECTOR2I( 1600, 0 ) ) ),
166 BOX2I{ VECTOR2{ -1000, -1000 }, VECTOR2{ 2000, 2000 } },
167 std::nullopt,
168 },
169 {
170 "Ray starts outside but crosses box",
171 HALF_LINE( SEG( VECTOR2I( -1500, 0 ), VECTOR2I( 0, 0 ) ) ),
172 BOX2I{ VECTOR2{ -1000, -1000 }, VECTOR2{ 2000, 2000 } },
173 SEG( VECTOR2I( -1000, 0 ), VECTOR2I( 1000, 0 ) ),
174 },
175 };
176
177 for( const auto& c : cases )
178 {
179 BOOST_TEST_INFO( c.Description );
180
181 std::optional<SEG> clipped = KIGEOM::ClipHalfLineToBox( c.Hl, c.Box );
182
183 BOOST_REQUIRE( clipped.has_value() == c.ExpectedClippedSeg.has_value() );
184
185 if( !clipped )
186 continue;
187
188 BOOST_CHECK_PREDICATE( GEOM_TEST::SegmentsHaveSameEndPoints,
189 ( *clipped )( *c.ExpectedClippedSeg ) );
190 }
191}
192
Definition: seg.h:42
bool SegmentsHaveSameEndPoints(const SEG &aSeg1, const SEG &aSeg2)
Check that two SEGs have the same end points, in either order.
std::optional< SEG > ClipHalfLineToBox(const HALF_LINE &aRay, const BOX2I &aBox)
Get the segment of a half-line that is inside a box, if any.
Definition: shape_utils.cpp:83
Utility functions for working with shapes.
std::optional< SEG > ExpectedClippedSeg
std::optional< VECTOR2I > ExpectedIntersection
BOOST_AUTO_TEST_CASE(Contains)
BOOST_AUTO_TEST_SUITE_END()
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691