KiCad PCB EDA Suite
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 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 <common.h> // KiROUND
27 
28 using namespace KIGFX::PREVIEW;
29 
30 
32 static double snapAngle( double aAngle )
33 {
34  return KiROUND( aAngle / M_PI_4 ) * M_PI_4;
35 }
36 
37 
39 {
40  switch( getStep() )
41  {
42  case SET_ORIGIN:
43  return setOrigin( aPt );
44  case SET_START:
45  return setStart( aPt );
46  case SET_ANGLE:
47  return setEnd( aPt );
48  case COMPLETE:
49  break;
50  }
51 
52  return false;
53 }
54 
55 
57 {
58  m_clockwise = aCw;
60 }
61 
62 
64 {
67 }
68 
69 
71 {
72  return m_origin;
73 }
74 
75 
77 {
78  return m_origin + VECTOR2I( m_radius, 0 ).Rotate( m_startAngle );
79 }
80 
81 
83 {
84  return m_origin + VECTOR2I( m_radius, 0 ).Rotate( m_endAngle );
85 }
86 
87 
89 {
90  return m_radius;
91 }
92 
93 
95 {
96  double angle = m_startAngle;
97 
98  if( m_clockwise )
99  angle -= 2 * M_PI;
100 
101  return -angle;
102 }
103 
104 
106 {
107  double angle = m_endAngle - m_startAngle;
108 
109  if( m_endAngle <= m_startAngle )
110  angle += 2 * M_PI;
111 
112  if( m_clockwise )
113  angle -= 2 * M_PI;
114 
115  return -angle;
116 }
117 
118 
119 bool ARC_GEOM_MANAGER::setOrigin( const VECTOR2I& aOrigin )
120 {
121  m_origin = aOrigin;
122  m_startAngle = 0.0;
123  m_endAngle = 0.0;
124 
125  return true;
126 }
127 
128 
130 {
131  const auto radVec = aEnd - m_origin;
132 
133  m_radius = radVec.EuclideanNorm();
134  m_startAngle = radVec.Angle();
135 
136  if( m_angleSnap )
138 
139  // normalise into 0-2Pi
140  while( m_startAngle < 0 )
141  m_startAngle += M_PI * 2;
142 
144 
145  return m_radius != 0.0;
146 }
147 
148 
149 bool ARC_GEOM_MANAGER::setEnd( const VECTOR2I& aCursor )
150 {
151  const auto radVec = aCursor - m_origin;
152 
153  m_endAngle = radVec.Angle();
154 
155  if( m_angleSnap )
157 
158  // normalise into 0-2Pi
159  while( m_endAngle < 0 )
160  m_endAngle += M_PI * 2;
161 
162  // if the end is the same as the start, this is a bad point
163  return m_endAngle != m_startAngle;
164 }
Waiting to lock in the arc end point
bool setEnd(const VECTOR2I &aCursor)
Set a point of the second radius line (collinear with arc end)
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:373
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
double GetRadius() const
Get the radius of the arc (valid if step >= SET_START)
void setGeometryChanged()
Mark the geometry as changed for clients to notice
VECTOR2I GetEndRadiusEnd() const
Get the coordinates of the arc end point
Waiting to lock in origin point
int getStep() const
Get the current stage of the manager
double GetSubtended() const
Get the angle of the vector leading to the end point (valid if step >= SET_ANGLE) ...
bool setStart(const VECTOR2I &aEnd)
Set the end of the first radius line (arc start)
Waiting to lock in the arc start point
bool acceptPoint(const VECTOR2I &aPt) override
Function that accepts a point for a stage, or rejects it to return to the previous stage ...
void ToggleClockwise()
Reverse the current are direction
void SetClockwise(bool aCw)
The the arc to be clockwise from start
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
The common library.
bool setOrigin(const VECTOR2I &aOrigin)
Set the centre point of the arc
double GetStartAngle() const
Get the angle of the vector leading to the start point (valid if step >= SET_START) ...
static double snapAngle(double aAngle)
Snap an angle to the nearest 45 degrees
VECTOR2I GetOrigin() const
Get the centre point of the arc (valid when state > SET_ORIGIN)
VECTOR2I GetStartRadiusEnd() const
Get the coordinates of the arc start