KiCad PCB EDA Suite
Loading...
Searching...
No Matches
arc_geom_manager.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
21
22#include <math/util.h> // for KiROUND
23#include <geometry/eda_angle.h>
24#include <trigo.h>
25
26using namespace KIGFX::PREVIEW;
27
28
30static EDA_ANGLE snapAngle( const EDA_ANGLE& aAngle )
31{
32 return ANGLE_45 * KiROUND( aAngle / ANGLE_45 );
33}
34
35
37{
38 switch( getStep() )
39 {
40 case SET_ORIGIN: return setOrigin( aPt );
41 case SET_START: return setStart( aPt );
42 case SET_ANGLE: return setEnd( aPt );
43 case COMPLETE: return false;
44 }
45
46 return false;
47}
48
49
51{
52 m_clockwise = aCw;
53 m_directionLocked = true;
55}
56
57
64
65
70
71
73{
74 VECTOR2I vec( static_cast<int>( m_radius ), 0 );
76 return m_origin +vec;
77}
78
79
81{
82 VECTOR2I vec( static_cast<int>( m_radius ), 0 );
83 RotatePoint( vec, -m_endAngle );
84 return m_origin + vec;
85}
86
87
89{
90 return m_radius;
91}
92
93
95{
96 EDA_ANGLE angle = m_startAngle;
97
98 if( m_clockwise )
99 angle -= ANGLE_360;
100
101 return -angle;
102}
103
104
106{
108
109 if( m_endAngle <= m_startAngle )
110 angle += ANGLE_360;
111
112 if( m_clockwise )
113 angle -= ANGLE_360;
114
115 return -angle;
116}
117
118
120{
121 m_origin = aOrigin;
124
125 return true;
126}
127
128
130{
131 const VECTOR2I radVec = aEnd - m_origin;
132
133 m_radius = radVec.EuclideanNorm();
134 m_startAngle = EDA_ANGLE( radVec );
135
136 if( m_angleSnap )
138
139 // normalise to 0..360
140 while( m_startAngle < ANGLE_0 )
142
144
145 return m_radius != 0.0;
146}
147
148
149bool ARC_GEOM_MANAGER::setEnd( const VECTOR2I& aCursor )
150{
151 const VECTOR2I radVec = aCursor - m_origin;
152
153 m_endAngle = EDA_ANGLE( radVec );
154
155 if( m_angleSnap )
157
158 // normalise to 0..360
159 while( m_endAngle < ANGLE_0 )
161
162 if( !m_directionLocked )
163 {
164 EDA_ANGLE ccwAngle = m_endAngle - m_startAngle;
165
166 if( m_endAngle <= m_startAngle )
167 ccwAngle += ANGLE_360;
168
169 EDA_ANGLE cwAngle = std::abs( ccwAngle - ANGLE_360 );
170
171 if( std::min( ccwAngle, cwAngle ) >= ANGLE_90 )
172 m_directionLocked = true;
173 else
174 m_clockwise = cwAngle < ccwAngle;
175 }
176 else if( std::abs( GetSubtended() ) < ANGLE_90 )
177 {
178 m_directionLocked = false;
179 }
180
181 // if the end is the same as the start, this is a bad point
182 return m_endAngle != m_startAngle;
183}
static EDA_ANGLE snapAngle(const EDA_ANGLE &aAngle)
< Snap an angle to the nearest 45 degrees
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
VECTOR2I GetOrigin() const
< Get the center point of the arc (valid when state > SET_ORIGIN)
void SetClockwise(bool aCw)
Reverse the current are direction.
void ToggleClockwise()
Set angle snapping (for the next point)
EDA_ANGLE GetStartAngle() const
Get the angle of the vector leading to the end point (valid if step >= SET_ANGLE)
bool setStart(const VECTOR2I &aEnd)
Set a point of the second radius line (collinear with arc end)
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc end point.
bool acceptPoint(const VECTOR2I &aPt) override
The arc to be clockwise from start.
VECTOR2I GetEndRadiusEnd() const
Get the radius of the arc (valid if step >= SET_START)
bool setEnd(const VECTOR2I &aCursor)
double GetRadius() const
Get the angle of the vector leading to the start point (valid if step >= SET_START)
bool setOrigin(const VECTOR2I &aOrigin)
< Set the center point of the arc
@ SET_ORIGIN
Waiting to lock in origin point.
@ SET_ANGLE
Waiting to lock in the arc end point.
@ SET_START
Waiting to lock in the arc start point.
void setGeometryChanged()
< Mark the geometry as changed for clients to notice
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:279
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_45
Definition eda_angle.h:412
static constexpr EDA_ANGLE ANGLE_360
Definition eda_angle.h:417
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683