115    if( aItem->
Anchor( 0 ) == aP )
 
 
  141            aMidpoint  = ( aP + aN ) / 2;
 
  142            aDirection = segP.
B - segP.
A;
 
  143            aDirection = aDirection.
Resize( ( aP - aN ).EuclideanNorm() );
 
  153    aMidpoint  = ( aP + aN ) / 2;
 
  154    aDirection = ( aP - aN ).Perpendicular();
 
  156    if( aDirection.
Dot( aCursorPos - aMidpoint ) < 0 )
 
  157        aDirection = -aDirection;
 
 
  178    return dir_a.
Angle( dir_b );
 
 
  192            if( dist_sq < gap_sq )
 
 
  277        checkP = ( p0.
Angle( p1 ) & aAllowedAngles ) != 0;
 
  289        checkN = ( n0.
Angle( n1 ) & aAllowedAngles ) != 0;
 
  292    return checkP && checkN;
 
 
  307        VECTOR2I midpoint( ( g.AnchorP() + g.AnchorN() ) / 2 );
 
  308        SEG guide_s( midpoint, midpoint + 
VECTOR2I( 1, 0 ) );
 
  309        SEG guide_d( midpoint, midpoint + 
VECTOR2I( 1, 1 ) );
 
  314        int dist_s = ( proj_s - aCursorPos ).EuclideanNorm();
 
  315        int dist_d = ( proj_d - aCursorPos ).EuclideanNorm();
 
  317        VECTOR2I proj = ( dist_s < dist_d ? proj_s : proj_d );
 
  329            t.SetPriority( aOrthoScore );
 
 
  341    int bestScore = -1000;
 
  348            for( 
bool preferred : { 
false, 
true } )
 
  350                int score = preferred ? 0 : -3;
 
  351                score += g_entry.Priority();
 
  352                score += g_target.Priority();
 
  354                if( score >= bestScore )
 
  358                    if( l.
BuildInitial( g_entry, g_target, preferred ? aPrefDiagonal
 
 
  387    return (dir.
x == 0 && dir.
y != 0) || (dir.
x == dir.
y) || (dir.
y == 0 && dir.
x != 0);
 
 
  394                    [aAngleMask, aRefOrientation]( 
const DP_GATEWAY& dp )
 
  397                        return ( orient.
Angle( aRefOrientation ) & aAngleMask );
 
 
  413    } 
while( ( rv * 2 ).EuclideanNorm() < length );
 
 
  422    int orthoFanDistance = 0;
 
  423    int diagFanDistance = 0;
 
  424    const SHAPE* shP = 
nullptr;
 
  426    if( aPair.
PrimP() == 
nullptr )
 
  450    majorDirection = ( p0_p - p0_n ).Perpendicular();
 
  455    switch( shP->
Type() )
 
  463        int w = 
static_cast<const SHAPE_RECT*
>( shP )->GetWidth();
 
  464        int h = 
static_cast<const SHAPE_RECT*
>( shP )->GetHeight();
 
  469        orthoFanDistance = ( w + 1 )* 3 / 2;
 
  470        diagFanDistance = ( w - h );
 
  476        int w = 
static_cast<const SHAPE_SEGMENT*
>( shP )->GetWidth();
 
  479        orthoFanDistance = w + ( s.
B - s.
A ).EuclideanNorm();
 
  480        diagFanDistance = ( s.
B - s.
A ).EuclideanNorm();
 
  494        orthoFanDistance = ( w + 1 )* 3 / 2;
 
  495        diagFanDistance = ( w - h );
 
  500        wxFAIL_MSG( wxString::Format( wxT( 
"Unsupported starting primitive: %d (%s)." ),
 
  508        int padDist = ( p0_p - p0_n ).EuclideanNorm();
 
  510        for( 
int k = 0; k < 2; k++ )
 
  519            int d = std::max( 0, padDist - 
m_gap );
 
  523            for( 
int i = 0; i < 2; i++ )
 
  525                int sign = i ? -1 : 1;
 
  535                gw.SetEntryLines( entryP, entryN );
 
  536                gw.SetPriority( 100 - k );
 
 
  550    for( 
bool diagonal : { 
false, 
true } )
 
  552        for( 
int i = 0; i < 4; i++ )
 
  569                    dir = 
VECTOR2I( (gap + 1) / 2 * ( ( i % 2 ) ? -1 : 1 ), 0 );
 
  571                    dir = 
VECTOR2I( 0, (gap + 1) / 2 * ( ( i % 2 ) ? -1 : 1 ) );
 
  575                BuildGeneric( aCursorPos + dir, aCursorPos - dir, 
true, 
true );
 
  577                m_gateways.emplace_back( aCursorPos + dir, aCursorPos - dir, diagonal );
 
 
  587        if( !g.HasEntryLines() )
 
  593            g.SetEntryLines( lead_p, lead_n );
 
 
  613    double SIN_22_5 = 0.38268;   
 
  614    double SIN_23_5 = 0.39875;   
 
  616    auto addAngledGateways =
 
  617            [&]( 
int length, 
int priority )
 
  640        addAngledGateways( 
KiROUND( (
double) 
m_gap * SIN_22_5 ), 20 );
 
  644        addAngledGateways( 
KiROUND( (
double) 
m_gap * SIN_23_5 ), 5 );
 
 
  652    SEG st_p[2], st_n[2];
 
  655    const int padToGapThreshold = 3;
 
  656    int padDist = ( p0_n - p0_p ).EuclideanNorm();
 
  668    for( 
int i = 0; i < 2; i++ )
 
  670        bool straightColl = st_p[i].
Collinear( st_n[i] );
 
  671        bool diagColl = d_p[i].
Collinear( d_n[i] );
 
  673        if( straightColl || diagColl )
 
  677            int prio = ( padDist > padToGapThreshold * 
m_gap ) ? 2 : 1;
 
  693    for( 
int i = 0; i < 2; i++ )
 
  695        for( 
int j = 0; j < 2; j++ )
 
  702            if( d_n[i].Collinear( d_p[j] ) )
 
  705            if( st_p[i].Collinear( st_p[j] ) )
 
  710            for( 
int k = 0; k < 2; k++ )
 
  716                    if( m != p0_p && m != p0_n )
 
  718                        int prio = ( padDist > padToGapThreshold * 
m_gap ? 10 : 20 );
 
  719                        VECTOR2I g_p( ( p0_p - m ).Resize( ceil( (
double) 
m_gap * M_SQRT1_2 ) ) );
 
  720                        VECTOR2I g_n( ( p0_n - m ).Resize( ceil( (
double) 
m_gap * M_SQRT1_2 ) ) );
 
  722                        m_gateways.emplace_back( m + g_p, m + g_n, k == 0 ? 
true : 
false,
 
  732            for( 
int k = 0; k < 2; k++ )
 
  738                    if( !aViaMode && m != p0_p && m != p0_n )
 
  742                        g_p = ( p0_p - m ).Resize( ceil( (
double) 
m_gap * M_SQRT2 ) );
 
  743                        g_n = ( p0_n - m ).Resize( ceil( (
double) 
m_gap ) );
 
  746                            m_gateways.emplace_back( m + g_p, m + g_n, 
true );
 
  748                        g_p = ( p0_p - m ).Resize( 
m_gap );
 
  749                        g_n = ( p0_n - m ).Resize( ceil( (
double) 
m_gap * M_SQRT2 ) );
 
  752                            m_gateways.emplace_back( m + g_p, m + g_n, 
true );
 
 
  791    int64_t t_b = p.
TCoef( p.
B );
 
  793    int64_t tproj_a = p.
TCoef( n_proj_p.
A );
 
  794    int64_t tproj_b = p.
TCoef( n_proj_p.
B );
 
  797        std::swap( t_b, t_a );
 
  799    if( tproj_b < tproj_a )
 
  800        std::swap( tproj_b, tproj_a );
 
  809    std::vector<int64_t> tv( t, t + 4 );
 
  810    std::sort( tv.begin(), tv.end() ); 
 
  815    pClip.
A.
x = p.
A.
x + 
rescale( (int64_t)dp.
x, tv[1], pLenSq );
 
  816    pClip.
A.
y = p.
A.
y + 
rescale( (int64_t)dp.
y, tv[1], pLenSq );
 
  818    pClip.
B.
x = p.
A.
x + 
rescale( (int64_t)dp.
x, tv[2], pLenSq );
 
  819    pClip.
B.
y = p.
A.
y + 
rescale( (int64_t)dp.
y, tv[2], pLenSq );
 
 
  830    return m_p.Length() - 
m_n.Length();
 
 
  857                aPairs.push_back( spair );
 
 
  898        l += pair.coupledP.Length();
 
 
  917    double lenP = 
m_p.Length();
 
  918    double lenN = 
m_n.Length();
 
  920    return (lenN + lenP ) / 2.0;
 
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
constexpr size_type GetWidth() const
 
constexpr size_type GetHeight() const
 
Represent route directions & corner angles in a 45-degree metric.
 
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.
 
AngleType Angle(const DIRECTION_45 &aOther) const
Return the type of angle between directions (this) and aOther.
 
const VECTOR2I ToVector() const
 
AngleType
Represent kind of angle formed by vectors heading in two DIRECTION_45s.
 
Basic class for a differential pair.
 
bool CheckConnectionAngle(const DIFF_PAIR &aOther, int allowedAngles) const
 
const SHAPE_LINE_CHAIN & CN() const
 
DP_PRIMITIVE_PAIR EndingPrimitives()
 
std::vector< COUPLED_SEGMENTS > COUPLED_SEGMENTS_VEC
 
double CoupledLength() const
 
bool BuildInitial(const DP_GATEWAY &aEntry, const DP_GATEWAY &aTarget, bool aPrefDiagonal)
 
RANGED_NUM< int > m_gapConstraint
 
double TotalLength() const
 
double CoupledLengthFactor() const
 
void SetShape(const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN &aN, bool aSwapLanes=false)
 
const SHAPE_LINE_CHAIN & CP() const
 
void CoupledSegmentPairs(COUPLED_SEGMENTS_VEC &aPairs) const
 
void BuildFromPrimitivePair(const DP_PRIMITIVE_PAIR &aPair, bool aPreferDiagonal)
 
bool FitGateways(DP_GATEWAYS &aEntry, DP_GATEWAYS &aTarget, bool aPrefDiagonal, DIFF_PAIR &aDp)
 
void BuildGeneric(const VECTOR2I &p0_p, const VECTOR2I &p0_n, bool aBuildEntries=false, bool aViaMode=false)
 
std::vector< DP_GATEWAY > & Gateways()
 
bool checkDiagonalAlignment(const VECTOR2I &a, const VECTOR2I &b) const
 
void BuildOrthoProjections(DP_GATEWAYS &aEntries, const VECTOR2I &aCursorPos, int aOrthoScore)
 
void buildDpContinuation(const DP_PRIMITIVE_PAIR &aPair, bool aIsDiagonal)
 
std::vector< DP_GATEWAY > m_gateways
 
void FilterByOrientation(int aAngleMask, DIRECTION_45 aRefOrientation)
 
void BuildForCursor(const VECTOR2I &aCursorPos)
 
void buildEntries(const VECTOR2I &p0_p, const VECTOR2I &p0_n)
 
Define a "gateway" for routing a differential pair - e.g.
 
SHAPE_LINE_CHAIN m_entryP
 
bool HasEntryLines() const
 
int AllowedAngles() const
 
const VECTOR2I & AnchorN() const
 
SHAPE_LINE_CHAIN m_entryN
 
void SetEntryLines(const SHAPE_LINE_CHAIN &aEntryP, const SHAPE_LINE_CHAIN &aEntryN)
 
const VECTOR2I & AnchorP() const
 
const DIFF_PAIR Entry() const
 
void SetPriority(int aPriority)
 
Store starting/ending primitives (pads, vias or segments) for a differential pair.
 
DIRECTION_45 DirN() const
 
const VECTOR2I & AnchorN() const
 
const VECTOR2I & AnchorP() const
 
DIRECTION_45 anchorDirection(const ITEM *aItem, const VECTOR2I &aP) const
 
void CursorOrientation(const VECTOR2I &aCursorPos, VECTOR2I &aMidpoint, VECTOR2I &aDirection) const
 
DP_PRIMITIVE_PAIR & operator=(const DP_PRIMITIVE_PAIR &aOther)
 
void SetAnchors(const VECTOR2I &aAnchorP, const VECTOR2I &aAnchorN)
 
DIRECTION_45 DirP() const
 
Base class for PNS router board items.
 
virtual const SHAPE * Shape(int aLayer) const
Return the geometrical shape of the item.
 
virtual ITEM * Clone() const =0
Return a deep copy of the item.
 
bool OfKind(int aKindMask) const
 
virtual VECTOR2I Anchor(int n) const
 
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
 
const SEG CSegment(int aIdx) const
Set line width.
 
ecoord SquaredDistance(const SEG &aSeg) const
 
VECTOR2I::extended_type ecoord
 
int Length() const
Return the length (this).
 
static SEG::ecoord Square(int a)
 
bool ApproxParallel(const SEG &aSeg, int aDistanceThreshold=1) const
 
bool Collinear(const SEG &aSeg) const
Check if segment aSeg lies on the same line as (this).
 
ecoord TCoef(const VECTOR2I &aP) const
 
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
 
ecoord SquaredLength() const
 
int Distance(const SEG &aSeg) const
Compute minimum Euclidean distance to segment aSeg.
 
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
 
SHAPE_TYPE Type() const
Return the type of the shape.
 
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.
 
const std::optional< INTERSECTION > SelfIntersecting() const
Check if the line chain is self-intersecting.
 
void Simplify(int aTolerance=0)
Simplify the line chain by removing colinear adjacent segments and duplicate vertices.
 
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
 
bool Intersects(const SEG &aSeg) const
 
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
 
int SegmentCount() const
Return the number of segments in this line chain.
 
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
 
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
 
An abstract shape on 2D plane.
 
virtual const BOX2I BBox(int aClearance=0) const =0
Compute a bounding box of the shape, with a margin of aClearance a collision.
 
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
 
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
 
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
 
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
 
Push and Shove diff pair dimensions (gap) settings dialog.
 
bool commonParallelProjection(SEG p, SEG n, SEG &pClip, SEG &nClip)
 
static VECTOR2I makeGapVector(VECTOR2I dir, int length)
 
static bool checkGap(const SHAPE_LINE_CHAIN &p, const SHAPE_LINE_CHAIN &n, int gap)
 
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
std::optional< VECTOR2I > OPT_VECTOR2I
 
@ SH_RECT
axis-aligned rectangle
 
@ SH_SIMPLE
simple polygon
 
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
 
static wxString SHAPE_TYPE_asString(SHAPE_TYPE a)
 
constexpr int sign(T val)
 
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
 
VECTOR2< int32_t > VECTOR2I