KiCad PCB EDA Suite
PNS::MOUSE_TRAIL_TRACER Class Reference

#include <pns_mouse_trail_tracer.h>

Public Member Functions

 MOUSE_TRAIL_TRACER ()
 
 ~MOUSE_TRAIL_TRACER ()
 
void Clear ()
 
void AddTrailPoint (const VECTOR2I &aP)
 
void SetTolerance (int toll)
 
void SetDefaultDirections (DIRECTION_45 aInitDirection, DIRECTION_45 aLastSegDir)
 
DIRECTION_45 GetPosture (const VECTOR2I &aP)
 
void FlipPosture ()
 
void SetMouseDisabled (bool aDisabled=true)
 Disables the mouse-trail portion of the posture solver; leaving only the manual posture switch and the previous-segment posture algorithm. More...
 
bool IsManuallyForced () const
 
VECTOR2I GetTrailLeadVector () const
 

Private Attributes

SHAPE_LINE_CHAIN m_trail
 
int m_tolerance
 
DIRECTION_45 m_direction
 
DIRECTION_45 m_lastSegDirection
 
bool m_forced
 
bool m_disableMouse
 
bool m_manuallyForced
 

Detailed Description

Definition at line 31 of file pns_mouse_trail_tracer.h.

Constructor & Destructor Documentation

◆ MOUSE_TRAIL_TRACER()

PNS::MOUSE_TRAIL_TRACER::MOUSE_TRAIL_TRACER ( )

◆ ~MOUSE_TRAIL_TRACER()

PNS::MOUSE_TRAIL_TRACER::~MOUSE_TRAIL_TRACER ( )

Definition at line 35 of file pns_mouse_trail_tracer.cpp.

35{}

Member Function Documentation

◆ AddTrailPoint()

void PNS::MOUSE_TRAIL_TRACER::AddTrailPoint ( const VECTOR2I aP)

Definition at line 46 of file pns_mouse_trail_tracer.cpp.

47{
48 if( m_trail.SegmentCount() == 0 )
49 {
50 m_trail.Append( aP );
51 }
52 else
53 {
54 SEG s_new( m_trail.CPoint( -1 ), aP );
55
56 if( m_trail.SegmentCount() > 2 )
57 {
58 SEG::ecoord limit = ( static_cast<SEG::ecoord>( m_tolerance ) * m_tolerance );
59
60 for( int i = 0; i < m_trail.SegmentCount() - 2; i++ )
61 {
62 const SEG& s_trail = m_trail.CSegment( i );
63
64 if( s_trail.SquaredDistance( s_new ) <= limit )
65 {
66 m_trail = m_trail.Slice( 0, i );
67 break;
68 }
69 }
70 }
71
72 m_trail.Append( aP );
73 }
74
76
77 DEBUG_DECORATOR *dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
78
79 PNS_DBG( dbg, AddShape, &m_trail, CYAN, 50000, wxT( "mt-trail" ) );
80}
virtual DEBUG_DECORATOR * GetDebugDecorator()=0
ROUTER_IFACE * GetInterface() const
Definition: pns_router.h:208
static ROUTER * GetInstance()
Definition: pns_router.cpp:78
Definition: seg.h:42
ecoord SquaredDistance(const SEG &aSeg) const
Definition: seg.cpp:75
VECTOR2I::extended_type ecoord
Definition: seg.h:44
SHAPE_LINE_CHAIN & Simplify(bool aRemoveColinear=true)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
const SHAPE_LINE_CHAIN Slice(int aStartIndex, int aEndIndex=-1) const
Return a subset of this line chain containing the [start_index, end_index] range of points.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
@ CYAN
Definition: color4d.h:58
#define PNS_DBG(dbg, method,...)

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), CYAN, PNS::ROUTER_IFACE::GetDebugDecorator(), PNS::ROUTER::GetInstance(), PNS::ROUTER::GetInterface(), m_tolerance, m_trail, PNS_DBG, SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Simplify(), SHAPE_LINE_CHAIN::Slice(), and SEG::SquaredDistance().

Referenced by PNS::DRAGGER::Drag(), PNS::LINE_PLACER::FixRoute(), PNS::LINE_PLACER::Move(), PNS::LINE_PLACER::Start(), PNS::DRAGGER::Start(), and PNS::LINE_PLACER::UnfixRoute().

◆ Clear()

◆ FlipPosture()

void PNS::MOUSE_TRAIL_TRACER::FlipPosture ( )

Definition at line 268 of file pns_mouse_trail_tracer.cpp.

269{
271 m_forced = true;
272 m_manuallyForced = true;
273}
const DIRECTION_45 Right() const
Return the direction on the right side of this (i.e.
Definition: direction45.h:251

References m_direction, m_forced, m_manuallyForced, and DIRECTION_45::Right().

Referenced by PNS::LINE_PLACER::FlipPosture().

◆ GetPosture()

DIRECTION_45 PNS::MOUSE_TRAIL_TRACER::GetPosture ( const VECTOR2I aP)

Definition at line 83 of file pns_mouse_trail_tracer.cpp.

84{
85 // Tuning factor for how good the "fit" of the trail must be to the posture
86 const double areaRatioThreshold = 1.3;
87
88 // Tuning factor to minimize flutter
89 const double areaRatioEpsilon = 0.25;
90
91 // Minimum distance factor of the trail before the min area test is used to lock the solver
92 const double minAreaCutoffDistanceFactor = 6;
93
94 // Adjusts how far away from p0 we get before whatever posture we solved is locked in
95 const int lockDistanceFactor = 25;
96
97 // Adjusts how close to p0 we unlock the posture again if one was locked already
98 const int unlockDistanceFactor = 4;
99
100 if( m_trail.PointCount() < 2 || m_manuallyForced )
101 {
102 // If mouse trail detection is enabled; using the last seg direction as a starting point
103 // will give the best results. Otherwise, just assume that we switch postures every
104 // segment.
107
108 return m_direction;
109 }
110
111 DEBUG_DECORATOR* dbg = ROUTER::GetInstance()->GetInterface()->GetDebugDecorator();
112 VECTOR2I p0 = m_trail.CPoint( 0 );
113 double refLength = SEG( p0, aP ).Length();
114 SHAPE_LINE_CHAIN straight( DIRECTION_45().BuildInitialTrace( p0, aP, false ) );
115
116 straight.SetClosed( true );
117 straight.Append( m_trail.Reverse() );
118 straight.Simplify();
119
120 PNS_DBG( dbg, AddShape, &straight, m_forced ? BLUE : GREEN, 100000, wxT( "mt-straight" ) );
121
122 double areaS = straight.Area();
123
124 SHAPE_LINE_CHAIN diag( DIRECTION_45().BuildInitialTrace( p0, aP, true ) );
125 diag.Append( m_trail.Reverse() );
126 diag.SetClosed( true );
127 diag.Simplify();
128
129 PNS_DBG( dbg, AddShape, &diag, YELLOW, 100000, wxT( "mt-diag" ) );
130
131 double areaDiag = diag.Area();
132 double ratio = areaS / ( areaDiag + 1.0 );
133
134 // heuristic to detect that the user dragged back the cursor to the beginning of the trace
135 // in this case, we cancel any forced posture and restart the trail
136 if( m_forced && refLength < unlockDistanceFactor * m_tolerance )
137 {
138 PNS_DBG( dbg, Message, "Posture: Unlocked and reset" );
139 m_forced = false;
140 VECTOR2I start = p0;
141 m_trail.Clear();
142 m_trail.Append( start );
143 }
144
145 bool areaOk = false;
146
147 // Check the actual trail area against the cutoff. This prevents flutter when the trail is
148 // very close to a straight line.
149 if( !m_forced && refLength > minAreaCutoffDistanceFactor * m_tolerance )
150 {
151 double areaCutoff = m_tolerance * refLength;
152 SHAPE_LINE_CHAIN trail( m_trail );
153 trail.SetClosed( true );
154
155 if( trail.Area() > areaCutoff )
156 areaOk = true;
157 }
158
159 DIRECTION_45 straightDirection;
160 DIRECTION_45 diagDirection;
161 DIRECTION_45 newDirection = m_direction;
162
163 straightDirection = DIRECTION_45( straight.CSegment( 0 ) );
164 diagDirection = DIRECTION_45( diag.CSegment( 0 ) );
165
166 if( !m_forced && areaOk && ratio > areaRatioThreshold + areaRatioEpsilon )
167 newDirection = diagDirection;
168 else if( !m_forced && areaOk && ratio < ( 1.0 / areaRatioThreshold ) - areaRatioEpsilon )
169 newDirection = straightDirection;
170 else
171 newDirection = m_direction.IsDiagonal() ? diagDirection : straightDirection;
172
173 if( !m_disableMouse && newDirection != m_direction )
174 {
175 PNS_DBG( dbg, Message, wxString::Format( "Posture: direction update %s => %s",
176 m_direction.Format(), newDirection.Format() ) );
177 m_direction = newDirection;
178 }
179
180 // If we have a last segment, correct the direction relative to it. For segment exit, we want
181 // to correct to the least obtuse
183 {
184 PNS_DBG( dbg, Message,
185 wxString::Format( wxT( "Posture: checking direction %s against last seg %s" ),
187
188 if( straightDirection == m_lastSegDirection )
189 {
190 if( m_direction != straightDirection )
191 {
192 PNS_DBG( dbg, Message, wxString::Format( wxT( "Posture: forcing straight => %s" ),
193 straightDirection.Format() ) );
194 }
195
196 m_direction = straightDirection;
197 }
198 else if( diagDirection == m_lastSegDirection )
199 {
200 if( m_direction != diagDirection )
201 {
202 PNS_DBG( dbg, Message, wxString::Format( wxT( "Posture: forcing diagonal => %s" ),
203 diagDirection.Format() ) );
204 }
205
206 m_direction = diagDirection;
207 }
208 else
209 {
211 {
213 // Force a better (acute) connection
214 m_direction = m_direction.IsDiagonal() ? straightDirection : diagDirection;
215 PNS_DBG( dbg, Message, wxString::Format( wxT( "Posture: correcting half full => %s" ),
216 m_direction.Format() ) );
217 break;
218
220 {
221 // Force a better connection by flipping if possible
222 DIRECTION_45 candidate = m_direction.IsDiagonal() ? straightDirection
223 : diagDirection;
224
226 {
227 PNS_DBG( dbg, Message, wxString::Format( wxT( "Posture: correcting right => %s" ),
228 candidate.Format() ) );
229 m_direction = candidate;
230 }
231
232 break;
233 }
234
236 {
237 // Force a better connection by flipping if possible
238 DIRECTION_45 candidate = m_direction.IsDiagonal() ? straightDirection
239 : diagDirection;
240
242 {
243 PNS_DBG( dbg, Message, wxString::Format( wxT( "Posture: correcting obtuse => %s" ),
244 candidate.Format() ) );
245 m_direction = candidate;
246 }
247
248 break;
249 }
250
251 default:
252 break;
253 }
254 }
255 }
256
257 // If we get far away from the initial point, lock in the current solution to prevent flutter
258 if( !m_forced && refLength > lockDistanceFactor * m_tolerance )
259 {
260 PNS_DBG( dbg, Message, "Posture: solution locked" );
261 m_forced = true;
262 }
263
264 return m_direction;
265}
Represent route directions & corner angles in a 45-degree metric.
Definition: direction45.h:37
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
Definition: direction45.h:181
bool IsDiagonal() const
Returns true if the direction is diagonal (e.g.
Definition: direction45.h:213
const std::string Format() const
Format the direction in a human readable word.
Definition: direction45.h:129
int Length() const
Return the length (this).
Definition: seg.h:351
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
const SHAPE_LINE_CHAIN Reverse() const
Reverse point order in the line chain.
int PointCount() const
Return the number of points (vertices) in this line chain.
@ BLUE
Definition: color4d.h:56
@ GREEN
Definition: color4d.h:57
@ YELLOW
Definition: color4d.h:67
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200

References DIRECTION_45::ANG_ACUTE, DIRECTION_45::ANG_HALF_FULL, DIRECTION_45::ANG_OBTUSE, DIRECTION_45::ANG_RIGHT, DIRECTION_45::Angle(), SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::Area(), BLUE, SHAPE_LINE_CHAIN::Clear(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::CSegment(), DIRECTION_45::Format(), Format(), PNS::ROUTER_IFACE::GetDebugDecorator(), PNS::ROUTER::GetInstance(), PNS::ROUTER::GetInterface(), GREEN, DIRECTION_45::IsDiagonal(), SEG::Length(), m_direction, m_disableMouse, m_forced, m_lastSegDirection, m_manuallyForced, m_tolerance, m_trail, PNS_DBG, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN::Reverse(), DIRECTION_45::Right(), SHAPE_LINE_CHAIN::SetClosed(), SHAPE_LINE_CHAIN::Simplify(), DIRECTION_45::UNDEFINED, and YELLOW.

Referenced by PNS::LINE_PLACER::buildInitialLine().

◆ GetTrailLeadVector()

VECTOR2I PNS::MOUSE_TRAIL_TRACER::GetTrailLeadVector ( ) const

Definition at line 276 of file pns_mouse_trail_tracer.cpp.

277{
278 if( m_trail.PointCount() < 2 )
279 {
280 return VECTOR2I(0, 0);
281 }
282 else
283 {
284 return m_trail.CPoint( -1 ) - m_trail.CPoint( 0 );
285 }
286}
VECTOR2< int > VECTOR2I
Definition: vector2d.h:607

References SHAPE_LINE_CHAIN::CPoint(), m_trail, and SHAPE_LINE_CHAIN::PointCount().

Referenced by PNS::DRAGGER::propagateViaForces().

◆ IsManuallyForced()

bool PNS::MOUSE_TRAIL_TRACER::IsManuallyForced ( ) const
inline

◆ SetDefaultDirections()

void PNS::MOUSE_TRAIL_TRACER::SetDefaultDirections ( DIRECTION_45  aInitDirection,
DIRECTION_45  aLastSegDir 
)
inline

Definition at line 43 of file pns_mouse_trail_tracer.h.

44 {
45 m_direction = aInitDirection;
46 m_lastSegDirection = aLastSegDir;
47 }

References m_direction, and m_lastSegDirection.

Referenced by PNS::LINE_PLACER::FixRoute(), PNS::LINE_PLACER::Start(), and PNS::LINE_PLACER::UnfixRoute().

◆ SetMouseDisabled()

void PNS::MOUSE_TRAIL_TRACER::SetMouseDisabled ( bool  aDisabled = true)
inline

Disables the mouse-trail portion of the posture solver; leaving only the manual posture switch and the previous-segment posture algorithm.

Definition at line 57 of file pns_mouse_trail_tracer.h.

57{ m_disableMouse = aDisabled; }

References m_disableMouse.

Referenced by PNS::LINE_PLACER::Start().

◆ SetTolerance()

void PNS::MOUSE_TRAIL_TRACER::SetTolerance ( int  toll)
inline

Definition at line 41 of file pns_mouse_trail_tracer.h.

41{ m_tolerance = toll; }

References m_tolerance.

Referenced by PNS::LINE_PLACER::FixRoute(), and PNS::LINE_PLACER::Start().

Member Data Documentation

◆ m_direction

DIRECTION_45 PNS::MOUSE_TRAIL_TRACER::m_direction
private

Definition at line 65 of file pns_mouse_trail_tracer.h.

Referenced by FlipPosture(), GetPosture(), and SetDefaultDirections().

◆ m_disableMouse

bool PNS::MOUSE_TRAIL_TRACER::m_disableMouse
private

Definition at line 68 of file pns_mouse_trail_tracer.h.

Referenced by GetPosture(), MOUSE_TRAIL_TRACER(), and SetMouseDisabled().

◆ m_forced

bool PNS::MOUSE_TRAIL_TRACER::m_forced
private

Definition at line 67 of file pns_mouse_trail_tracer.h.

Referenced by Clear(), FlipPosture(), and GetPosture().

◆ m_lastSegDirection

DIRECTION_45 PNS::MOUSE_TRAIL_TRACER::m_lastSegDirection
private

Definition at line 66 of file pns_mouse_trail_tracer.h.

Referenced by GetPosture(), and SetDefaultDirections().

◆ m_manuallyForced

bool PNS::MOUSE_TRAIL_TRACER::m_manuallyForced
private

Definition at line 69 of file pns_mouse_trail_tracer.h.

Referenced by Clear(), FlipPosture(), GetPosture(), and IsManuallyForced().

◆ m_tolerance

int PNS::MOUSE_TRAIL_TRACER::m_tolerance
private

◆ m_trail

SHAPE_LINE_CHAIN PNS::MOUSE_TRAIL_TRACER::m_trail
private

Definition at line 63 of file pns_mouse_trail_tracer.h.

Referenced by AddTrailPoint(), Clear(), GetPosture(), and GetTrailLeadVector().


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