KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_eda_shape.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 3
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 */
17
18
20
21#include <eda_shape.h>
23#include <qa_utils/geometry/geometry.h> // For KI_TEST::IsVecWithinTol
24#include <geometry/shape_arc.h> // For SHAPE_ARC::DefaultAccuracyForPCB()
25
26
27BOOST_AUTO_TEST_SUITE( EdaShape )
28
30{
31public:
32 EDA_SHAPE_MOCK( SHAPE_T aShapeType ) : EDA_SHAPE( aShapeType, 0, FILL_T::NO_FILL ){};
33};
34
35
45
46
47static const std::vector<SET_ANGLE_END_CASE> set_angle_end_cases =
48{
49 {
50 "Issue 13626: clockwise semicircle",
51 {-428880000, 117229160 },
52 {-430060565, 113472820 },
53 180.0,
54 {-431241130, 109716480 },
55 false
56 },
57 {
58 "Issue 13626: anticlockwise arc",
59 { -431241130, 109716480 },
60 { -434923630, 112954230 },
61 -138.46654568595355,
62 { -439827050, 112936200 },
63 true
64 }
65};
66
67
68BOOST_AUTO_TEST_CASE( SetAngleAndEnd )
69{
70 for( const auto& c : set_angle_end_cases )
71 {
72 BOOST_TEST_INFO_SCOPE( c.m_CaseName );
73
75 shape.SetStart( c.m_Start );
76 shape.SetCenter( c.m_Center );
77
78 shape.SetArcAngleAndEnd( EDA_ANGLE( c.m_Angle, DEGREES_T ), true );
79
80 BOOST_CHECK_EQUAL( shape.EndsSwapped(), c.m_ExpectedStartEndSwapped );
81
82 const VECTOR2I newEnd = shape.EndsSwapped() ? shape.GetStart() : shape.GetEnd();
83
86 (newEnd) ( c.m_ExpectedEndBeforeSwap ) ( SHAPE_ARC::DefaultAccuracyForPCB() ) );
87 }
88}
89
90
103
104static const std::vector<SET_ARC_GEOMETRY_CASE> set_arc_geometry_cases = {
105 {
106 // Test that when setting an arc by start/mid/end, the winding
107 // direction is correctly determined (in 15694, this was in FP_SHAPE,
108 // but the logic has since been merged with EDA_SHAPE).
109 "Issue 15694: clockwise arc",
110 { 10000000, 0 },
111 { 0, 10000000 },
112 { -10000000, 0 },
113 { 0, 0 },
114 10000000,
115 false,
116 { -10000000, 0 }, // unchanged
117 180.0,
118 },
119 {
120 "Issue 15694: anticlockwise arc",
121 { -10000000, 0 },
122 { 0, 10000000 },
123 { 10000000, 0 },
124 { 0, 0 },
125 10000000,
126 true,
127 { 10000000, 0 }, // the start is the end after swapping
128 180.0, // angle is positive after swapping
129 },
130};
131
132BOOST_AUTO_TEST_CASE( SetArcGeometry )
133{
134 const double angle_tol = 0.1;
135
136 for( const auto& c : set_arc_geometry_cases )
137 {
138 BOOST_TEST_INFO_SCOPE( c.m_CaseName );
139
141
142 shape.SetArcGeometry( c.m_Start, c.m_Mid, c.m_End );
143
144 const VECTOR2I center = shape.getCenter();
145
148 (center) ( c.m_ExpectedCenter ) ( SHAPE_ARC::DefaultAccuracyForPCB() ) );
149
150 const int radius = shape.GetRadius();
151
154 (radius) ( c.m_ExpectedRadius ) ( SHAPE_ARC::DefaultAccuracyForPCB() ) );
155
156 BOOST_CHECK_EQUAL( shape.EndsSwapped(), c.m_ExpectedStartEndSwapped );
157
158 const VECTOR2I newEnd = shape.EndsSwapped() ? shape.GetStart() : shape.GetEnd();
159
162 (newEnd) ( c.m_ExpectedEndAfterSwap ) ( SHAPE_ARC::DefaultAccuracyForPCB() ) );
163
164 const EDA_ANGLE angle = shape.GetArcAngle();
165
168 ( angle.AsDegrees() )( c.m_ExpectedAngleAfterSwapDeg )( 360.0 )( angle_tol ) );
169
170 // Check that the centre is still correct
171 }
172}
173
181BOOST_AUTO_TEST_CASE( PolygonBehaviorSurvivesAssignment )
182{
184
185 SHAPE_POLY_SET& poly = shape.GetPolyShape();
186 poly.NewOutline();
187 poly.Append( { 0, 0 } );
188 poly.Append( { 1000000, 0 } );
189 poly.Append( { 1000000, 1000000 } );
190
191 EDA_POLYGON_POINT_EDIT_BEHAVIOR behavior( shape );
192
193 EDIT_POINTS points( nullptr );
194 behavior.MakePoints( points );
195 BOOST_CHECK_EQUAL( points.PointsSize(), 3u );
196
197 EDA_SHAPE_MOCK copy( shape );
198 shape = copy;
199
200 // After assignment, shape.m_poly is a fresh allocation.
201 // The behavior must still work (not use-after-free).
202 EDIT_POINTS points2( nullptr );
203 behavior.MakePoints( points2 );
204 BOOST_CHECK_EQUAL( points2.PointsSize(), 3u );
205
206 BOOST_CHECK( behavior.UpdatePoints( points ) );
207}
208
double AsDegrees() const
Definition eda_angle.h:116
"Standard" polygon editing behavior for EDA_SHAPE polygons.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
EDA_SHAPE_MOCK(SHAPE_T aShapeType)
EDA_ANGLE GetArcAngle() const
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
SHAPE_POLY_SET & GetPolyShape()
int GetRadius() const
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
Definition eda_shape.cpp:54
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:228
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:190
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:186
bool EndsSwapped() const
Have the start and end points been swapped since they were set?
Definition eda_shape.h:294
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
unsigned int PointsSize() const
Return number of stored EDIT_POINTs.
static int DefaultAccuracyForPCB()
Definition shape_arc.h:283
Represent a set of closed polygons.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
@ DEGREES_T
Definition eda_angle.h:31
SHAPE_T
Definition eda_shape.h:45
FILL_T
Definition eda_shape.h:58
@ NO_FILL
Definition eda_shape.h:59
bool IsWithinWrapped(T aValue, T aNominal, T aWrap, T aError)
Check if a value is within a tolerance of a nominal value, wrapping to a given val.
Definition numeric.h:43
bool IsWithin(T aValue, T aNominal, T aError)
Check if a value is within a tolerance of a nominal value.
Definition numeric.h:61
bool IsVecWithinTol(const VEC &aVec, const VEC &aExp, typename VEC::coord_type aTol)
Check that both x and y of a vector are within expected error.
Definition geometry.h:55
VECTOR2I m_ExpectedEndBeforeSwap
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static const std::vector< SET_ARC_GEOMETRY_CASE > set_arc_geometry_cases
BOOST_AUTO_TEST_CASE(SetAngleAndEnd)
static const std::vector< SET_ANGLE_END_CASE > set_angle_end_cases
BOOST_AUTO_TEST_SUITE_END()
VECTOR2I center
int radius
BOOST_CHECK_PREDICATE(ArePolylineEndPointsNearCircle,(chain)(c.m_geom.m_center_point)(radius)(accuracy+epsilon))
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687