KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_vector2.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 The 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, see <https://www.gnu.org/licenses/>.
18 */
19
23
25
26// Code under test
27#include <math/vector2d.h>
28
32BOOST_AUTO_TEST_SUITE( VECTOR2TESTS )
33
35{
36 constexpr VECTOR2I vi_1_2{ 1, 2 };
37 // Something to test at runtime
38 BOOST_TEST( vi_1_2 == VECTOR2I( 1, 2 ) );
39 static_assert( vi_1_2.x == 1 );
40 static_assert( vi_1_2.y == 2 );
41
42 constexpr VECTOR2I vi_3_5 = vi_1_2 + VECTOR2I( 3, 4 ) - VECTOR2I( 1, 1 );
43
44 static_assert( vi_3_5 == VECTOR2I( 3, 5 ) );
45
46 static_assert( vi_3_5.SquaredEuclideanNorm() == 9 + 25 );
47 static_assert( vi_3_5 > vi_1_2 );
48 static_assert( vi_1_2 < vi_3_5 );
49 static_assert( vi_1_2 != vi_3_5 );
50 static_assert( vi_1_2 <= vi_1_2 );
51 static_assert( vi_1_2 >= vi_1_2 );
52
53 static_assert( vi_1_2.SquaredDistance( vi_3_5 ) == 4 + 9 );
54
55 static_assert( LexicographicalCompare( vi_1_2, vi_3_5 ) < 0 );
56 // Was the copy avoided?
57 static_assert( &LexicographicalMin( vi_1_2, vi_3_5 ) == &vi_1_2 );
58 static_assert( &LexicographicalMin( vi_1_2, vi_3_5 ) == &vi_1_2 );
59
60 constexpr VECTOR2D vd_1_2{ 1.0, 2.0 };
61 constexpr VECTOR2D vd_3_4{ 3.0, 4.0 };
62
63 static_assert( vd_1_2 == VECTOR2D( 1.0, 2.0 ) );
64 static_assert( vd_1_2 != vd_3_4 );
65 static_assert( vd_1_2 < vd_3_4 );
66 static_assert( vd_1_2 <= vd_3_4 );
67 static_assert( vd_3_4 > vd_1_2 );
68
69 // After C++23
70 //static_assert( equals( vd_1_2, vd_3_4, 2.0 ) );
71}
72
73BOOST_AUTO_TEST_CASE( test_cross_product, *boost::unit_test::tolerance( 0.000001 ) )
74{
75 VECTOR2I v1(0, 1);
76 VECTOR2I v2(1, 0);
77
78 BOOST_TEST( v2.Cross( v1 ) == 1 );
79}
80
81BOOST_AUTO_TEST_CASE( test_dot_product, *boost::unit_test::tolerance( 0.000001 ) )
82{
83 VECTOR2I v1( 0, 1 );
84 VECTOR2I v2( 1, 0 );
85
86 BOOST_TEST( v2.Dot( v1 ) == 0 );
87}
88
89BOOST_AUTO_TEST_CASE( test_euclidean_norm_exact )
90{
91 const int imin = std::numeric_limits<int>::min();
92 const int imax = std::numeric_limits<int>::max();
93
94 // std::hypot rounds this one to 95556683
95 BOOST_CHECK_EQUAL( VECTOR2I( 175139, 95556522 ).EuclideanNorm(), 95556682 );
96
97 BOOST_CHECK_EQUAL( VECTOR2I( imin, 0 ).EuclideanNorm(), imax );
98 BOOST_CHECK_EQUAL( VECTOR2I( imin, imin ).EuclideanNorm(), imax );
99 BOOST_CHECK_EQUAL( VECTOR2I( imin, imin ).SquaredEuclideanNorm(), std::numeric_limits<int64_t>::max() );
100}
101
102BOOST_AUTO_TEST_CASE( test_euclidean_norm_int64_exact )
103{
104 const int64_t lmin = std::numeric_limits<int64_t>::min();
105 const int64_t lmax = std::numeric_limits<int64_t>::max();
106
107 // std::hypot rounds this to a multiple of the double spacing, 1414213562373095168
108 BOOST_CHECK_EQUAL( VECTOR2L( 1000000000000000003, 1000000000000000007 ).EuclideanNorm(), 1414213562373095056 );
109
110 BOOST_CHECK_EQUAL( VECTOR2L( lmin, 0 ).EuclideanNorm(), lmax );
111 BOOST_CHECK_EQUAL( VECTOR2L( lmin, 0 ).SquaredEuclideanNorm(), lmax );
112}
113
114BOOST_AUTO_TEST_CASE( test_resize, *boost::unit_test::tolerance( 0.000001 ) )
115{
116 // just some arbitrary vectors
117 VECTOR2I v1( 4, 3 );
118 VECTOR2I v2( 5, -1 );
119 VECTOR2I v3( -2, 1 );
120 VECTOR2I v4( 1, 1 );
121 VECTOR2I v5( -70, -70 );
122
123 BOOST_TEST( v1.Resize( 8 ) == VECTOR2I( 6, 5 ) );
124 BOOST_TEST( v2.Resize( 10 ) == VECTOR2I( 10, -2 ) );
125 BOOST_TEST( v3.Resize( 4 ) == VECTOR2I( -4, 2 ) );
126 BOOST_TEST( v4.Resize( 1 ) == VECTOR2I( 1, 1 ) );
127 BOOST_TEST( v5.Resize( 100 ) == VECTOR2I( -71, -71 ) );
128}
129
130BOOST_AUTO_TEST_CASE( test_casting )
131{
132 VECTOR2I vint( 4, 3 );
133 VECTOR2D vdouble( 4.0, 3.0 );
134 VECTOR2L vlong( 4, 3 );
135 VECTOR2<float> vfloat( 4.0f, 3.0f );
136 VECTOR2<unsigned> vunsigned( 4, 3 );
137
138 BOOST_CHECK_EQUAL( vint, VECTOR2I( vdouble ) );
139 BOOST_CHECK_EQUAL( vint, VECTOR2I( vlong ) );
140 BOOST_CHECK_EQUAL( vint, VECTOR2I( vfloat ) );
141 BOOST_CHECK_EQUAL( vint, VECTOR2I( vunsigned ) );
142
143 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( vint ) );
144 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( vlong ) );
145 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( vfloat ) );
146 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( vunsigned ) );
147
148 BOOST_CHECK_EQUAL( vlong, VECTOR2L( vint ) );
149 BOOST_CHECK_EQUAL( vlong, VECTOR2L( vdouble ) );
150 BOOST_CHECK_EQUAL( vlong, VECTOR2L( vfloat ) );
151 BOOST_CHECK_EQUAL( vlong, VECTOR2L( vunsigned ) );
152
153 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( vint ) );
154 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( vdouble ) );
155 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( vlong ) );
156 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( vunsigned ) );
157
158 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( vint ) );
159 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( vdouble ) );
160 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( vlong ) );
161 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( vfloat ) );
162
163 // Check that negative values are handled correctly
164 vint = vint - 1;
165 vdouble = vdouble - 1;
166 vlong = vlong - 1;
167 vfloat = vfloat - 1;
168 vunsigned = vunsigned - 1;
169
170 BOOST_CHECK_EQUAL( vint, VECTOR2I( 3, 2 ) );
171 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( 3.0, 2.0 ) );
172 BOOST_CHECK_EQUAL( vlong, VECTOR2L( 3, 2 ) );
173 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( 3.0f, 2.0f ) );
174 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 3, 2 ) );
175
176 // Check that subtracting unsigned values works correctly
177 vint = vint - (unsigned)1;
178 vdouble = vdouble - (unsigned)1;
179 vlong = vlong - (unsigned)1;
180 vfloat = vfloat - (unsigned)1;
181 vunsigned = vunsigned - (unsigned)1;
182
183 BOOST_CHECK_EQUAL( vint, VECTOR2I( 2, 1 ) );
184 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( 2.0, 1.0 ) );
185 BOOST_CHECK_EQUAL( vlong, VECTOR2L( 2, 1 ) );
186 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( 2.0f, 1.0f ) );
187 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 2, 1 ) );
188
189 vint = vint - 5.0;
190 vdouble = vdouble - 5.0;
191 vlong = vlong - 5.0;
192 vfloat = vfloat - 5.0;
193 vunsigned = vunsigned - 5.0;
194
195 BOOST_CHECK_EQUAL( vint, VECTOR2I( -3, -4 ) );
196 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( -3.0, -4.0 ) );
197 BOOST_CHECK_EQUAL( vlong, VECTOR2L( -3, -4 ) );
198 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( -3.0f, -4.0f ) );
199 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 4294967293, 4294967292 ) ); // roll over unsigned when explicitly subtracting.
200
201 // Check that negative initial values are handled correctly
202 vint = VECTOR2I( -4, -3 );
203 vdouble = VECTOR2D( -4.0, -3.0 );
204 vlong = VECTOR2L( -4, -3 );
205 vfloat = VECTOR2<float>( -4.0f, -3.0f );
206 vunsigned = VECTOR2<unsigned>( -4, -3 );
207
208 vint = vint - 1;
209 vdouble = vdouble - 1;
210 vlong = vlong - 1;
211 vfloat = vfloat - 1;
212 vunsigned = vunsigned - 1;
213
214 BOOST_CHECK_EQUAL( vint, VECTOR2I( -5, -4 ) );
215 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( -5.0, -4.0 ) );
216 BOOST_CHECK_EQUAL( vlong, VECTOR2L( -5, -4 ) );
217 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( -5.0f, -4.0f ) );
218 BOOST_CHECK_EQUAL( vunsigned, VECTOR2<unsigned>( 4294967291, 4294967292 ) );
219
220 vint = vint - 1u;
221 vdouble = vdouble - 1u;
222 vlong = vlong - 1u;
223 vfloat = vfloat - 1u;
224
225 BOOST_CHECK_EQUAL( vint, VECTOR2I( -6, -5 ) );
226 BOOST_CHECK_EQUAL( vdouble, VECTOR2D( -6.0, -5.0 ) );
227 BOOST_CHECK_EQUAL( vlong, VECTOR2L( -6, -5 ) );
228 BOOST_CHECK_EQUAL( vfloat, VECTOR2<float>( -6.0f, -5.0f ) );
229
230 auto add = vint + vdouble;
231 BOOST_CHECK_EQUAL( add, VECTOR2D( -12.0, -10.0 ) );
232
233 auto sub = vint - 2 * vlong;
234 BOOST_CHECK_EQUAL( sub.x, 6 );
235 BOOST_CHECK_EQUAL( sub.y, 5 );
236
237 vunsigned = VECTOR2<unsigned>( std::numeric_limits<unsigned>::max(), std::numeric_limits<unsigned>::max() );
238 vint = VECTOR2I( vunsigned );
239 BOOST_CHECK_EQUAL( vint.x, std::numeric_limits<int>::max() );
240
241 vunsigned += 1;
242 BOOST_CHECK_EQUAL( vunsigned.x, 0 );
243}
244
Define a general 2D-vector/point.
Definition vector2d.h:67
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition vector2d.h:312
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_TEST(netlist.find("R_G1 ARM_OUT1 DIE_B R='0.001 / ((SW_STATE)") !=std::string::npos)
VECTOR3I v1(5, 5, 5)
BOOST_CHECK_EQUAL(result, "25.4")
BOOST_AUTO_TEST_CASE(Constexpr)
Test suite for KiCad math code.
VECTOR2I v2(1, 0)
VECTOR2I v4(1, 1)
VECTOR2I v5(-70, -70)
VECTOR2I v3(-2, 1)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707
constexpr const VECTOR2< T > & LexicographicalMin(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition vector2d.h:645
VECTOR2< int64_t > VECTOR2L
Definition vector2d.h:709
constexpr int LexicographicalCompare(const VECTOR2< T > &aA, const VECTOR2< T > &aB)
Definition vector2d.h:657