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 (C) 2017-2021 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 <math/util.h> // for KiROUND
27#include <geometry/eda_angle.h>
28#include <trigo.h>
29
30using namespace KIGFX::PREVIEW;
31
32
34static EDA_ANGLE snapAngle( const EDA_ANGLE& aAngle )
35{
36 return ANGLE_45 * KiROUND( aAngle / ANGLE_45 );
37}
38
39
41{
42 switch( getStep() )
43 {
44 case SET_ORIGIN: return setOrigin( aPt );
45 case SET_START: return setStart( aPt );
46 case SET_ANGLE: return setEnd( aPt );
47 case COMPLETE: return false;
48 }
49
50 return false;
51}
52
53
55{
56 m_clockwise = aCw;
57 m_directionLocked = true;
59}
60
61
63{
65 m_directionLocked = true;
67}
68
69
71{
72 return m_origin;
73}
74
75
77{
78 VECTOR2I vec( static_cast<int>( m_radius ), 0 );
80 return m_origin +vec;
81}
82
83
85{
86 VECTOR2I vec( static_cast<int>( m_radius ), 0 );
87 RotatePoint( vec, -m_endAngle );
88 return m_origin + vec;
89}
90
91
93{
94 return m_radius;
95}
96
97
99{
100 EDA_ANGLE angle = m_startAngle;
101
102 if( m_clockwise )
103 angle -= ANGLE_360;
104
105 return -angle;
106}
107
108
110{
112
113 if( m_endAngle <= m_startAngle )
114 angle += ANGLE_360;
115
116 if( m_clockwise )
117 angle -= ANGLE_360;
118
119 return -angle;
120}
121
122
124{
125 m_origin = aOrigin;
128
129 return true;
130}
131
132
134{
135 const VECTOR2I radVec = aEnd - m_origin;
136
137 m_radius = radVec.EuclideanNorm();
138 m_startAngle = EDA_ANGLE( radVec );
139
140 if( m_angleSnap )
142
143 // normalise to 0..360
144 while( m_startAngle < ANGLE_0 )
146
148
149 return m_radius != 0.0;
150}
151
152
153bool ARC_GEOM_MANAGER::setEnd( const VECTOR2I& aCursor )
154{
155 const VECTOR2I radVec = aCursor - m_origin;
156
157 m_endAngle = EDA_ANGLE( radVec );
158
159 if( m_angleSnap )
161
162 // normalise to 0..360
163 while( m_endAngle < ANGLE_0 )
165
166 if( !m_directionLocked )
167 {
168 EDA_ANGLE ccwAngle = m_endAngle - m_startAngle;
169
170 if( m_endAngle <= m_startAngle )
171 ccwAngle += ANGLE_360;
172
173 EDA_ANGLE cwAngle = std::abs( ccwAngle - ANGLE_360 );
174
175 if( std::min( ccwAngle, cwAngle ) >= ANGLE_90 )
176 m_directionLocked = true;
177 else
178 m_clockwise = cwAngle < ccwAngle;
179 }
180 else if( std::abs( GetSubtended() ) < ANGLE_90 )
181 {
182 m_directionLocked = false;
183 }
184
185 // if the end is the same as the start, this is a bad point
186 return m_endAngle != m_startAngle;
187}
static EDA_ANGLE snapAngle(const EDA_ANGLE &aAngle)
< Snap an angle to the nearest 45 degrees
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:265
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:435
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:437
static constexpr EDA_ANGLE ANGLE_45
Definition: eda_angle.h:436
static constexpr EDA_ANGLE ANGLE_360
Definition: eda_angle.h:441
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:424
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:228
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85