KiCad PCB EDA Suite
direction45.h
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) 2013-2015 CERN
5  * Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
8  *
9  * This program is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by the
11  * Free Software Foundation, either version 3 of the License, or (at your
12  * option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program. If not, see <http://www.gnu.or/licenses/>.
21  */
22 
23 #ifndef DIRECTION45_H
24 #define DIRECTION45_H
25 
26 #include <geometry/seg.h>
28 #include <math/vector2d.h>
29 
30 // believe or not, X11 headers have a F****ING macro called Opposite...
31 #undef Opposite
32 
37 {
38 public:
39 
48  enum Directions : int
49  {
50  N = 0,
51  NE = 1,
52  E = 2,
53  SE = 3,
54  S = 4,
55  SW = 5,
56  W = 6,
57  NW = 7,
58  LAST = 8,
59  UNDEFINED = -1
60  };
61 
65  enum AngleType
66  {
67  ANG_OBTUSE = 0x01,
68  ANG_RIGHT = 0x02,
69  ANG_ACUTE = 0x04,
70  ANG_STRAIGHT = 0x08,
71  ANG_HALF_FULL = 0x10,
73  };
74 
75  DIRECTION_45( Directions aDir = UNDEFINED ) : m_dir( aDir ), m_90deg( false ) {}
76 
80  DIRECTION_45( const VECTOR2I &aVec, bool a90 = false ) :
81  m_90deg( a90 )
82  {
83  VECTOR2I vec( aVec );
84  vec.y = -vec.y;
85  construct_( vec );
86  }
87 
91  DIRECTION_45( const SEG& aSeg, bool a90 = false ) :
92  m_90deg( a90 )
93  {
94  VECTOR2I vec( aSeg.B - aSeg.A );
95  vec.y = -vec.y;
96  construct_( vec );
97  }
98 
104  DIRECTION_45( const SHAPE_ARC& aArc, bool a90 = false ) :
105  m_90deg( a90 )
106  {
107  VECTOR2I vec( aArc.GetP1() - aArc.GetP0() );
108  vec.y = -vec.y;
109  construct_( vec );
110  }
111 
117  const std::string Format() const
118  {
119  switch( m_dir )
120  {
121  case N:
122  return "north";
123 
124  case NE:
125  return "north-east";
126 
127  case E:
128  return "east";
129 
130  case SE:
131  return "south-east";
132 
133  case S:
134  return "south";
135 
136  case SW:
137  return "south-west";
138 
139  case W:
140  return "west";
141 
142  case NW:
143  return "north-west";
144 
145  case UNDEFINED:
146  return "undefined";
147 
148  default:
149  return "<Error>";
150  }
151  }
152 
159  {
160  const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED };
161  return OppositeMap[m_dir];
162  }
163 
169  AngleType Angle( const DIRECTION_45& aOther ) const
170  {
171  if( m_dir == UNDEFINED || aOther.m_dir == UNDEFINED )
172  return ANG_UNDEFINED;
173 
174  int d = std::abs( m_dir - aOther.m_dir );
175 
176  if( d == 1 || d == 7 )
177  return ANG_OBTUSE;
178  else if( d == 2 || d == 6 )
179  return ANG_RIGHT;
180  else if( d == 3 || d == 5 )
181  return ANG_ACUTE;
182  else if( d == 4 )
183  return ANG_HALF_FULL;
184  else
185  return ANG_STRAIGHT;
186  }
187 
191  bool IsObtuse( const DIRECTION_45& aOther ) const
192  {
193  return Angle( aOther ) == ANG_OBTUSE;
194  }
195 
201  bool IsDiagonal() const
202  {
203  return ( m_dir % 2 ) == 1;
204  }
205 
206  bool IsDefined() const
207  {
208  return m_dir != UNDEFINED;
209  }
210 
221  const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1,
222  bool aStartDiagonal = false,
223  bool aFillet = false ) const;
224 
225  bool operator==( const DIRECTION_45& aOther ) const
226  {
227  return aOther.m_dir == m_dir;
228  }
229 
230  bool operator!=( const DIRECTION_45& aOther ) const
231  {
232  return aOther.m_dir != m_dir;
233  }
234 
238  const DIRECTION_45 Right() const
239  {
240  DIRECTION_45 r;
241 
242  if ( m_dir != UNDEFINED )
243  {
244  if( m_90deg )
245  r.m_dir = static_cast<Directions>( ( m_dir + 2 ) % LAST );
246  else
247  r.m_dir = static_cast<Directions>( ( m_dir + 1 ) % LAST );
248  }
249 
250  return r;
251  }
252 
256  const DIRECTION_45 Left() const
257  {
258  DIRECTION_45 l;
259 
260  if ( m_dir != UNDEFINED )
261  {
262  if( m_90deg )
263  l.m_dir = static_cast<Directions>( ( m_dir + LAST - 2 ) % LAST );
264  else
265  l.m_dir = static_cast<Directions>( ( m_dir + LAST - 1 ) % LAST );
266  }
267 
268  return l;
269  }
270 
274  const VECTOR2I ToVector() const
275  {
276  switch( m_dir )
277  {
278  case N: return VECTOR2I( 0, -1 );
279  case S: return VECTOR2I( 0, 1 );
280  case E: return VECTOR2I( 1, 0 );
281  case W: return VECTOR2I( -1, 0 );
282  case NE: return VECTOR2I( 1, -1 );
283  case NW: return VECTOR2I( -1, -1 );
284  case SE: return VECTOR2I( 1, 1 );
285  case SW: return VECTOR2I( -1, 1 );
286 
287  default:
288  return VECTOR2I( 0, 0 );
289  }
290  }
291 
292  int Mask() const
293  {
294  return 1 << ( (int) m_dir );
295  }
296 
297 private:
298 
305  void construct_( const VECTOR2I& aVec )
306  {
307  m_dir = UNDEFINED;
308 
309  if( aVec.x == 0 && aVec.y == 0 )
310  return;
311 
312  double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0;
313 
314  if( mag >= 360.0 )
315  mag -= 360.0;
316 
317  if( mag < 0.0 )
318  mag += 360.0;
319 
320  int dir = ( mag + 22.5 ) / 45.0;
321 
322  if( dir >= LAST )
323  dir -= LAST;
324 
325  if( dir < 0 )
326  dir += LAST;
327 
328  m_dir = (Directions) dir;
329 
330  return;
331  }
332 
335 
337  bool m_90deg;
338 };
339 
340 #endif // DIRECTION45_H
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition: direction45.h:48
DIRECTION_45(const SEG &aSeg, bool a90=false)
Definition: direction45.h:91
int Mask() const
Definition: direction45.h:292
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:117
const VECTOR2I ToVector() const
Definition: direction45.h:274
const DIRECTION_45 Left() const
Return the direction on the left side of this (i.e.
Definition: direction45.h:256
bool operator!=(const DIRECTION_45 &aOther) const
Definition: direction45.h:230
DIRECTION_45(const VECTOR2I &aVec, bool a90=false)
Definition: direction45.h:80
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
Definition: direction45.h:238
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
DIRECTION_45(const SHAPE_ARC &aArc, bool a90=false)
Create a DIRECTION_45 from the endpoints of a given arc.
Definition: direction45.h:104
DIRECTION_45(Directions aDir=UNDEFINED)
Definition: direction45.h:75
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
Definition: direction45.h:169
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
bool IsDefined() const
Definition: direction45.h:206
const VECTOR2I & GetP0() const
Definition: shape_arc.h:95
DIRECTION_45 Opposite() const
Return a direction opposite (180 degree) to (this).
Definition: direction45.h:158
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, bool aFillet=false) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
Definition: direction45.h:201
bool operator==(const DIRECTION_45 &aOther) const
Definition: direction45.h:225
Definition: seg.h:40
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition: direction45.h:65
SHAPE_LINE_CHAIN.
VECTOR2I A
Definition: seg.h:48
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:334
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
Definition: direction45.h:305
const VECTOR2I & GetP1() const
Definition: shape_arc.h:96
bool IsObtuse(const DIRECTION_45 &aOther) const
Definition: direction45.h:191
VECTOR2I B
Definition: seg.h:49