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
93 DIRECTION_45( const VECTOR2I &aVec, bool a90 = false ) :
94 m_90deg( a90 )
95 {
96 VECTOR2I vec( aVec );
97 vec.y = -vec.y;
98 construct_( vec );
99 }
100
105 DIRECTION_45( const SEG& aSeg, bool a90 = false ) :
106 m_90deg( a90 )
107 {
108 VECTOR2I vec( aSeg.B - aSeg.A );
109 vec.y = -vec.y;
110 construct_( vec );
111 }
112
119 DIRECTION_45( const SHAPE_ARC& aArc, bool a90 = false ) :
120 m_90deg( a90 )
121 {
122 VECTOR2I vec( aArc.GetP1() - aArc.GetP0() );
123 vec.y = -vec.y;
124 construct_( vec );
125 }
126
132 const std::string Format() const
133 {
134 switch( m_dir )
135 {
136 case N:
137 return "north";
138
139 case NE:
140 return "north-east";
141
142 case E:
143 return "east";
144
145 case SE:
146 return "south-east";
147
148 case S:
149 return "south";
150
151 case SW:
152 return "south-west";
153
154 case W:
155 return "west";
156
157 case NW:
158 return "north-west";
159
160 case UNDEFINED:
161 return "undefined";
162
163 default:
164 return "<Error>";
165 }
166 }
167
174 {
175 const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED };
176 return OppositeMap[m_dir];
177 }
178
184 AngleType Angle( const DIRECTION_45& aOther ) const
185 {
186 if( m_dir == UNDEFINED || aOther.m_dir == UNDEFINED )
187 return ANG_UNDEFINED;
188
189 int d = std::abs( m_dir - aOther.m_dir );
190
191 if( d == 1 || d == 7 )
192 return ANG_OBTUSE;
193 else if( d == 2 || d == 6 )
194 return ANG_RIGHT;
195 else if( d == 3 || d == 5 )
196 return ANG_ACUTE;
197 else if( d == 4 )
198 return ANG_HALF_FULL;
199 else
200 return ANG_STRAIGHT;
201 }
202
206 bool IsObtuse( const DIRECTION_45& aOther ) const
207 {
208 return Angle( aOther ) == ANG_OBTUSE;
209 }
210
216 bool IsDiagonal() const
217 {
218 return ( m_dir % 2 ) == 1;
219 }
220
221 bool IsDefined() const
222 {
223 return m_dir != UNDEFINED;
224 }
225
237 const SHAPE_LINE_CHAIN BuildInitialTrace( const VECTOR2I& aP0, const VECTOR2I& aP1,
238 bool aStartDiagonal = false,
239 CORNER_MODE aMode = CORNER_MODE::MITERED_45 ) const;
240
241 bool operator==( const DIRECTION_45& aOther ) const
242 {
243 return aOther.m_dir == m_dir;
244 }
245
246 bool operator!=( const DIRECTION_45& aOther ) const
247 {
248 return aOther.m_dir != m_dir;
249 }
250
254 const DIRECTION_45 Right() const
255 {
256 DIRECTION_45 r;
257
258 if ( m_dir != UNDEFINED )
259 {
260 if( m_90deg )
261 r.m_dir = static_cast<Directions>( ( m_dir + 2 ) % LAST );
262 else
263 r.m_dir = static_cast<Directions>( ( m_dir + 1 ) % LAST );
264 }
265
266 return r;
267 }
268
272 const DIRECTION_45 Left() const
273 {
274 DIRECTION_45 l;
275
276 if ( m_dir != UNDEFINED )
277 {
278 if( m_90deg )
279 l.m_dir = static_cast<Directions>( ( m_dir + LAST - 2 ) % LAST );
280 else
281 l.m_dir = static_cast<Directions>( ( m_dir + LAST - 1 ) % LAST );
282 }
283
284 return l;
285 }
286
290 const VECTOR2I ToVector() const
291 {
292 switch( m_dir )
293 {
294 case N: return VECTOR2I( 0, -1 );
295 case S: return VECTOR2I( 0, 1 );
296 case E: return VECTOR2I( 1, 0 );
297 case W: return VECTOR2I( -1, 0 );
298 case NE: return VECTOR2I( 1, -1 );
299 case NW: return VECTOR2I( -1, -1 );
300 case SE: return VECTOR2I( 1, 1 );
301 case SW: return VECTOR2I( -1, 1 );
302
303 default:
304 return VECTOR2I( 0, 0 );
305 }
306 }
307
308 int Mask() const
309 {
310 return 1 << ( (int) m_dir );
311 }
312
313 static int AllDirectionsMask()
314 {
315 return 0xffff;
316 }
317
318private:
325 void construct_( const VECTOR2I& aVec )
326 {
328
329 if( aVec.x == 0 && aVec.y == 0 )
330 return;
331
332 double mag = 360.0 - ( 180.0 / M_PI * atan2( (double) aVec.y, (double) aVec.x ) ) + 90.0;
333
334 if( mag >= 360.0 )
335 mag -= 360.0;
336
337 if( mag < 0.0 )
338 mag += 360.0;
339
340 int dir = ( mag + 22.5 ) / 45.0;
341
342 if( dir >= LAST )
343 dir -= LAST;
344
345 if( dir < 0 )
346 dir += LAST;
347
348 m_dir = (Directions) dir;
349
350 return;
351 }
352
355
358};
359
360#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
our actual direction
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:93
bool IsObtuse(const DIRECTION_45 &aOther) const
bool m_90deg
Are we routing on 45 or 90 degree increments.
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:437
#define M_PI
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708