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 (C) 2017-2021 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 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{
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,
59 UNDEFINED = -1
60 };
61
67 {
72 };
73
78 {
79 ANG_OBTUSE = 0x01,
80 ANG_RIGHT = 0x02,
81 ANG_ACUTE = 0x04,
84 ANG_UNDEFINED = 0x20
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
310private:
317 void construct_( const VECTOR2I& aVec )
318 {
320
321 if( aVec.x == 0 && aVec.y == 0 )
322 return;
323
324 double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0;
325
326 if( mag >= 360.0 )
327 mag -= 360.0;
328
329 if( mag < 0.0 )
330 mag += 360.0;
331
332 int dir = ( mag + 22.5 ) / 45.0;
333
334 if( dir >= LAST )
335 dir -= LAST;
336
337 if( dir < 0 )
338 dir += LAST;
339
340 m_dir = (Directions) dir;
341
342 return;
343 }
344
347
350};
351
352#endif // DIRECTION45_H
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:37
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.
Definition: direction45.h:181
bool operator!=(const DIRECTION_45 &aOther) const
Definition: direction45.h:243
int Mask() const
Definition: direction45.h:305
const DIRECTION_45 Left() const
Return the direction on the left side of this (i.e.
Definition: direction45.h:269
const VECTOR2I ToVector() const
Definition: direction45.h:287
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)
Definition: direction45.h:103
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
Definition: direction45.h:213
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.
Definition: direction45.h:346
bool IsDefined() const
Definition: direction45.h:218
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
Definition: direction45.h:317
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
Definition: direction45.h:251
DIRECTION_45(const SHAPE_ARC &aArc, bool a90=false)
Create a DIRECTION_45 from the endpoints of a given arc.
Definition: direction45.h:116
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:129
DIRECTION_45(const VECTOR2I &aVec, bool a90=false)
Definition: direction45.h:92
bool IsObtuse(const DIRECTION_45 &aOther) const
Definition: direction45.h:203
bool operator==(const DIRECTION_45 &aOther) const
Definition: direction45.h:238
DIRECTION_45 Opposite() const
Return a direction opposite (180 degree) to (this).
Definition: direction45.h:170
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112
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:424
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588