KiCad PCB EDA Suite
DIRECTION_45 Class Reference

Represent route directions & corner angles in a 45-degree metric. More...

#include <direction45.h>

Public Types

enum  Directions : int {
  N = 0 , NE = 1 , E = 2 , SE = 3 ,
  S = 4 , SW = 5 , W = 6 , NW = 7 ,
  LAST = 8 , UNDEFINED = -1
}
 Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined direction, reserved for traces that don't respect 45-degree routing regime. More...
 
enum  CORNER_MODE { MITERED_45 = 0 , ROUNDED_45 = 1 , MITERED_90 = 2 , ROUNDED_90 = 3 }
 Corner modes. More...
 
enum  AngleType {
  ANG_OBTUSE = 0x01 , ANG_RIGHT = 0x02 , ANG_ACUTE = 0x04 , ANG_STRAIGHT = 0x08 ,
  ANG_HALF_FULL = 0x10 , ANG_UNDEFINED = 0x20
}
 Represent kind of angle formed by vectors heading in two DIRECTION_45s. More...
 

Public Member Functions

 DIRECTION_45 (Directions aDir=UNDEFINED)
 
 DIRECTION_45 (const VECTOR2I &aVec, bool a90=false)
 
 DIRECTION_45 (const SEG &aSeg, bool a90=false)
 
 DIRECTION_45 (const SHAPE_ARC &aArc, bool a90=false)
 Create a DIRECTION_45 from the endpoints of a given arc. More...
 
const std::string Format () const
 Format the direction in a human readable word. More...
 
DIRECTION_45 Opposite () const
 Return a direction opposite (180 degree) to (this). More...
 
AngleType Angle (const DIRECTION_45 &aOther) const
 Return the type of angle between directions (this) and aOther. More...
 
bool IsObtuse (const DIRECTION_45 &aOther) const
 
bool IsDiagonal () const
 Returns true if the direction is diagonal (e.g. More...
 
bool IsDefined () const
 
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. More...
 
bool operator== (const DIRECTION_45 &aOther) const
 
bool operator!= (const DIRECTION_45 &aOther) const
 
const DIRECTION_45 Right () const
 Return the direction on the right side of this (i.e. More...
 
const DIRECTION_45 Left () const
 Return the direction on the left side of this (i.e. More...
 
const VECTOR2I ToVector () const
 
int Mask () const
 

Private Member Functions

void construct_ (const VECTOR2I &aVec)
 Calculate the direction from a vector. More...
 

Private Attributes

Directions m_dir
 Are we routing on 45 or 90 degree increments. More...
 
bool m_90deg
 

Detailed Description

Represent route directions & corner angles in a 45-degree metric.

Definition at line 36 of file direction45.h.

Member Enumeration Documentation

◆ AngleType

Represent kind of angle formed by vectors heading in two DIRECTION_45s.

Enumerator
ANG_OBTUSE 
ANG_RIGHT 
ANG_ACUTE 
ANG_STRAIGHT 
ANG_HALF_FULL 
ANG_UNDEFINED 

Definition at line 77 of file direction45.h.

78 {
79 ANG_OBTUSE = 0x01,
80 ANG_RIGHT = 0x02,
81 ANG_ACUTE = 0x04,
82 ANG_STRAIGHT = 0x08,
83 ANG_HALF_FULL = 0x10,
84 ANG_UNDEFINED = 0x20
85 };

◆ CORNER_MODE

Corner modes.

A corner can either be 45° or 90° and can be fillet/rounded or mitered

Enumerator
MITERED_45 

H/V/45 with mitered corners (default)

ROUNDED_45 

H/V/45 with filleted corners.

MITERED_90 

H/V only (90-degree corners)

ROUNDED_90 

H/V with filleted corners.

Definition at line 66 of file direction45.h.

67 {
68 MITERED_45 = 0,
69 ROUNDED_45 = 1,
70 MITERED_90 = 2,
71 ROUNDED_90 = 3,
72 };
@ 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

Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined direction, reserved for traces that don't respect 45-degree routing regime.

Note
North represents "up" to the user looking at the application, which is the negative-y direction in the world coordinate space!
Enumerator
NE 
SE 
SW 
NW 
LAST 
UNDEFINED 

Definition at line 48 of file direction45.h.

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 };

Constructor & Destructor Documentation

◆ DIRECTION_45() [1/4]

DIRECTION_45::DIRECTION_45 ( Directions  aDir = UNDEFINED)
inline

Definition at line 87 of file direction45.h.

87: m_dir( aDir ), m_90deg( false ) {}
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

◆ DIRECTION_45() [2/4]

DIRECTION_45::DIRECTION_45 ( const VECTOR2I aVec,
bool  a90 = false 
)
inline
Parameters
aVecvector in world space, whose direction will be translated into a DIRECTION_45.

Definition at line 92 of file direction45.h.

92 :
93 m_90deg( a90 )
94 {
95 VECTOR2I vec( aVec );
96 vec.y = -vec.y;
97 construct_( vec );
98 }
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
Definition: direction45.h:317

References construct_(), and VECTOR2< T >::y.

◆ DIRECTION_45() [3/4]

DIRECTION_45::DIRECTION_45 ( const SEG aSeg,
bool  a90 = false 
)
inline
Parameters
aSegsegment, whose direction will be translated into a DIRECTION_45.

Definition at line 103 of file direction45.h.

103 :
104 m_90deg( a90 )
105 {
106 VECTOR2I vec( aSeg.B - aSeg.A );
107 vec.y = -vec.y;
108 construct_( vec );
109 }
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, construct_(), and VECTOR2< T >::y.

◆ DIRECTION_45() [4/4]

DIRECTION_45::DIRECTION_45 ( const SHAPE_ARC aArc,
bool  a90 = false 
)
inline

Create a DIRECTION_45 from the endpoints of a given arc.

Parameters
aArcwill be translated into the closest DIRECTION_45

Definition at line 116 of file direction45.h.

116 :
117 m_90deg( a90 )
118 {
119 VECTOR2I vec( aArc.GetP1() - aArc.GetP0() );
120 vec.y = -vec.y;
121 construct_( vec );
122 }
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113
const VECTOR2I & GetP0() const
Definition: shape_arc.h:112

References construct_(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), and VECTOR2< T >::y.

Member Function Documentation

◆ Angle()

AngleType DIRECTION_45::Angle ( const DIRECTION_45 aOther) const
inline

Return the type of angle between directions (this) and aOther.

Parameters
aOtherdirection to compare angle with

Definition at line 181 of file direction45.h.

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 }
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401

References std::abs(), ANG_ACUTE, ANG_HALF_FULL, ANG_OBTUSE, ANG_RIGHT, ANG_STRAIGHT, ANG_UNDEFINED, m_dir, and UNDEFINED.

Referenced by PNS::angle(), PNS::DIFF_PAIR::CheckConnectionAngle(), PNS::LINE::CountCorners(), PNS::LINE::dragSegment45(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::LINE_PLACER::handlePullback(), IsObtuse(), PNS::LINE_PLACER::mergeHead(), PNS::OPTIMIZER::smartPadsSingle(), and PNS::tightenSegment().

◆ BuildInitialTrace()

const SHAPE_LINE_CHAIN DIRECTION_45::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.

If aStartDiagonal is true, the trace starts with a diagonal segment.

Parameters
aP0starting point
aP1ending point
aStartDiagonalwhether the first segment has to be diagonal
aModeHow the corner is made. If it is a 90° corner, aStartDiagonal means start with the shorter direction first / use arc before the straight segment.
Returns
the trace

Definition at line 24 of file direction_45.cpp.

28{
29 bool startDiagonal;
30
31 if( m_dir == UNDEFINED )
32 startDiagonal = aStartDiagonal;
33 else
34 startDiagonal = IsDiagonal();
35
36 int w = abs( aP1.x - aP0.x );
37 int h = abs( aP1.y - aP0.y );
38 int sw = sign( aP1.x - aP0.x );
39 int sh = sign( aP1.y - aP0.y );
40
41 bool is90mode = aMode == CORNER_MODE::ROUNDED_90 || aMode == CORNER_MODE::MITERED_90;
43
44 // Shortcut where we can generate just one segment and quit. Avoids more complicated handling
45 // of precision errors if filleting is enabled
46 if( w == 0 || h == 0 || ( !is90mode && h == w ) )
47 {
48 pl.Append( aP0 );
49 pl.Append( aP1 );
50 return pl;
51 }
52
53 VECTOR2I mp0, mp1;
54 int tangentLength;
55
56 if( is90mode )
57 {
58 if( startDiagonal == ( h >= w ) )
59 {
60 mp0 = VECTOR2I( w * sw, 0 ); // direction: E
61 }
62 else
63 {
64 mp0 = VECTOR2I( 0, sh * h ); // direction: N
65 }
66 }
67 else
68 {
69 if( w > h )
70 {
71 mp0 = VECTOR2I( ( w - h ) * sw, 0 ); // direction: E
72 mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE
73 tangentLength = ( w - h ) - mp1.EuclideanNorm();
74 }
75 else
76 {
77 mp0 = VECTOR2I( 0, sh * ( h - w ) ); // direction: N
78 mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE
79 tangentLength = ( h - w ) - mp1.EuclideanNorm();
80 }
81 }
82
83 SHAPE_ARC arc;
84 VECTOR2I arcEndpoint;
85
86 switch( aMode )
87 {
88 case CORNER_MODE::MITERED_45:
89 /*
90 * For width greater than height, we're calculating something like this.
91 * mp0 will be used if we start straight; mp1 if we start diagonal.
92 *
93 * aP0 ----------------- mp0
94 * . \
95 * . \
96 * . \
97 * mp1 . . . . . . . . aP1
98 *
99 */
100 pl.Append( aP0 );
101 pl.Append( startDiagonal ? ( aP0 + mp1 ) : ( aP0 + mp0 ) );
102 pl.Append( aP1 );
103 break;
104
105 case CORNER_MODE::ROUNDED_45:
106 {
107 /*
108 * For a fillet, we need to know the arc start point (A in the diagram below)
109 * A straight segment will be needed between aP0 and A if we are starting straight,
110 * or between the arc end and aP1 if we are starting diagonally.
111 *
112 * aP0 -- A --___ mp0
113 * . ---
114 * . --
115 * . --
116 * mp1 . . . . . . . . aP1
117 *
118 * For the length of this segment (tangentLength), we subtract the length of the "diagonal"
119 * line from the "straight" line (i.e. dist(aP0, mp0) - dist(mp0, aP1))
120 * In the example above, we will have a straight segment from aP0 to A, and then we can use
121 * the distance from A to aP1 (diagLength) to calculate the radius of the arc.
122 */
123 if( w == h )
124 {
125 pl.Append( aP0 );
126 pl.Append( aP1 );
127 break;
128 }
129
130 double diag2 = tangentLength >= 0 ? mp1.SquaredEuclideanNorm() : mp0.SquaredEuclideanNorm();
131 double diagLength = std::sqrt( ( 2 * diag2 ) - ( 2 * diag2 * std::cos( 3 * M_PI_4 ) ) );
132 int arcRadius = KiROUND( diagLength / ( 2.0 * std::cos( 67.5 * M_PI / 180.0 ) ) );
133
134 // There are four different ways to build an arc, depending on whether or not we are
135 // starting diagonally and whether or not we have a negative tangent length (meaning the
136 // arc has to be on the opposite end of the line from normal). This math could probably
137 // be condensed and optimized but I'm tired of staring at it for now (and it works!)
138
139 if( startDiagonal )
140 {
141 int rotationSign = ( w > h ) ? ( sw * sh * -1 ) : ( sw * sh );
142
143 if( tangentLength >= 0 )
144 {
145 // Positive tangentLength, diagonal start: arc goes at the start
146 arcEndpoint = aP1 - mp0.Resize( tangentLength );
147 arc.ConstructFromStartEndAngle( aP0, arcEndpoint, - ANGLE_45 * rotationSign );
148
149 if( arc.GetP0() == arc.GetP1() )
150 pl.Append( aP0 );
151 else
152 pl.Append( arc );
153
154 pl.Append( aP1 );
155 }
156 else
157 {
158 // Negative tangentLength, diagonal start: arc goes at the end
159 arcEndpoint = aP0 + mp1.Resize( std::abs( tangentLength ) );
160 arc.ConstructFromStartEndAngle( arcEndpoint, aP1, - ANGLE_45 * rotationSign );
161
162 pl.Append( aP0 );
163
164 if( arc.GetP0() == arc.GetP1() )
165 pl.Append( aP1 );
166 else
167 pl.Append( arc );
168 }
169 }
170 else
171 {
172 int rotationSign = ( w > h ) ? ( sw * sh * -1 ) : ( sw * sh );
173 VECTOR2D centerDir( mp0 );
174
175 RotatePoint( centerDir, ANGLE_90 * rotationSign );
176
177 if( tangentLength >= 0 )
178 {
179 // Positive tangentLength: arc goes at the end
180 arcEndpoint = aP0 + mp0.Resize( tangentLength );
181 arc.ConstructFromStartEndAngle( arcEndpoint, aP1, ANGLE_45 * rotationSign );
182
183 pl.Append( aP0 );
184
185 if( arc.GetP0() == arc.GetP1() )
186 pl.Append( aP1 );
187 else
188 pl.Append( arc );
189 }
190 else
191 {
192 // Negative tangentLength: arc goes at the start
193 VECTOR2I arcCenter = aP0 + centerDir.Resize( arcRadius );
194 SHAPE_ARC ca( arcCenter, aP0, -ANGLE_45 * rotationSign );
195
196
197 // Constructing with a center can lead to imprecise endpoint. We need to guarantee
198 // tangency of the endpoint.
199 // TODO: update the math above to calculate the proper endpoint directly
200 VECTOR2I endpoint( ca.GetP1() );
201
202 if( std::abs( endpoint.y - aP1.y ) < SHAPE_ARC::MIN_PRECISION_IU )
203 {
204 VECTOR2I fixedEnd( endpoint.x, aP1.y );
205 ca.ConstructFromStartEndAngle( ca.GetP0(), fixedEnd, - ANGLE_45 * rotationSign );
206 }
207 else if( std::abs( endpoint.x - aP1.x ) < SHAPE_ARC::MIN_PRECISION_IU )
208 {
209 VECTOR2I fixedEnd( aP1.x, endpoint.y );
210 ca.ConstructFromStartEndAngle( ca.GetP0(), fixedEnd, - ANGLE_45 * rotationSign );
211 }
212
213 if( ca.GetP0() == ca.GetP1() )
214 pl.Append( aP0 );
215 else
216 pl.Append( ca );
217
218 pl.Append( aP1 );
219 }
220 }
221 break;
222 }
223 case CORNER_MODE::MITERED_90:
224 /*
225 * For width greater than height, we're calculating something like this.
226 *
227 * <-mp0->
228 * aP0 -------------------+
229 * |
230 * |
231 * |
232 * aP1
233 */
234 pl.Append( aP0 );
235 pl.Append( aP0 + mp0 );
236 pl.Append( aP1 );
237 break;
238
239 case CORNER_MODE::ROUNDED_90:
240 /*
241 * For a fillet, we need to know the arc end point
242 * A straight segment will be needed between aP0 and arcEnd in case distance aP0,mp0 is bigger
243 * than the distance mp0,aP1, if the distance is shorter the straigth segment is between
244 * arcEnd and aP1. If both distances are equal, we don't need a straight segment.
245 *
246 * aP0 ----- arcEnd ---__
247 * --
248 * \
249 * |
250 * arcCenter aP1
251 *
252 * For the length of the radius we use the shorter of the horizontal and vertical distance.
253 */
254 SHAPE_ARC arc;
255
256 if( w == h ) // we only need one arc without a straigth line.
257 {
258 arc.ConstructFromStartEndCenter( aP0, aP1, aP1 - mp0, sh == sw != startDiagonal );
259 pl.Append( arc );
260 return pl;
261 }
262
263 VECTOR2I arcEnd; // Arc position that is not at aP0 nor aP1
264 VECTOR2I arcCenter;
265
266 if( startDiagonal ) //Means start with the arc first
267 {
268 if( h > w ) // Arc followed by a vertical line
269 {
270 int y = aP0.y + ( w * sh );
271 arcEnd = VECTOR2I( aP1.x, y );
272 arcCenter = VECTOR2I( aP0.x, y );
273 arc.ConstructFromStartEndCenter( aP0, arcEnd, arcCenter, sh != sw );
274 pl.Append( arc );
275 pl.Append( aP1 );
276 }
277 else // Arc followed by a horizontal line
278 {
279 int x = aP0.x + ( h * sw );
280 arcEnd = VECTOR2I( x, aP1.y );
281 arcCenter = VECTOR2I( x, aP0.y );
282 arc.ConstructFromStartEndCenter( aP0, arcEnd, arcCenter, sh == sw );
283 pl.Append( arc );
284 pl.Append( aP1 );
285 }
286 }
287 else
288 {
289 if( w > h ) // Horizontal line followed by the arc
290 {
291 int x = aP1.x - ( h * sw );
292 arcEnd = VECTOR2I( x, aP0.y );
293 arcCenter = VECTOR2I( x, aP1.y );
294 pl.Append( aP0 );
295 arc.ConstructFromStartEndCenter( arcEnd, aP1, arcCenter, sh != sw );
296 pl.Append( arc );
297 }
298 else // Vertical line followed by the arc
299 {
300 int y = aP1.y - ( w * sh );
301 arcEnd = VECTOR2I( aP0.x, y );
302 arcCenter = VECTOR2I( aP1.x, y );
303 pl.Append( aP0 );
304 arc.ConstructFromStartEndCenter( arcEnd, aP1, arcCenter, sh == sw );
305 pl.Append( arc );
306 }
307 }
308 break;
309 }
310
311 pl.Simplify();
312 return pl;
313}
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
Definition: direction45.h:213
SHAPE_ARC & ConstructFromStartEndAngle(const VECTOR2I &aStart, const VECTOR2I &aEnd, const EDA_ANGLE &aAngle, double aWidth=0)
Construct this arc from the given start, end and angle.
Definition: shape_arc.cpp:191
SHAPE_ARC & ConstructFromStartEndCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aClockwise=false, double aWidth=0)
Constructs this arc from the given start, end and center.
Definition: shape_arc.cpp:209
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
static const int MIN_PRECISION_IU
This is the minimum precision for all the points in a shape.
Definition: shape.h:128
extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition: vector2d.h:300
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:378
static constexpr EDA_ANGLE & ANGLE_45
Definition: eda_angle.h:413
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:414
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
int sign(T val)
Definition: util.h:111
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:80
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618

References std::abs(), ANGLE_45, ANGLE_90, SHAPE_LINE_CHAIN::Append(), SHAPE_ARC::ConstructFromStartEndAngle(), SHAPE_ARC::ConstructFromStartEndCenter(), VECTOR2< T >::EuclideanNorm(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), IsDiagonal(), KiROUND(), m_dir, SHAPE::MIN_PRECISION_IU, VECTOR2< T >::Resize(), RotatePoint(), sign(), SHAPE_LINE_CHAIN::Simplify(), VECTOR2< T >::SquaredEuclideanNorm(), UNDEFINED, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by PNS::DP_GATEWAYS::buildDpContinuation(), PNS::DP_GATEWAYS::buildEntries(), PNS::DIFF_PAIR::BuildInitial(), PNS::LINE_PLACER::buildInitialLine(), PNS::coupledBypass(), PNS::dragCornerInternal(), PNS::OPTIMIZER::fanoutCleanup(), PNS::OPTIMIZER::mergeDpStep(), PNS::OPTIMIZER::mergeStep(), PNS::LINE_PLACER::reduceTail(), and PNS::OPTIMIZER::smartPadsSingle().

◆ construct_()

void DIRECTION_45::construct_ ( const VECTOR2I aVec)
inlineprivate

Calculate the direction from a vector.

If the vector's angle is not a multiple of 45 degrees, the direction is rounded to the nearest octant.

Parameters
aVecour vector our actual direction

Definition at line 317 of file direction45.h.

References LAST, m_dir, UNDEFINED, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by DIRECTION_45().

◆ Format()

const std::string DIRECTION_45::Format ( ) const
inline

Format the direction in a human readable word.

Returns
name of the direction

Definition at line 129 of file direction45.h.

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 }

References E, m_dir, N, NE, NW, S, SE, SW, UNDEFINED, and W.

Referenced by PNS::LINE_PLACER::buildInitialLine(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), PNS::LINE_PLACER::handlePullback(), PNS::LINE_PLACER::initPlacement(), PNS::LINE_PLACER::routeStep(), and PNS::LINE_PLACER::Start().

◆ IsDefined()

bool DIRECTION_45::IsDefined ( ) const
inline

Definition at line 218 of file direction45.h.

219 {
220 return m_dir != UNDEFINED;
221 }

References m_dir, and UNDEFINED.

◆ IsDiagonal()

bool DIRECTION_45::IsDiagonal ( ) const
inline

Returns true if the direction is diagonal (e.g.

North-West, South-East, etc).

Returns
true, when diagonal.

Definition at line 213 of file direction45.h.

214 {
215 return ( m_dir % 2 ) == 1;
216 }

References m_dir.

Referenced by BuildInitialTrace(), PNS::coupledBypass(), PNS::dragCornerInternal(), PNS::DIFF_PAIR_PLACER::FixRoute(), PNS::MOUSE_TRAIL_TRACER::GetPosture(), and PNS::OPTIMIZER::mergeDpStep().

◆ IsObtuse()

bool DIRECTION_45::IsObtuse ( const DIRECTION_45 aOther) const
inline
Returns
true, when (this) forms an obtuse angle with aOther.

Definition at line 203 of file direction45.h.

204 {
205 return Angle( aOther ) == ANG_OBTUSE;
206 }
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
Definition: direction45.h:181

References ANG_OBTUSE, and Angle().

Referenced by PNS::OPTIMIZER::mergeDpStep(), and PNS::tightenSegment().

◆ Left()

const DIRECTION_45 DIRECTION_45::Left ( ) const
inline

Return the direction on the left side of this (i.e.

turns left by 45 or 90 deg).

Definition at line 269 of file direction45.h.

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 }
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:37
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition: direction45.h:49

References LAST, m_90deg, m_dir, and UNDEFINED.

Referenced by PNS::DP_GATEWAYS::buildDpContinuation(), and PNS::LINE::dragSegment45().

◆ Mask()

int DIRECTION_45::Mask ( ) const
inline

Definition at line 305 of file direction45.h.

306 {
307 return 1 << ( (int) m_dir );
308 }

References m_dir.

◆ operator!=()

bool DIRECTION_45::operator!= ( const DIRECTION_45 aOther) const
inline

Definition at line 243 of file direction45.h.

244 {
245 return aOther.m_dir != m_dir;
246 }

References m_dir.

◆ operator==()

bool DIRECTION_45::operator== ( const DIRECTION_45 aOther) const
inline

Definition at line 238 of file direction45.h.

239 {
240 return aOther.m_dir == m_dir;
241 }

References m_dir.

◆ Opposite()

DIRECTION_45 DIRECTION_45::Opposite ( ) const
inline

Return a direction opposite (180 degree) to (this).

Returns
opposite direction

Definition at line 170 of file direction45.h.

171 {
172 const Directions OppositeMap[] = { S, SW, W, NW, N, NE, E, SE, UNDEFINED };
173 return OppositeMap[m_dir];
174 }

References E, m_dir, N, NE, NW, S, SE, SW, UNDEFINED, and W.

◆ Right()

const DIRECTION_45 DIRECTION_45::Right ( ) const
inline

Return the direction on the right side of this (i.e.

turns right by 45 or 90 deg).

Definition at line 251 of file direction45.h.

252 {
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 }
E_SERIE r
Definition: eserie.cpp:41

References LAST, m_90deg, m_dir, r, and UNDEFINED.

Referenced by PNS::DP_GATEWAYS::buildDpContinuation(), PNS::LINE::dragSegment45(), PNS::MOUSE_TRAIL_TRACER::FlipPosture(), and PNS::MOUSE_TRAIL_TRACER::GetPosture().

◆ ToVector()

const VECTOR2I DIRECTION_45::ToVector ( ) const
inline
Returns
a unit vector in world coordinate system corresponding to our direction.

Definition at line 287 of file direction45.h.

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 }

References E, m_dir, N, NE, NW, S, SE, SW, and W.

Referenced by PNS::DP_GATEWAYS::buildDpContinuation(), and PNS::LINE::dragSegment45().

Member Data Documentation

◆ m_90deg

bool DIRECTION_45::m_90deg
private

Definition at line 349 of file direction45.h.

Referenced by Left(), and Right().

◆ m_dir

Directions DIRECTION_45::m_dir
private

Are we routing on 45 or 90 degree increments.

Definition at line 346 of file direction45.h.

Referenced by Angle(), BuildInitialTrace(), construct_(), Format(), IsDefined(), IsDiagonal(), Left(), Mask(), operator!=(), operator==(), Opposite(), Right(), and ToVector().


The documentation for this class was generated from the following files: