KiCad PCB EDA Suite
PNS::MEANDERED_LINE Class Reference

Represent a set of meanders fitted over a single or two lines. More...

#include <pns_meander.h>

Public Member Functions

 MEANDERED_LINE ()
 
 MEANDERED_LINE (MEANDER_PLACER_BASE *aPlacer, bool aIsDual=false)
 
 ~MEANDERED_LINE ()
 
void AddCorner (const VECTOR2I &aA, const VECTOR2I &aB=VECTOR2I(0, 0))
 Create a dummy meander shape representing a line corner. More...
 
void AddArc (const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
 Create a dummy meander shape representing an arc corner. More...
 
void AddArcAndPt (const SHAPE_ARC &aArc1, const VECTOR2I &aPt2)
 Create a dummy meander shape representing an arc corner. More...
 
void AddPtAndArc (const VECTOR2I &aPt1, const SHAPE_ARC &aArc2)
 Create a dummy meander shape representing an arc corner. More...
 
void AddMeander (MEANDER_SHAPE *aShape)
 Add a new meander shape to the meandered line. More...
 
void Clear ()
 Clear the line geometry, removing all corners and meanders. More...
 
void SetWidth (int aWidth)
 Set the line width. More...
 
void MeanderSegment (const SEG &aSeg, bool aSide, int aBaseIndex=0)
 Fit maximum amplitude meanders on a given segment and adds to the current line. More...
 
void SetBaselineOffset (int aOffset)
 Set the parallel offset between the base segment and the meandered line. More...
 
std::vector< MEANDER_SHAPE * > & Meanders ()
 
bool CheckSelfIntersections (MEANDER_SHAPE *aShape, int aClearance)
 Check if the given shape is intersecting with any other meander in the current line. More...
 
const MEANDER_SETTINGSSettings () const
 

Private Attributes

VECTOR2I m_last
 
MEANDER_PLACER_BASEm_placer
 
std::vector< MEANDER_SHAPE * > m_meanders
 
bool m_dual
 
int m_width
 
int m_baselineOffset
 

Detailed Description

Represent a set of meanders fitted over a single or two lines.

Definition at line 385 of file pns_meander.h.

Constructor & Destructor Documentation

◆ MEANDERED_LINE() [1/2]

PNS::MEANDERED_LINE::MEANDERED_LINE ( )
inline

Definition at line 388 of file pns_meander.h.

389  {
390  // Do not leave uninitialized members, and keep static analyzer quiet:
391  m_placer = nullptr;
392  m_dual = false;
393  m_width = 0;
394  m_baselineOffset = 0;
395  }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511

References m_baselineOffset, m_dual, m_placer, and m_width.

◆ MEANDERED_LINE() [2/2]

PNS::MEANDERED_LINE::MEANDERED_LINE ( MEANDER_PLACER_BASE aPlacer,
bool  aIsDual = false 
)
inline
Parameters
aPlacerthe meander placer instance
aIsDualwhen true, the meanders are generated for two coupled lines

Definition at line 401 of file pns_meander.h.

401  :
402  m_placer( aPlacer ),
403  m_dual( aIsDual )
404  {
405  // Do not leave uninitialized members, and keep static analyzer quiet:
406  m_width = 0;
407  m_baselineOffset = 0;
408  }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511

References m_baselineOffset, and m_width.

◆ ~MEANDERED_LINE()

PNS::MEANDERED_LINE::~MEANDERED_LINE ( )
inline

Definition at line 410 of file pns_meander.h.

411  {
412  Clear();
413  }
void Clear()
Clear the line geometry, removing all corners and meanders.

References Clear().

Member Function Documentation

◆ AddArc()

void PNS::MEANDERED_LINE::AddArc ( const SHAPE_ARC aArc1,
const SHAPE_ARC aArc2 = SHAPE_ARC() 
)

Create a dummy meander shape representing an arc corner.

Allows representing existing arc tracks so they can be reconstructed after length tuning.

Parameters
aArc1Arc shape on the 1st line.
aArc2Arc shape on the 2nd line (if m_dual == true).

Definition at line 577 of file pns_meander.cpp.

578 {
579  MEANDER_SHAPE* m = new MEANDER_SHAPE( m_placer, m_width, m_dual );
580 
581  m->MakeArc( aArc1, aArc2 );
582  m_last = aArc1.GetP1();
583 
584  m_meanders.push_back( m );
585 }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512
const VECTOR2I & GetP1() const
Definition: shape_arc.h:112

References SHAPE_ARC::GetP1(), m_dual, m_last, m_meanders, m_placer, m_width, and PNS::MEANDER_SHAPE::MakeArc().

Referenced by AddArcAndPt(), AddPtAndArc(), and PNS::MEANDER_PLACER::doMove().

◆ AddArcAndPt()

void PNS::MEANDERED_LINE::AddArcAndPt ( const SHAPE_ARC aArc1,
const VECTOR2I aPt2 
)

Create a dummy meander shape representing an arc corner.

Allows representing existing arc tracks so they can be reconstructed after length tuning.

Parameters
aArc1Arc shape on the 1st line.
aPt2corner point of the 2nd line (if m_dual == true).

Definition at line 588 of file pns_meander.cpp.

589 {
590  SHAPE_ARC arc2( aPt2, aPt2, aPt2, 0 );
591 
592  AddArc( aArc1, arc2 );
593 }
void AddArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.

References AddArc().

Referenced by PNS::DP_MEANDER_PLACER::Move().

◆ AddCorner()

void PNS::MEANDERED_LINE::AddCorner ( const VECTOR2I aA,
const VECTOR2I aB = VECTOR2I( 0, 0 ) 
)

Create a dummy meander shape representing a line corner.

Used to define the starts/ends of meandered segments.

Parameters
aAcorner point of the 1st line.
aBcorner point of the 2nd line (if m_dual == true).

Definition at line 566 of file pns_meander.cpp.

567 {
568  MEANDER_SHAPE* m = new MEANDER_SHAPE( m_placer, m_width, m_dual );
569 
570  m->MakeCorner( aA, aB );
571  m_last = aA;
572 
573  m_meanders.push_back( m );
574 }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512

References m_dual, m_last, m_meanders, m_placer, m_width, and PNS::MEANDER_SHAPE::MakeCorner().

Referenced by PNS::MEANDER_PLACER::doMove(), MeanderSegment(), and PNS::DP_MEANDER_PLACER::Move().

◆ AddMeander()

void PNS::MEANDERED_LINE::AddMeander ( MEANDER_SHAPE aShape)

Add a new meander shape to the meandered line.

Parameters
aShapethe meander shape to add

Definition at line 628 of file pns_meander.cpp.

629 {
630  m_last = aShape->BaseSegment().B;
631  m_meanders.push_back( aShape );
632 }
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512

References SEG::B, PNS::MEANDER_SHAPE::BaseSegment(), m_last, and m_meanders.

Referenced by MeanderSegment().

◆ AddPtAndArc()

void PNS::MEANDERED_LINE::AddPtAndArc ( const VECTOR2I aPt1,
const SHAPE_ARC aArc2 
)

Create a dummy meander shape representing an arc corner.

Allows representing existing arc tracks so they can be reconstructed after length tuning.

Parameters
aPt1corner point of the 1st line.
aArc2Arc shape on the 2nd line (if m_dual == true).

Definition at line 596 of file pns_meander.cpp.

597 {
598  SHAPE_ARC arc1( aPt1, aPt1, aPt1, 0 );
599 
600  AddArc( arc1, aArc2 );
601 }
void AddArc(const SHAPE_ARC &aArc1, const SHAPE_ARC &aArc2=SHAPE_ARC())
Create a dummy meander shape representing an arc corner.

References AddArc().

Referenced by PNS::DP_MEANDER_PLACER::Move().

◆ CheckSelfIntersections()

bool PNS::MEANDERED_LINE::CheckSelfIntersections ( MEANDER_SHAPE aShape,
int  aClearance 
)

Check if the given shape is intersecting with any other meander in the current line.

Parameters
aShapethe shape to check.
aClearanceclearance value.
Returns
true, if the meander shape is not colliding.

Definition at line 404 of file pns_meander.cpp.

405 {
406  for( int i = m_meanders.size() - 1; i >= 0; i-- )
407  {
408  MEANDER_SHAPE* m = m_meanders[i];
409 
410  if( m->Type() == MT_EMPTY || m->Type() == MT_CORNER )
411  continue;
412 
413  const SEG& b1 = aShape->BaseSegment();
414  const SEG& b2 = m->BaseSegment();
415 
416  if( b1.ApproxParallel( b2 ) )
417  continue;
418 
419  int n = m->CLine( 0 ).SegmentCount();
420 
421  for( int j = n - 1; j >= 0; j-- )
422  {
423  if( aShape->CLine( 0 ).Collide( m->CLine( 0 ) .CSegment( j ), aClearance ) )
424  return false;
425  }
426  }
427 
428  return true;
429 }
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
Definition: seg.h:290
Definition: seg.h:40

References SEG::ApproxParallel(), PNS::MEANDER_SHAPE::BaseSegment(), PNS::MEANDER_SHAPE::CLine(), SHAPE_LINE_CHAIN::Collide(), SHAPE_LINE_CHAIN::CSegment(), m_meanders, PNS::MT_CORNER, PNS::MT_EMPTY, SHAPE_LINE_CHAIN::SegmentCount(), and PNS::MEANDER_SHAPE::Type().

Referenced by PNS::MEANDER_PLACER::CheckFit(), and PNS::DP_MEANDER_PLACER::CheckFit().

◆ Clear()

void PNS::MEANDERED_LINE::Clear ( )

Clear the line geometry, removing all corners and meanders.

Definition at line 635 of file pns_meander.cpp.

636 {
637  for( MEANDER_SHAPE* m : m_meanders )
638  {
639  delete m;
640  }
641 
642  m_meanders.clear( );
643 }
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512

References m_meanders.

Referenced by ~MEANDERED_LINE().

◆ Meanders()

std::vector<MEANDER_SHAPE*>& PNS::MEANDERED_LINE::Meanders ( )
inline
Returns
set of meander shapes for this line.

Definition at line 489 of file pns_meander.h.

490  {
491  return m_meanders;
492  }
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:512

References m_meanders.

Referenced by PNS::MEANDER_PLACER::doMove(), PNS::DP_MEANDER_PLACER::Move(), and PNS::MEANDER_PLACER_BASE::tuneLineLength().

◆ MeanderSegment()

void PNS::MEANDERED_LINE::MeanderSegment ( const SEG aSeg,
bool  aSide,
int  aBaseIndex = 0 
)

Fit maximum amplitude meanders on a given segment and adds to the current line.

Parameters
aSegthe base segment to meander.
aSideSide to start meandering the segment. True=left, False=Right
aBaseIndexindex of the base segment in the original line.

Definition at line 45 of file pns_meander.cpp.

46 {
47  double base_len = aBase.Length();
48 
50 
51  bool side = aSide;
52  VECTOR2D dir( aBase.B - aBase.A );
53 
54  if( !m_dual )
55  AddCorner( aBase.A );
56 
57  bool turning = false;
58  bool started = false;
59 
60  m_last = aBase.A;
61 
62  do
63  {
64  MEANDER_SHAPE m( m_placer, m_width, m_dual );
65 
66  m.SetBaselineOffset( m_baselineOffset );
67  m.SetBaseIndex( aBaseIndex );
68 
69  double thr = (double) m.spacing();
70 
71  bool fail = false;
72  double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm();
73 
74  auto addSingleIfFits = [&]()
75  {
76  fail = true;
77 
78  for( int i = 0; i < 2; i++ )
79  {
80  bool checkSide = ( i == 0 ) ? side : !side;
81 
82  if( m.Fit( MT_SINGLE, aBase, m_last, checkSide ) )
83  {
84  AddMeander( new MEANDER_SHAPE( m ) );
85  fail = false;
86  started = false;
87  side = !checkSide;
88  break;
89  }
90  }
91  };
92 
93  if( remaining < Settings( ).m_step )
94  break;
95 
96  if( remaining > 3.0 * thr )
97  {
98  if( !turning )
99  {
100  for( int i = 0; i < 2; i++ )
101  {
102  bool checkSide = ( i == 0 ) ? side : !side;
103 
104  if( m.Fit( MT_CHECK_START, aBase, m_last, checkSide ) )
105  {
106  turning = true;
107  AddMeander( new MEANDER_SHAPE( m ) );
108  side = !checkSide;
109  started = true;
110  break;
111  }
112  }
113 
114  if( !turning )
115  addSingleIfFits();
116  }
117  else
118  {
119  bool rv = m.Fit( MT_CHECK_FINISH, aBase, m_last, side );
120 
121  if( rv )
122  {
123  m.Fit( MT_TURN, aBase, m_last, side );
124  AddMeander( new MEANDER_SHAPE( m ) );
125  started = true;
126  }
127  else
128  {
129  m.Fit( MT_FINISH, aBase, m_last, side );
130  started = false;
131  AddMeander( new MEANDER_SHAPE( m ) );
132  turning = false;
133  }
134 
135  side = !side;
136  }
137  }
138  else if( started )
139  {
140  bool rv = m.Fit( MT_FINISH, aBase, m_last, side );
141 
142  if( rv )
143  AddMeander( new MEANDER_SHAPE( m ) );
144 
145  break;
146 
147  }
148  else if( !turning && remaining > thr * 2.0 )
149  {
150  addSingleIfFits();
151  }
152  else
153  {
154  fail = true;
155  }
156 
157  remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( );
158 
159  if( remaining < Settings( ).m_step )
160  break;
161 
162  if( fail )
163  {
164  MEANDER_SHAPE tmp( m_placer, m_width, m_dual );
165  tmp.SetBaselineOffset( m_baselineOffset );
166  tmp.SetBaseIndex( aBaseIndex );
167 
168  int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step;
169  VECTOR2I pn = m_last + dir.Resize( nextP );
170 
171  if( aBase.Contains( pn ) && !m_dual )
172  {
173  AddCorner( pn );
174  } else
175  break;
176  }
177 
178 
179  } while( true );
180 
181  if( !m_dual )
182  AddCorner( aBase.B );
183 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511
void AddCorner(const VECTOR2I &aA, const VECTOR2I &aB=VECTOR2I(0, 0))
Create a dummy meander shape representing a line corner.
const MEANDER_SETTINGS & Settings() const
Definition: pns_meander.cpp:39
int m_step
Length PadToDie.
Definition: pns_meander.h:86
void AddMeander(MEANDER_SHAPE *aShape)
Add a new meander shape to the meandered line.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...

References SEG::A, AddCorner(), AddMeander(), SEG::B, SEG::Contains(), PNS::MEANDER_SHAPE::cornerRadius(), EuclideanNorm(), PNS::MEANDER_SHAPE::Fit(), SEG::Length(), m_baselineOffset, m_dual, m_last, m_placer, PNS::MEANDER_SETTINGS::m_step, m_width, PNS::MT_CHECK_FINISH, PNS::MT_CHECK_START, PNS::MT_FINISH, PNS::MT_SINGLE, PNS::MT_TURN, VECTOR2< T >::Resize(), PNS::MEANDER_SHAPE::SetBaseIndex(), PNS::MEANDER_SHAPE::SetBaselineOffset(), Settings(), and PNS::MEANDER_SHAPE::spacing().

Referenced by PNS::MEANDER_PLACER::doMove(), and PNS::DP_MEANDER_PLACER::Move().

◆ SetBaselineOffset()

void PNS::MEANDERED_LINE::SetBaselineOffset ( int  aOffset)
inline

Set the parallel offset between the base segment and the meandered line.

Used for dual meanders (diff pair) only.

Parameters
aOffsetthe offset.

Definition at line 481 of file pns_meander.h.

482  {
483  m_baselineOffset = aOffset;
484  }

References m_baselineOffset.

Referenced by PNS::MEANDER_PLACER::doMove(), and PNS::DP_MEANDER_PLACER::Move().

◆ Settings()

const MEANDER_SETTINGS & PNS::MEANDERED_LINE::Settings ( ) const
Returns
the current meandering settings.

Definition at line 39 of file pns_meander.cpp.

40 {
41  return m_placer->MeanderSettings();
42 }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:511
virtual const MEANDER_SETTINGS & MeanderSettings() const
Return the current meandering configuration.

References m_placer, and PNS::MEANDER_PLACER_BASE::MeanderSettings().

Referenced by MeanderSegment().

◆ SetWidth()

void PNS::MEANDERED_LINE::SetWidth ( int  aWidth)
inline

Set the line width.

Definition at line 466 of file pns_meander.h.

467  {
468  m_width = aWidth;
469  }

References m_width.

Referenced by PNS::MEANDER_PLACER::doMove(), and PNS::DP_MEANDER_PLACER::Move().

Member Data Documentation

◆ m_baselineOffset

int PNS::MEANDERED_LINE::m_baselineOffset
private

Definition at line 516 of file pns_meander.h.

Referenced by MEANDERED_LINE(), MeanderSegment(), and SetBaselineOffset().

◆ m_dual

bool PNS::MEANDERED_LINE::m_dual
private

Definition at line 514 of file pns_meander.h.

Referenced by AddArc(), AddCorner(), MEANDERED_LINE(), and MeanderSegment().

◆ m_last

VECTOR2I PNS::MEANDERED_LINE::m_last
private

Definition at line 509 of file pns_meander.h.

Referenced by AddArc(), AddCorner(), AddMeander(), and MeanderSegment().

◆ m_meanders

std::vector<MEANDER_SHAPE*> PNS::MEANDERED_LINE::m_meanders
private

Definition at line 512 of file pns_meander.h.

Referenced by AddArc(), AddCorner(), AddMeander(), CheckSelfIntersections(), Clear(), and Meanders().

◆ m_placer

MEANDER_PLACER_BASE* PNS::MEANDERED_LINE::m_placer
private

Definition at line 511 of file pns_meander.h.

Referenced by AddArc(), AddCorner(), MEANDERED_LINE(), MeanderSegment(), and Settings().

◆ m_width

int PNS::MEANDERED_LINE::m_width
private

Definition at line 515 of file pns_meander.h.

Referenced by AddArc(), AddCorner(), MEANDERED_LINE(), MeanderSegment(), and SetWidth().


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