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 411 of file pns_meander.h.

Constructor & Destructor Documentation

◆ MEANDERED_LINE() [1/2]

PNS::MEANDERED_LINE::MEANDERED_LINE ( )
inline

Definition at line 414 of file pns_meander.h.

415 {
416 // Do not leave uninitialized members, and keep static analyzer quiet:
417 m_placer = nullptr;
418 m_dual = false;
419 m_width = 0;
421 }
MEANDER_PLACER_BASE * m_placer
Definition: pns_meander.h:537

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 427 of file pns_meander.h.

427 :
428 m_placer( aPlacer ),
429 m_dual( aIsDual )
430 {
431 // Do not leave uninitialized members, and keep static analyzer quiet:
432 m_width = 0;
434 }

References m_baselineOffset, and m_width.

◆ ~MEANDERED_LINE()

PNS::MEANDERED_LINE::~MEANDERED_LINE ( )
inline

Definition at line 436 of file pns_meander.h.

437 {
438 Clear();
439 }
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 627 of file pns_meander.cpp.

628{
629 MEANDER_SHAPE* m = new MEANDER_SHAPE( m_placer, m_width, m_dual );
630
631 m->MakeArc( aArc1, aArc2 );
632 m_last = aArc1.GetP1();
633
634 m_meanders.push_back( m );
635}
std::vector< MEANDER_SHAPE * > m_meanders
Definition: pns_meander.h:538
const VECTOR2I & GetP1() const
Definition: shape_arc.h:113

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 638 of file pns_meander.cpp.

639{
640 SHAPE_ARC arc2( aPt2, aPt2, aPt2, 0 );
641
642 AddArc( aArc1, arc2 );
643}
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 616 of file pns_meander.cpp.

617{
618 MEANDER_SHAPE* m = new MEANDER_SHAPE( m_placer, m_width, m_dual );
619
620 m->MakeCorner( aA, aB );
621 m_last = aA;
622
623 m_meanders.push_back( m );
624}

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 678 of file pns_meander.cpp.

679{
680 m_last = aShape->BaseSegment().B;
681 m_meanders.push_back( aShape );
682}

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 646 of file pns_meander.cpp.

647{
648 SHAPE_ARC arc1( aPt1, aPt1, aPt1, 0 );
649
650 AddArc( arc1, aArc2 );
651}

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 460 of file pns_meander.cpp.

461{
462 for( int i = m_meanders.size() - 1; i >= 0; i-- )
463 {
464 MEANDER_SHAPE* m = m_meanders[i];
465
466 if( m->Type() == MT_EMPTY || m->Type() == MT_CORNER )
467 continue;
468
469 const SEG& b1 = aShape->BaseSegment();
470 const SEG& b2 = m->BaseSegment();
471
472 if( b1.ApproxParallel( b2 ) )
473 continue;
474
475 int n = m->CLine( 0 ).SegmentCount();
476
477 for( int j = n - 1; j >= 0; j-- )
478 {
479 if( aShape->CLine( 0 ).Collide( m->CLine( 0 ) .CSegment( j ), aClearance ) )
480 return false;
481 }
482 }
483
484 return true;
485}
Definition: seg.h:42
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
Definition: seg.cpp:403
@ MT_EMPTY
Definition: pns_meander.h:46
@ MT_CORNER
Definition: pns_meander.h:44

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::DP_MEANDER_PLACER::CheckFit(), and PNS::MEANDER_PLACER::CheckFit().

◆ Clear()

void PNS::MEANDERED_LINE::Clear ( )

Clear the line geometry, removing all corners and meanders.

Definition at line 685 of file pns_meander.cpp.

686{
687 for( MEANDER_SHAPE* m : m_meanders )
688 {
689 delete m;
690 }
691
692 m_meanders.clear( );
693}

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 515 of file pns_meander.h.

516 {
517 return m_meanders;
518 }

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

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_singleSided, 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 507 of file pns_meander.h.

508 {
509 m_baselineOffset = aOffset;
510 }

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}
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 492 of file pns_meander.h.

493 {
494 m_width = aWidth;
495 }

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 542 of file pns_meander.h.

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

◆ m_dual

bool PNS::MEANDERED_LINE::m_dual
private

Definition at line 540 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 535 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 538 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 537 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 541 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: