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.

◆ 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  };
H/V with filleted corners.
Definition: direction45.h:71
H/V/45 with mitered corners (default)
Definition: direction45.h:68
H/V/45 with filleted corners.
Definition: direction45.h:69
H/V only (90-degree corners)
Definition: direction45.h:70

◆ 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.

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

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  }
Define a general 2D-vector/point.
Definition: vector2d.h:61
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  }
Define a general 2D-vector/point.
Definition: vector2d.h:61
VECTOR2I A
Definition: seg.h:48
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
Definition: direction45.h:317
VECTOR2I B
Definition: seg.h:49

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  }
Define a general 2D-vector/point.
Definition: vector2d.h:61
const VECTOR2I & GetP0() const
Definition: shape_arc.h:111
void construct_(const VECTOR2I &aVec)
Calculate the direction from a vector.
Definition: direction45.h:317
const VECTOR2I & GetP1() 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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

References ANG_ACUTE, ANG_HALF_FULL, ANG_OBTUSE, ANG_RIGHT, ANG_STRAIGHT, ANG_UNDEFINED, m_dir, and UNDEFINED.

Referenced by PNS::angle(), 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 23 of file direction_45.cpp.

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

References SHAPE_LINE_CHAIN::Append(), SHAPE_ARC::ConstructFromStartEndAngle(), SHAPE_ARC::ConstructFromStartEndCenter(), VECTOR2< T >::EuclideanNorm(), SHAPE_ARC::GetP0(), SHAPE_ARC::GetP1(), IsDiagonal(), KiROUND(), m_dir, M_PI_2, SHAPE::MIN_PRECISION_IU, VECTOR2< T >::Resize(), VECTOR2< T >::Rotate(), 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::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 vectorour 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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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::mergeHead(), 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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

References m_dir.

Referenced by BuildInitialTrace(), 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:36
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
Directions
Available directions, there are 8 of them, as on a rectilinear map (north = up) + an extra undefined ...
Definition: direction45.h:48
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  {
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  }
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:36
E_SERIE r
Definition: eserie.cpp:41
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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  }
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
Directions m_dir
Are we routing on 45 or 90 degree increments.
Definition: direction45.h:346

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: