KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Tomasz Wlostowski <[email protected]>
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
20 * along with this program. If not, see <https://www.gnu.org/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{
38public:
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,
60 };
61
73
78 {
79 ANG_OBTUSE = 0x01,
80 ANG_RIGHT = 0x02,
81 ANG_ACUTE = 0x04,
85 };
86
87 DIRECTION_45( Directions aDir = UNDEFINED ) : m_dir( aDir ), m_90deg( false ) {}
88
92 DIRECTION_45( const VECTOR2I &aVec, bool a90 = false ) :
93 m_90deg( a90 )
94 {
95 VECTOR2I vec( aVec );
96 vec.y = -vec.y;
97 construct_( vec );
98 }
99
103 DIRECTION_45( const SEG& aSeg, bool a90 = false ) :
104 m_90deg( a90 )
105 {
106 VECTOR2I vec( aSeg.B - aSeg.A );
107 vec.y = -vec.y;
108 construct_( vec );
109 }
110
116 DIRECTION_45( const SHAPE_ARC& aArc, bool a90 = false ) :
117 m_90deg( a90 )
118 {
119 VECTOR2I vec( aArc.GetP1() - aArc.GetP0() );
120 vec.y = -vec.y;
121 construct_( vec );
122 }
123
129 const std::string Format() const
130 {
131 switch( m_dir )
132 {
133 case N:
134 return "north";
135
136 case NE:
137 return "north-east";
138
139 case E:
140 return "east";
141
142 case SE:
143 return "south-east";
144
145 case S:
146 return "south";
147
148 case SW:
149 return "south-west";
150
151 case W:
152 return "west";
153
154 case NW:
155 return "north-west";
156
157 case UNDEFINED:
158 return "undefined";
159
160 default:
161 return "<Error>";
162 }
163 }
164
171 {
172 const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED };
173 return OppositeMap[m_dir];
174 }
175
181 AngleType Angle( const DIRECTION_45& aOther ) const
182 {
183 if( m_dir == UNDEFINED || aOther.m_dir == UNDEFINED )
184 return ANG_UNDEFINED;
185
186 int d = std::abs( m_dir - aOther.m_dir );
187
188 if( d == 1 || d == 7 )
189 return ANG_OBTUSE;
190 else if( d == 2 || d == 6 )
191 return ANG_RIGHT;
192 else if( d == 3 || d == 5 )
193 return ANG_ACUTE;
194 else if( d == 4 )
195 return ANG_HALF_FULL;
196 else
197 return ANG_STRAIGHT;
198 }
199
203 bool IsObtuse( const DIRECTION_45& aOther ) const
204 {
205 return Angle( aOther ) == ANG_OBTUSE;
206 }
207
213 bool IsDiagonal() const
214 {
215 return ( m_dir % 2 ) == 1;
216 }
217
218 bool IsDefined() const
219 {
220 return m_dir != UNDEFINED;
221 }
222
234 const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1,
235 bool aStartDiagonal = false,
236 CORNER_MODE aMode = CORNER_MODE::MITERED_45 ) const;
237
238 bool operator==( const DIRECTION_45& aOther ) const
239 {
240 return aOther.m_dir == m_dir;
241 }
242
243 bool operator!=( const DIRECTION_45& aOther ) const
244 {
245 return aOther.m_dir != m_dir;
246 }
247
251 const DIRECTION_45 Right() const
252 {
253 DIRECTION_45 r;
254
255 if ( m_dir != UNDEFINED )
256 {
257 if( m_90deg )
258 r.m_dir = static_cast<Directions>( ( m_dir + 2 ) % LAST );
259 else
260 r.m_dir = static_cast<Directions>( ( m_dir + 1 ) % LAST );
261 }
262
263 return r;
264 }
265
269 const DIRECTION_45 Left() const
270 {
271 DIRECTION_45 l;
272
273 if ( m_dir != UNDEFINED )
274 {
275 if( m_90deg )
276 l.m_dir = static_cast<Directions>( ( m_dir + LAST - 2 ) % LAST );
277 else
278 l.m_dir = static_cast<Directions>( ( m_dir + LAST - 1 ) % LAST );
279 }
280
281 return l;
282 }
283
287 const VECTOR2I ToVector() const
288 {
289 switch( m_dir )
290 {
291 case N: return VECTOR2I( 0, -1 );
292 case S: return VECTOR2I( 0, 1 );
293 case E: return VECTOR2I( 1, 0 );
294 case W: return VECTOR2I( -1, 0 );
295 case NE: return VECTOR2I( 1, -1 );
296 case NW: return VECTOR2I( -1, -1 );
297 case SE: return VECTOR2I( 1, 1 );
298 case SW: return VECTOR2I( -1, 1 );
299
300 default:
301 return VECTOR2I( 0, 0 );
302 }
303 }
304
305 int Mask() const
306 {
307 return 1 << ( (int) m_dir );
308 }
309
310 static int AllDirectionsMask()
311 {
312 return 0xffff;
313 }
314
315private:
322 void construct_( const VECTOR2I& aVec )
323 {
325
326 if( aVec.x == 0 && aVec.y == 0 )
327 return;
328
329 double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0;
330
331 if( mag >= 360.0 )
332 mag -= 360.0;
333
334 if( mag < 0.0 )
335 mag += 360.0;
336
337 int dir = ( mag + 22.5 ) / 45.0;
338
339 if( dir >= LAST )
340 dir -= LAST;
341
342 if( dir < 0 )
343 dir += LAST;
344
345 m_dir = (Directions) dir;
346
347 return;
348 }
349
352
355};
356
357#endif // DIRECTION45_H
const SHAPE_LINE_CHAIN BuildInitialTrace(const VECTOR2I &aP0, const VECTOR2I &aP1, bool aStartDiagonal=false, CORNER_MODE aMode=CORNER_MODE::MITERED_45) const
Build a 2-segment line chain between points aP0 and aP1 and following 45-degree routing regime.
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
bool operator!=(const DIRECTION_45 &aOther) const
int Mask() const
const DIRECTION_45 Left() const
Return the direction on the left side of this (i.e.
static int AllDirectionsMask()
const VECTOR2I ToVector() const
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
Definition direction45.h:78
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition direction45.h:49
DIRECTION_45(Directions aDir=UNDEFINED)
Definition direction45.h:87
DIRECTION_45(const SEG &aSeg, bool a90=false)
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
CORNER_MODE
Corner modes.
Definition direction45.h:67
@ ROUNDED_90
H/V with filleted corners.
Definition direction45.h:71
@ MITERED_90
H/V only (90-degree corners)
Definition direction45.h:70
@ ROUNDED_45
H/V/45 with filleted corners.
Definition direction45.h:69
@ MITERED_45
H/V/45 with mitered corners (default)
Definition direction45.h:68
Directions m_dir
Are we routing on 45 or 90 degree increments.
bool IsDefined() const
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
DIRECTION_45(const SHAPE_ARC &aArc, bool a90=false)
Create a DIRECTION_45 from the endpoints of a given arc.
const std::string Format() const
Format the direction in a human readable word.
DIRECTION_45(const VECTOR2I &aVec, bool a90=false)
Definition direction45.h:92
bool IsObtuse(const DIRECTION_45 &aOther) const
bool operator==(const DIRECTION_45 &aOther) const
DIRECTION_45 Opposite() const
Return a direction opposite (180 degree) to (this).
Definition seg.h:38
VECTOR2I A
Definition seg.h:45
VECTOR2I B
Definition seg.h:46
const VECTOR2I & GetP1() const
Definition shape_arc.h:115
const VECTOR2I & GetP0() const
Definition shape_arc.h:114
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:411
#define M_PI
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683