KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_item_realignment.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
22#include <item_realignment.h>
23
24
34
35
36BOOST_FIXTURE_TEST_SUITE( ItemRealignmentTestSuite, ItemRealignmentOrthoTestFixture )
37
38
40{
41 // Make sure that two identical sets of points are aligned with no transform
42
43 std::vector<VECTOR2I> ptsA{
44 { 0, 0 },
45 { 0, 1000 },
46 };
47 std::vector<VECTOR2I> ptsB = ptsA;
48
49 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
50
51 BOOST_REQUIRE( transform.has_value() );
52 BOOST_TEST( transform->m_Rotation == ANGLE_0 );
53 BOOST_TEST( transform->m_Translation == VECTOR2I( 0, 0 ) );
54}
55
56
57BOOST_AUTO_TEST_CASE( SimpleRotation )
58{
59 std::vector<VECTOR2I> ptsA{
60 { 0, 0 },
61 { 1000, 0 },
62 };
63 std::vector<VECTOR2I> ptsB{
64 { 0, 0 },
65 { 0, 1000 },
66 };
67
68 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
69
70 BOOST_REQUIRE( transform.has_value() );
71 BOOST_TEST( transform->m_Rotation == ANGLE_90 );
72 BOOST_TEST( transform->m_Translation == VECTOR2I( 0, 0 ) );
73}
74
75
76BOOST_AUTO_TEST_CASE( AlmostRotation )
77{
78 std::vector<VECTOR2I> ptsA{
79 { 0, 0 },
80 { 1000, 0 },
81 };
82 // One point moved a bit, but we will interpret that as a point moved,
83 // rather than a tiny rotation of the whole thing.
84 std::vector<VECTOR2I> ptsB{
85 { 0, 0 },
86 { 1000, 10 },
87 };
88
89 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
90
91 BOOST_REQUIRE( transform.has_value() );
92 BOOST_TEST( transform->m_Rotation == ANGLE_0 );
93 BOOST_TEST( transform->m_Translation == VECTOR2I( 0, -5 ) );
94}
95
96
97BOOST_AUTO_TEST_CASE( MinorityOfPointsMoved )
98{
99 // In this case, the points don't rotate, but one of the points moves.
100 // We want to leave the transform still locked to the matching 3 points, and let
101 // the one outlier point be the one that moves.
102
103 std::vector<VECTOR2I> ptsA = {
104 { 0, 0 },
105 { 1000, 0 },
106 { 0, 1000 },
107 { 1000, 1000 },
108 };
109 std::vector<VECTOR2I> ptsB = {
110 { 0, 0 },
111 { 1000, 10 },
112 { 0, 1000 },
113 { 1000, 1000 },
114 };
115
116 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
117
118 BOOST_REQUIRE( transform.has_value() );
119 BOOST_TEST( transform->m_Rotation == ANGLE_0 );
120 BOOST_TEST( transform->m_Translation == VECTOR2I( 0, 0 ) );
121}
122
123
124BOOST_AUTO_TEST_CASE( PointsSpacedApart )
125{
126 // In this case, all the points move apart - this is like a gullwing having the
127 // the pad lengths changed. In this case, we want the transform to minimise
128 // the error, rather than saying locked down one side.
129
130 const int pitchXA = 1000;
131 const int pitchY = 1000;
132 const int pitchXB = 1100;
133
134 // Note - the points aren't centred over the origin - this is
135 // intentional so the transform doesn't just equal zero.
136 std::vector<VECTOR2I> ptsA {
137 { 0, -pitchY },
138 { 0, 0 },
139 { 0, pitchY },
140 { pitchXA, -pitchY },
141 { pitchXA, 0 },
142 { pitchXA, pitchY },
143 };
144 std::vector<VECTOR2I> ptsB {
145 { 0, -pitchY },
146 { 0, 0 },
147 { 0, pitchY },
148 { pitchXB, -pitchY },
149 { pitchXB, 0 },
150 { pitchXB, pitchY },
151 };
152
153 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
154
155 const int expectedTranslationX = -std::abs( pitchXB - pitchXA ) / 2;
156 const int expectedTranslationY = 0;
157
158 BOOST_REQUIRE( transform.has_value() );
159 BOOST_TEST( transform->m_Rotation == ANGLE_0 );
160 BOOST_TEST( transform->m_Translation == VECTOR2I( expectedTranslationX, expectedTranslationY ) );
161}
162
163
164BOOST_AUTO_TEST_CASE( RotateAndMove )
165{
166 // In this case, the points are rotated and moved.
167
168 const int pitch = 1000;
169
170 // Rectangle 2000x1000 centred on 0,0
171 std::vector<VECTOR2I> ptsA = {
172 { -1000, -500 },
173 { -1000, 500 },
174 { 1000, -500 },
175 { 1000, 500 },
176 };
177 // Same rectangle, but rotated 90 degrees ACW and centred on (1000,1000)
178 std::vector<VECTOR2I> ptsB = {
179 { 500, 2000 },
180 { 1500, 2000 },
181 { 500, 0 },
182 { 1500, 0 },
183 };
184
185 std::optional<ITEM_REALIGNER_BASE::TRANSFORM> transform = m_aligner.GetTransform( ptsA, ptsB );
186
187 // The expected translation is applied after the rotation about the origin,
188 // so ptB[0] wll be rotated to (0, 500). Then to get to the expected position of ptsA[0] = (-1000, -500), we need to translate by (1000, -1000)
189 const VECTOR2I expectedTranslation( 1000, -1000 );
190
191 BOOST_REQUIRE( transform.has_value() );
192 BOOST_TEST( transform->m_Rotation == ANGLE_270 ); // 90 CW
193 BOOST_TEST( transform->m_Translation == expectedTranslation );
194}
195
196
This is a relatively straight-forward implementation of the ITEM_REALIGNER_BASE that should handle mo...
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:416
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_TEST(contains==c.ExpectedContains)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(SimpleNull)
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687