int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { int sum = 0; for( int i = 0; i < SegmentCount(); i++ ) { const SEG seg = CSegment( i ); int d = seg.Distance( aP ); if( d <= 1 ) { sum += ( aP - seg.A ).EuclideanNorm(); return sum; } else sum += seg.Length(); } return -1; }
void PNS_MEANDERED_LINE::MeanderSegment( const SEG& aBase, int aBaseIndex ) { double base_len = aBase.Length(); SHAPE_LINE_CHAIN lc; bool side = true; VECTOR2D dir( aBase.B - aBase.A ); if( !m_dual ) AddCorner( aBase.A ); bool turning = false; bool started = false; m_last = aBase.A; do { PNS_MEANDER_SHAPE* m = new PNS_MEANDER_SHAPE( m_placer, m_width, m_dual ); m->SetBaselineOffset( m_baselineOffset ); m->SetBaseIndex( aBaseIndex ); double thr = (double) m->spacing(); bool fail = false; double remaining = base_len - ( m_last - aBase.A ).EuclideanNorm(); if( remaining < Settings( ).m_step ) break; if( remaining > 3.0 * thr ) { if( !turning ) { for( int i = 0; i < 2; i++ ) { if ( m->Fit( MT_CHECK_START, aBase, m_last, i ) ) { turning = true; AddMeander( m ); side = !i; started = true; break; } } if( !turning ) { fail = true; for( int i = 0; i < 2; i++ ) { if ( m->Fit ( MT_SINGLE, aBase, m_last, i ) ) { AddMeander( m ); fail = false; started = false; side = !i; break; } } } } else { bool rv = m->Fit( MT_CHECK_FINISH, aBase, m_last, side ); if( rv ) { m->Fit( MT_TURN, aBase, m_last, side ); AddMeander( m ); started = true; } else { m->Fit( MT_FINISH, aBase, m_last, side ); started = false; AddMeander( m ); turning = false; } side = !side; } } else if( started ) { bool rv = m->Fit( MT_FINISH, aBase, m_last, side ); if( rv ) AddMeander( m ); break; } else { fail = true; } remaining = base_len - ( m_last - aBase.A ).EuclideanNorm( ); if( remaining < Settings( ).m_step ) break; if( fail ) { PNS_MEANDER_SHAPE tmp( m_placer, m_width, m_dual ); tmp.SetBaselineOffset( m_baselineOffset ); tmp.SetBaseIndex( aBaseIndex ); int nextP = tmp.spacing() - 2 * tmp.cornerRadius() + Settings().m_step; VECTOR2I pn = m_last + dir.Resize( nextP ); if( aBase.Contains( pn ) && !m_dual ) { AddCorner( pn ); } else break; } } while( true ); if( !m_dual ) AddCorner( aBase.B ); }