30                           std::vector<VECTOR2I>* aIntersectionPoints = 
nullptr )
 
   32    SEG       segment( p1, p2 );
 
   39    if( aIntersectionPoints )
 
   41        size_t startCount = aIntersectionPoints->size();
 
   44        std::visit( visitor, geom1 );
 
   46        return aIntersectionPoints->size() > startCount;
 
   50        std::vector<VECTOR2I> intersectionPoints;
 
   53        std::visit( visitor, geom1 );
 
   55        return intersectionPoints.size() > 0;
 
 
   63                         std::vector<VECTOR2I>& aIntersectionPoints )
 
   65    if( p1 == p2 || p1 == q2 || q1 == p2 || q1 == q2 )
 
   68    SEG segment1( p1, q1 );
 
   69    SEG segment2( p2, q2 );
 
   74    size_t startCount = aIntersectionPoints.size();
 
   77    std::visit( visitor, geom1 );
 
   79    return aIntersectionPoints.size() > startCount;
 
 
   94    if( a->
GetType() == CREEP_SHAPE::TYPE::UNDEFINED )
 
  100    if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
 
 
  118    if( a->
GetType() == CREEP_SHAPE::TYPE::POINT )
 
  121    if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
 
 
  129                                                    double aMaxSquaredWeight )
 const 
  131    std::vector<PATH_CONNECTION> 
result;
 
  133    double weight = ( this->
GetPos() - aS2.
GetPos() ).SquaredEuclideanNorm();
 
  135    if( weight > aMaxSquaredWeight )
 
  141    pc.
weight = sqrt( weight );
 
 
  149                                                    double aMaxSquaredWeight )
 const 
  151    std::vector<PATH_CONNECTION> 
result;
 
  159    double pointToCenterDistanceSquared = ( pointPos - circleCenter ).SquaredEuclideanNorm();
 
  160    double weightSquared = pointToCenterDistanceSquared - (float) 
radius * (
float) 
radius;
 
  162    if( weightSquared > aMaxSquaredWeight )
 
  166    direction1 = direction1.
Resize( 1 );
 
  170    double radiusSquared = double( 
radius ) * double( 
radius );
 
  172    double distance = sqrt( pointToCenterDistanceSquared );
 
  173    double value1 = radiusSquared / 
distance;
 
  174    double value2 = sqrt( radiusSquared - value1 * value1 );
 
  180    pc.
weight = sqrt( weightSquared );
 
  182    resultPoint = direction1 * value1 + direction2 * value2 + circleCenter;
 
  183    pc.
a2.
x = int( resultPoint.
x );
 
  184    pc.
a2.
y = int( resultPoint.
y );
 
  187    resultPoint = direction1 * value1 - direction2 * value2 + circleCenter;
 
  188    pc.
a2.
x = int( resultPoint.
x );
 
  189    pc.
a2.
y = int( resultPoint.
y );
 
 
  198    std::pair<bool, bool> 
result;
 
  215    double pointAngle = testAngle.
AsRadians();
 
  218    bool connectToEndPoint;
 
  220    connectToEndPoint = ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y >= R );
 
  223        connectToEndPoint &= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R );
 
  225    connectToEndPoint |= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R )
 
  226                         && ( pointAngle >= endAngle || pointAngle <= startAngle );
 
  228    result.first = !connectToEndPoint;
 
  230    connectToEndPoint = ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y >= R );
 
  233        connectToEndPoint &= ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R );
 
  235    connectToEndPoint |= ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R )
 
  236                         && ( pointAngle >= endAngle || pointAngle <= startAngle );
 
  238    result.second = !connectToEndPoint;
 
 
  244                                                    double aMaxSquaredWeight )
 const 
  246    std::vector<PATH_CONNECTION> 
result;
 
  252    std::pair<bool, bool> behavesLikeCircle;
 
  255    if( behavesLikeCircle.first && behavesLikeCircle.second )
 
  258        return this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
 
  261    if( behavesLikeCircle.first )
 
  264        std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
 
  266        if( paths.size() > 1 ) 
 
  267            result.push_back( paths[1] );
 
  277    if( behavesLikeCircle.second )
 
  280        std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
 
  282        if( paths.size() > 1 ) 
 
  283            result.push_back( paths[0] );
 
 
  297                                                     double aMaxSquaredWeight )
 const 
  299    std::vector<PATH_CONNECTION> 
result;
 
  307    double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
 
  309    if( centerDistance + arcRadius < circleRadius )
 
 
  347                                                  double aMaxSquaredWeight )
 const 
  349    std::vector<PATH_CONNECTION> 
result;
 
  355    double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
 
  357    if( centerDistance + arcRadius < circleRadius )
 
  369                                                  aMaxWeight, aMaxSquaredWeight ) )
 
  378                                          .
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) )
 
 
  391                                                     double aMaxSquaredWeight )
 const 
  393    std::vector<PATH_CONNECTION> 
result;
 
  398    VECTOR2D distSquared( 
double( ( p2 - p1 ).x ), 
double( ( p2 - p1 ).y ) );
 
  404    double Rdiff = abs( R1 - R2 );
 
  405    double Rsum = R1 + R2;
 
  408    double weightSquared1 = weightSquared - Rdiff * Rdiff;
 
  410    double weightSquared2 = weightSquared - Rsum * Rsum;
 
  412    if( weightSquared1 <= aMaxSquaredWeight )
 
  415        direction1 = direction1.
Resize( 1 );
 
  418        double D = sqrt( weightSquared );
 
  419        double ratio1 = ( R1 - R2 ) / 
D;
 
  420        double ratio2 = sqrt( 1 - ratio1 * ratio1 );
 
  424        pc.
weight = sqrt( weightSquared1 );
 
  426        pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
 
  427        pc.
a2 = p2 + direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
 
  431        pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
 
  432        pc.
a2 = p2 + direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
 
  436    if( weightSquared2 <= aMaxSquaredWeight )
 
  439        direction1 = direction1.
Resize( 1 );
 
  442        double D = sqrt( weightSquared );
 
  443        double ratio1 = ( R1 + R2 ) / 
D;
 
  444        double ratio2 = sqrt( 1 - ratio1 * ratio1 );
 
  448        pc.
weight = sqrt( weightSquared2 );
 
  450        pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
 
  451        pc.
a2 = p2 - direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
 
  455        pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
 
  456        pc.
a2 = p2 - direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
 
 
  472        switch( p1->GetType() )
 
  474        case CREEP_SHAPE::TYPE::POINT:  
AddNode( GRAPH_NODE::TYPE::POINT, p1, p1->GetPos() );  
break;
 
  475        case CREEP_SHAPE::TYPE::CIRCLE: 
AddNode( GRAPH_NODE::TYPE::CIRCLE, p1, p1->GetPos() ); 
break;
 
  476        case CREEP_SHAPE::TYPE::ARC:    
AddNode( GRAPH_NODE::TYPE::ARC, p1, p1->GetPos() );    
break;
 
 
  486    std::vector<CREEP_SHAPE*> newVector;
 
 
  563            double   tolerance = 10;
 
 
  592    if( 
n1->m_type == GRAPH_NODE::TYPE::VIRTUAL || 
n2->m_type == GRAPH_NODE::TYPE::VIRTUAL )
 
  596            && 
n1->m_parent == 
n2->m_parent
 
  597            && 
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::CIRCLE )
 
  604        if( R1.
Cross( R2 ) > 0 )
 
  616        aShapes.push_back( s );
 
  621            && 
n1->m_parent == 
n2->m_parent
 
  622            && 
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::ARC )
 
  631            if( R1.
Cross( R2 ) > 0 )
 
  646            EDA_ANGLE midAngle = arc->AngleBetweenStartAndEnd( mid );
 
  648            if( midAngle > arc->GetEndAngle() )
 
  657            aShapes.push_back( s );
 
  665    aShapes.push_back( s );
 
 
  696    EDA_ANGLE maxAngle = angle1 > angle2 ? angle1 : angle2;
 
  699    skipAngle += skipAngle; 
 
  700    EDA_ANGLE pointAngle = maxAngle - skipAngle;
 
  710    pc.
a1 = maxAngle == angle2 ? a1->m_pos : a2->m_pos;
 
  716    pc.
a2 = maxAngle == angle2 ? a2->m_pos : a1->m_pos;
 
  719    std::shared_ptr<GRAPH_CONNECTION> gc = aG.
AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
 
  722        gc->m_forceStraightLine = 
true;
 
 
  735    VECTOR2D distI( a1->m_pos - a2->m_pos );
 
  736    VECTOR2D distD( 
double( distI.
x ), 
double( distI.
y ) );
 
  748        pc.
weight = std::max( weight, 0.0 );
 
 
  769    double weight = abs( 
m_radius * ( angle2 - angle1 ).AsRadians() );
 
 
  798                                                      double aMaxSquaredWeight )
 const 
  800    std::vector<PATH_CONNECTION> 
result;
 
  803    double                       halfWidth = this->
GetWidth() / 2;
 
  807    double length = ( start - 
end ).EuclideanNorm();
 
  808    double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - start.
x )
 
  809                          + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - start.
y );
 
  813    if( projectedPos <= 0 )
 
  815        newPoint = start + ( pointPos - start ).Resize( halfWidth );
 
  817    else if( projectedPos >= length )
 
  819        newPoint = 
end + ( pointPos - 
end ).Resize( halfWidth );
 
  823        double posOnSegment = ( start - pointPos ).SquaredEuclideanNorm()
 
  824                              - ( 
end - pointPos ).SquaredEuclideanNorm();
 
  825        posOnSegment = posOnSegment / ( 2 * length ) + length / 2;
 
  827        newPoint = start + ( 
end - start ).Resize( posOnSegment );
 
  828        newPoint += ( pointPos - newPoint ).Resize( halfWidth );
 
  831    double weightSquared = ( pointPos - newPoint ).SquaredEuclideanNorm();
 
  833    if( weightSquared > aMaxSquaredWeight )
 
  839    pc.
weight = sqrt( weightSquared );
 
 
  847                                                      double aMaxSquaredWeight )
 const 
  849    std::vector<PATH_CONNECTION> 
result;
 
  852    double                       halfWidth = this->
GetWidth() / 2;
 
  856    double    length = ( start - 
end ).EuclideanNorm();
 
  859    double   weightSquared = std::numeric_limits<double>::infinity();
 
  860    VECTOR2I PointOnTrack, PointOnCircle;
 
  864    double projectedPos1 = cos( trackAngle.
AsRadians() ) * ( circleCenter.
x - start.
x )
 
  865                           + sin( trackAngle.
AsRadians() ) * ( circleCenter.
y - start.
y );
 
  866    double projectedPos2 = projectedPos1 + circleRadius;
 
  867    projectedPos1 = projectedPos1 - circleRadius;
 
  869    double trackSide = ( 
end - start ).Cross( circleCenter - start ) > 0 ? 1 : -1;
 
  871    if( ( projectedPos1 < 0 && projectedPos2 < 0 ) )
 
  879    else if( ( projectedPos1 > length && projectedPos2 > length ) )
 
  887    else if( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) && ( projectedPos2 >= 0 )
 
  888             && ( projectedPos2 <= length ) )
 
  891        PointOnTrack = start;
 
  892        PointOnTrack += ( 
end - start ).Resize( projectedPos1 );
 
  893        PointOnTrack += ( 
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
 
  894        PointOnCircle = circleCenter - ( 
end - start ).Resize( circleRadius );
 
  895        weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
 
  897        if( weightSquared < aMaxSquaredWeight )
 
  900            pc.
a1 = PointOnTrack;
 
  901            pc.
a2 = PointOnCircle;
 
  902            pc.
weight = sqrt( weightSquared );
 
  906            PointOnTrack = start;
 
  907            PointOnTrack += ( 
end - start ).Resize( projectedPos2 );
 
  908            PointOnTrack += ( 
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
 
  909            PointOnCircle = circleCenter + ( 
end - start ).Resize( circleRadius );
 
  912            pc.
a1 = PointOnTrack;
 
  913            pc.
a2 = PointOnCircle;
 
  918    else if( ( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) )
 
  919             && ( ( projectedPos2 > length ) || projectedPos2 < 0 ) )
 
  922        std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
  927        result.push_back( pcs.at( trackSide == 1 ? 1 : 0 ) );
 
  930        PointOnTrack = start;
 
  931        PointOnTrack += ( 
end - start ).Resize( projectedPos1 );
 
  932        PointOnTrack += ( 
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
 
  933        PointOnCircle = circleCenter - ( 
end - start ).Resize( circleRadius );
 
  934        weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
 
  936        if( weightSquared < aMaxSquaredWeight )
 
  939            pc.
a1 = PointOnTrack;
 
  940            pc.
a2 = PointOnCircle;
 
  941            pc.
weight = sqrt( weightSquared );
 
  946    else if( ( ( projectedPos2 >= 0 ) && ( projectedPos2 <= length ) )
 
  947             && ( ( projectedPos1 > length ) || projectedPos1 < 0 ) )
 
  950        std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
  955        result.push_back( pcs.at( trackSide == 1 ? 0 : 1 ) );
 
  957        PointOnTrack = start;
 
  958        PointOnTrack += ( 
end - start ).Resize( projectedPos2 );
 
  959        PointOnTrack += ( 
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
 
  960        PointOnCircle = circleCenter + ( 
end - start ).Resize( circleRadius );
 
  961        weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
 
  963        if( weightSquared < aMaxSquaredWeight )
 
  966            pc.
a1 = PointOnTrack;
 
  967            pc.
a2 = PointOnCircle;
 
  968            pc.
weight = sqrt( weightSquared );
 
 
  979                                                      double aMaxSquaredWeight )
 const 
  981    std::vector<PATH_CONNECTION> 
result;
 
 1005            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 1011            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 
 1021                                                     double aMaxSquaredWeight )
 const 
 1023    std::vector<PATH_CONNECTION> 
result;
 
 1046            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 1052            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 
 1062                                                  double aMaxSquaredWeight )
 const 
 1064    std::vector<PATH_CONNECTION> 
result;
 
 
 1093                                                  double aMaxSquaredWeight )
 const 
 1095    std::vector<PATH_CONNECTION> 
result;
 
 1118            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 1124            if( !
segmentIntersectsArc( pc.a1, pc.a2, beArcPos, beArcRadius, beArcStartAngle, beArcEndAngle ) )
 
 
 1134                                                     double aMaxSquaredWeight )
 const 
 1136    std::vector<PATH_CONNECTION> 
result;
 
 1141    double   weight = ( 
center - point ).EuclideanNorm() - R;
 
 1143    if( weight > aMaxWeight )
 
 1147    pc.
weight = std::max( weight, 0.0 );
 
 
 1157                                                     double aMaxSquaredWeight )
 const 
 1159    std::vector<PATH_CONNECTION> 
result;
 
 1166    if( ( C1 - C2 ).SquaredEuclideanNorm() < ( R1 - R2 ) * ( R1 - R2 ) )
 
 1172    double weight = ( C1 - C2 ).EuclideanNorm() - R1 - R2;
 
 1174    if( weight > aMaxWeight || weight < 0 )
 
 1178    pc.
weight = std::max( weight, 0.0 );
 
 1179    pc.
a1 = ( C2 - C1 ).Resize( R1 ) + C1;
 
 1180    pc.
a2 = ( C1 - C2 ).Resize( R2 ) + C2;
 
 
 1187                                                      double aMaxSquaredWeight )
 const 
 1189    std::vector<PATH_CONNECTION> 
result;
 
 1193    double   halfWidth = this->
GetWidth() / 2;
 
 1195    EDA_ANGLE trackAngle( s_end - s_start );
 
 1198    double length = ( s_start - s_end ).EuclideanNorm();
 
 1199    double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - s_start.
x )
 
 1200                          + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - s_start.
y );
 
 1202    if( ( projectedPos <= 0 ) || ( s_start == s_end ) )
 
 1205        return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
 1208    if( projectedPos >= length )
 
 1211        return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
 1215    double trackSide = ( s_end - s_start ).Cross( pointPos - s_start ) > 0 ? 1 : -1;
 
 1218    pc.
a1 = s_start + ( s_end - s_start ).Resize( projectedPos )
 
 1219            + ( s_end - s_start ).Perpendicular().
Resize( halfWidth ) * trackSide;
 
 1220    pc.
a2 = ( pc.
a1 - pointPos ).Resize( 
radius ) + pointPos;
 
 1221    pc.
weight = ( pc.
a2 - pc.
a1 ).SquaredEuclideanNorm();
 
 1223    if( pc.
weight <= aMaxSquaredWeight )
 
 
 1234                                                     double aMaxSquaredWeight )
 const 
 1236    std::vector<PATH_CONNECTION> 
result;
 
 1241    double circleRadius = this->
GetRadius();
 
 1249    if( ( circlePos - arcPos ).EuclideanNorm() > arcRadius + circleRadius )
 
 1251        const std::vector<PATH_CONNECTION>& pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
 
 1253        if( pcs.size() == 1 )
 
 1259                result.push_back( pcs[0] );
 
 1271    std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
 
 1272    std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
 
 1276        if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
 
 1282        if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
 
 1290    if( ( circlePos - arcPos ).SquaredEuclideanNorm() < arcRadius * arcRadius )
 
 1292        if( circlePos != arcPos ) 
 
 1298                pc3.
weight = std::max( arcRadius - ( circlePos - arcPos ).EuclideanNorm() - circleRadius, 0.0 );
 
 1299                pc3.
a1 = circlePos + ( circlePos - arcPos ).Resize( circleRadius );
 
 1300                pc3.
a2 = arcPos + ( circlePos - arcPos ).Resize( arcRadius - aS2.
GetWidth() / 2 );
 
 1308    if( bestPath && bestPath->
weight > 0 )
 
 1310        result.push_back( *bestPath );
 
 
 1318                                                      double aMaxSquaredWeight )
 const 
 1320    std::vector<PATH_CONNECTION> 
result;
 
 1324    double   halfWidth1 = this->
GetWidth() / 2;
 
 1328    double   halfWidth2 = aS2.
GetWidth() / 2;
 
 1333    std::vector<PATH_CONNECTION> pcs;
 
 1334    pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
 
 1336    if( pcs.size() < 1 )
 
 1342    if( pcs.size() > 0 )
 
 1344        circlePoint = pcs[0].a1;
 
 1348    if( testAngle < aS2.
GetEndAngle() && pcs.size() > 0 )
 
 1350        result.push_back( pcs[0] );
 
 1360        if( !bestPath || ( bestPath->
weight > pc.weight ) )
 
 1366        if( !bestPath || ( bestPath->
weight > pc.weight ) )
 
 1375        if( !bestPath || ( bestPath->
weight > pc.weight ) )
 
 1382        if( !bestPath || ( bestPath->
weight > pc.weight ) )
 
 1387        result.push_back( *bestPath );
 
 
 1406    t = std::max( 0.0, std::min( 1.0, t ) );
 
 1408    return A + ( AB * t );
 
 
 1414                                                      double aMaxSquaredWeight )
 const 
 1416    std::vector<PATH_CONNECTION> 
result;
 
 1420    double   halfWidth1 = this->
GetWidth() / 2;
 
 1425    double   halfWidth2 = aS2.
GetWidth() / 2;
 
 1433    double dist1 = ( P1 - 
C ).SquaredEuclideanNorm();
 
 1434    double dist2 = ( P2 - 
D ).SquaredEuclideanNorm();
 
 1435    double dist3 = ( P3 - 
A ).SquaredEuclideanNorm();
 
 1436    double dist4 = ( P4 - 
B ).SquaredEuclideanNorm();
 
 1439    double   min_dist = dist1;
 
 1443    if( dist2 < min_dist )
 
 1450    if( dist3 < min_dist )
 
 1457    if( dist4 < min_dist )
 
 1466    pc.
a1 = closest1 + ( closest2 - closest1 ).Resize( halfWidth1 );
 
 1467    pc.
a2 = closest2 + ( closest1 - closest2 ).Resize( halfWidth2 );
 
 1468    pc.
weight = std::max( sqrt( min_dist ) - halfWidth1 - halfWidth2, 0.0 );
 
 1470    if( pc.
weight <= aMaxWeight )
 
 
 1478                                                     double aMaxSquaredWeight )
 const 
 1480    std::vector<PATH_CONNECTION> 
result;
 
 1486    double   dist = ( center1 - center2 ).EuclideanNorm();
 
 1488    if( dist > aMaxWeight || dist == 0 )
 
 1491    double weight = sqrt( dist * dist - R2 * R2 ) - R1;
 
 1492    double theta = asin( R2 / dist );
 
 1493    double psi = acos( R2 / dist );
 
 1495    if( weight > aMaxWeight )
 
 1499    pc.
weight = std::max( weight, 0.0 );
 
 1506    pStart = 
VECTOR2I( R1 * cos( theta + circleAngle ), R1 * sin( theta + circleAngle ) );
 
 1508    pEnd = 
VECTOR2I( -R2 * cos( psi - circleAngle ), R2 * sin( psi - circleAngle ) );
 
 1515    pStart = 
VECTOR2I( R1 * cos( -theta + circleAngle ), R1 * sin( -theta + circleAngle ) );
 
 1517    pEnd = 
VECTOR2I( -R2 * cos( -psi - circleAngle ), R2 * sin( -psi - circleAngle ) );
 
 
 1529                                                  double aMaxSquaredWeight )
 const 
 1531    std::vector<PATH_CONNECTION> 
result;
 
 1547        if( ( point - arcCenter ).SquaredEuclideanNorm() > 
radius * 
radius )
 
 1550            return circle.Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
 1555            pc.
weight = std::max( ( 
radius - width / 2 ) - ( point - arcCenter ).EuclideanNorm(), 0.0 );
 
 1556            pc.
a1 = ( point - arcCenter ).Resize( 
radius - width / 2 ) + arcCenter;
 
 1569        if( ( point - this->
GetStartPoint() ).SquaredEuclideanNorm()
 
 1570                > ( point - this->
GetEndPoint() ).SquaredEuclideanNorm() )
 
 1580        return circle.Paths( aS2, aMaxWeight, aMaxSquaredWeight );
 
 
 1588                                                  double aMaxSquaredWeight )
 const 
 1590    std::vector<PATH_CONNECTION> 
result;
 
 1599    bestPath.
weight = std::numeric_limits<double>::infinity();
 
 1608    for( 
const std::vector<PATH_CONNECTION>& pcs : { csc1.
Paths( csc2, aMaxWeight, aMaxSquaredWeight ),
 
 1609                                                     this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight ),
 
 1610                                                     csc1.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) } )
 
 1622    for( 
const std::vector<PATH_CONNECTION>& pcs : { this->
Paths( csc5, aMaxWeight, aMaxSquaredWeight ),
 
 1623                                                     this->
Paths( csc6, aMaxWeight, aMaxSquaredWeight ),
 
 1624                                                     csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ),
 
 1625                                                     csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) } )
 
 1629            if( bestPath.
weight > pc.weight )
 
 1634    if( bestPath.
weight != std::numeric_limits<double>::infinity() )
 
 1635        result.push_back( bestPath );
 
 
 1642                              std::vector<VECTOR2I>* aIntersectPoints )
 
 1644    SEG    segment( p1, p2 );
 
 1647    std::vector<VECTOR2I> intersectionPoints;
 
 1652    std::visit( visitor, geom1 );
 
 1654    if( aIntersectPoints )
 
 1656        for( 
VECTOR2I& point : intersectionPoints )
 
 1657            aIntersectPoints->push_back( point );
 
 1660    return intersectionPoints.size() > 0;
 
 
 1664                             const std::vector<BOARD_ITEM*>&       aBe,
 
 1665                             const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
 
 1666                             int                                   aMinGrooveWidth )
 
 1668    std::vector<VECTOR2I> intersectionPoints;
 
 1669    bool TestGrooveWidth = aMinGrooveWidth > 0;
 
 1673        if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
 
 1685                                                  intersectionPoints );
 
 1687            if( intersects && !TestGrooveWidth )
 
 1700            bool intersects = 
false;
 
 1706            if( intersects && !TestGrooveWidth )
 
 1716            if( points.size() < 2 )
 
 1719            VECTOR2I prevPoint = points.back();
 
 1721            bool intersects = 
false;
 
 1729            if( intersects && !TestGrooveWidth )
 
 1742            if( intersects && !TestGrooveWidth )
 
 1758            if( intersects && !TestGrooveWidth )
 
 1769    if( intersectionPoints.size() <= 0 )
 
 1772    if( intersectionPoints.size() % 2 != 0 )
 
 1775    int minx = intersectionPoints[0].x;
 
 1776    int maxx = intersectionPoints[0].x;
 
 1777    int miny = intersectionPoints[0].y;
 
 1778    int maxy = intersectionPoints[0].y;
 
 1780    for( 
const VECTOR2I& v : intersectionPoints )
 
 1782        minx = v.x < minx ? v.x : minx;
 
 1783        maxx = v.x > maxx ? v.x : maxx;
 
 1784        miny = v.x < miny ? v.x : miny;
 
 1785        maxy = v.x > maxy ? v.x : maxy;
 
 1788    if( abs( maxx - minx ) > abs( maxy - miny ) )
 
 1790        std::sort( intersectionPoints.begin(), intersectionPoints.end(),
 
 1798        std::sort( intersectionPoints.begin(), intersectionPoints.end(),
 
 1805    int GVSquared = aMinGrooveWidth * aMinGrooveWidth;
 
 1807    for( 
size_t i = 0; i < intersectionPoints.size(); i += 2 )
 
 1809        if( intersectionPoints[i].SquaredDistance( intersectionPoints[i + 1] ) > GVSquared )
 
 
 1819    double                       maxWeight = aMaxWeight;
 
 1820    double                       maxWeightSquared = maxWeight * maxWeight;
 
 1821    std::vector<PATH_CONNECTION> 
result;
 
 1840    if( cuarc1 && cuarc2 )
 
 1841        return cuarc1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1842    if( cuarc1 && cucircle2 )
 
 1843        return cuarc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1844    if( cuarc1 && cusegment2 )
 
 1845        return cuarc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1846    if( cucircle1 && cuarc2 )
 
 1847        return cucircle1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1848    if( cucircle1 && cucircle2 )
 
 1849        return cucircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1850    if( cucircle1 && cusegment2 )
 
 1851        return cucircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1852    if( cusegment1 && cuarc2 )
 
 1853        return cusegment1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1854    if( cusegment1 && cucircle2 )
 
 1855        return cusegment1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1856    if( cusegment1 && cusegment2 )
 
 1857        return cusegment1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1862    if( cuarc1 && bearc2 )
 
 1863        return cuarc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1864    if( cuarc1 && becircle2 )
 
 1865        return cuarc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1866    if( cuarc1 && bepoint2 )
 
 1867        return cuarc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 1868    if( cucircle1 && bearc2 )
 
 1869        return cucircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1870    if( cucircle1 && becircle2 )
 
 1871        return cucircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1872    if( cucircle1 && bepoint2 )
 
 1873        return cucircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 1874    if( cusegment1 && bearc2 )
 
 1875        return cusegment1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1876    if( cusegment1 && becircle2 )
 
 1877        return cusegment1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1878    if( cusegment1 && bepoint2 )
 
 1879        return cusegment1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 1883    if( cuarc2 && bearc1 )
 
 1884        return bearc1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1885    if( cuarc2 && becircle1 )
 
 1886        return becircle1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1887    if( cuarc2 && bepoint1 )
 
 1888        return bepoint1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
 
 1889    if( cucircle2 && bearc1 )
 
 1890        return bearc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1891    if( cucircle2 && becircle1 )
 
 1892        return becircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1893    if( cucircle2 && bepoint1 )
 
 1894        return bepoint1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
 
 1895    if( cusegment2 && bearc1 )
 
 1896        return bearc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1897    if( cusegment2 && becircle1 )
 
 1898        return becircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1899    if( cusegment2 && bepoint1 )
 
 1900        return bepoint1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
 
 1905    if( bearc1 && bearc2 )
 
 1906        return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1907    if( bearc1 && becircle2 )
 
 1908        return bearc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1909    if( bearc1 && bepoint2 )
 
 1910        return bearc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 1911    if( becircle1 && bearc2 )
 
 1912        return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1913    if( becircle1 && becircle2 )
 
 1914        return becircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1915    if( becircle1 && bepoint2 )
 
 1916        return becircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 1917    if( bepoint1 && bearc2 )
 
 1918        return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
 
 1919    if( bepoint1 && becircle2 )
 
 1920        return bepoint1->
Paths( *becircle2, maxWeight, maxWeightSquared );
 
 1921    if( bepoint1 && bepoint2 )
 
 1922        return bepoint1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
 
 
 1928                              std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult ) 
 
 1930    if( !aFrom || !aTo )
 
 1937    std::unordered_map<GRAPH_NODE*, double>     distances;
 
 1938    std::unordered_map<GRAPH_NODE*, GRAPH_NODE*> previous;
 
 1942        double distLeft = distances[
left];
 
 1943        double distRight = distances[
right];
 
 1945        if( distLeft == distRight )
 
 1947        return distLeft > distRight;
 
 1949    std::priority_queue<GRAPH_NODE*, std::vector<GRAPH_NODE*>, 
decltype( cmp )> pq( cmp );
 
 1952    for( 
const std::shared_ptr<GRAPH_NODE>& node : 
m_nodes )
 
 1954        if( node != 
nullptr )
 
 1955            distances[node.get()] = std::numeric_limits<double>::infinity(); 
 
 1958    distances[aFrom.get()] = 0.0;
 
 1959    distances[aTo.get()] = std::numeric_limits<double>::infinity();
 
 1960    pq.push( aFrom.get() );
 
 1963    while( !pq.empty() )
 
 1968        if( current == aTo.get() )
 
 1974        for( 
const std::shared_ptr<GRAPH_CONNECTION>& connection : current->
m_node_conns )
 
 1976            GRAPH_NODE* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
 
 1977                                                                       : ( connection->n1 ).get();
 
 1983            if( connection->m_path.weight < 0.0 )
 
 1985                wxLogTrace( 
"CREEPAGE", 
"Negative weight connection found. Ignoring connection." );
 
 1989            double alt = distances[current] + connection->m_path.weight; 
 
 1991            if( alt < distances[neighbor] )
 
 1993                distances[neighbor] = alt;
 
 1994                previous[neighbor] = current;
 
 1995                pq.push( neighbor );
 
 2000    double pathWeight = distances[aTo.get()];
 
 2003    if( pathWeight == std::numeric_limits<double>::infinity() )
 
 2004        return std::numeric_limits<double>::infinity();
 
 2009    while( step != aFrom.get() )
 
 2013        for( 
const std::shared_ptr<GRAPH_CONNECTION>& node_conn : step->
m_node_conns )
 
 2015            if( ( ( node_conn->n1 ).get() == prevNode && ( node_conn->n2 ).get() == step )
 
 2016                || ( ( node_conn->n1 ).get() == step && ( node_conn->n2 ).get() == prevNode ) )
 
 2018                aResult.push_back( node_conn );
 
 
 2036    switch( aShape.
Type() )
 
 2050        newshape = 
dynamic_cast<CREEP_SHAPE*
>( cucircle );
 
 2064            start = arc.
GetP0();
 
 2070            start = arc.
GetP1();
 
 2084        int nbShapes = 
static_cast<const SHAPE_COMPOUND*
>( &aShape )->Shapes().size();
 
 2085        for( 
const SHAPE* subshape : ( 
static_cast<const SHAPE_COMPOUND*
>( &aShape )->Shapes() ) )
 
 2090                if( !( ( subshape->Type() == 
SH_RECT ) && ( nbShapes == 5 ) ) )
 
 2091                    Addshape( *subshape, aConnectTo, aParent );
 
 2102            const SEG     object = *it;
 
 2104            Addshape( segment, aConnectTo, aParent );
 
 2118            Addshape( segment, aConnectTo, aParent );
 
 2144    std::shared_ptr<GRAPH_NODE> gnShape = 
nullptr;
 
 2148    switch( aShape.
Type() )
 
 2159        gnShape->m_net = aConnectTo->m_net;
 
 2160        std::shared_ptr<GRAPH_CONNECTION> gc = 
AddConnection( gnShape, aConnectTo );
 
 2163            gc->m_path.m_show = 
false;
 
 
 2174    std::vector<std::shared_ptr<GRAPH_NODE>> nodes;
 
 2175    std::mutex                               nodes_lock;
 
 2178    std::copy_if( 
m_nodes.begin(), 
m_nodes.end(), std::back_inserter( nodes ),
 
 2179            [&]( 
const std::shared_ptr<GRAPH_NODE>& gn )
 
 2181                return gn && gn->m_parent && gn->m_connectDirectly && ( gn->m_type != GRAPH_NODE::TYPE::VIRTUAL );
 
 2184    std::sort( nodes.begin(), nodes.end(),
 
 2185            []( 
const std::shared_ptr<GRAPH_NODE>& gn1, 
const std::shared_ptr<GRAPH_NODE>& gn2 )
 
 2187                return gn1->m_parent < gn2->m_parent
 
 2188                        || ( gn1->m_parent == gn2->m_parent && gn1->m_net < gn2->m_net );
 
 2192    std::unordered_map<const BOARD_ITEM*, std::unordered_map<int, std::vector<std::shared_ptr<GRAPH_NODE>>>> parent_net_groups;
 
 2193    std::vector<const BOARD_ITEM*> parent_keys;
 
 2195    for( 
const auto& gn : nodes )
 
 2197        const BOARD_ITEM* parent = gn->m_parent->GetParent();
 
 2199        if( parent_net_groups[parent].
empty() )
 
 2200            parent_keys.push_back( parent );
 
 2202        parent_net_groups[parent][gn->m_net].push_back( gn );
 
 2206    std::vector<std::pair<std::shared_ptr<GRAPH_NODE>, std::shared_ptr<GRAPH_NODE>>> work_items;
 
 2208    for( 
size_t i = 0; i < parent_keys.size(); ++i )
 
 2210        for( 
size_t j = i + 1; j < parent_keys.size(); ++j )
 
 2212            const auto& group1_nets = parent_net_groups[parent_keys[i]];
 
 2213            const auto& group2_nets = parent_net_groups[parent_keys[j]];
 
 2215            for( 
const auto& [net1, nodes1] : group1_nets )
 
 2217                for( 
const auto& [net2, nodes2] : group2_nets )
 
 2222                        bool all_conductive_1 = std::all_of( nodes1.begin(), nodes1.end(),
 
 2225                                    return n->m_parent->IsConductive();
 
 2228                        bool all_conductive_2 = std::all_of( nodes2.begin(), nodes2.end(),
 
 2231                                    return n->m_parent->IsConductive();
 
 2234                        if( all_conductive_1 && all_conductive_2 )
 
 2239                    for( 
const auto& gn1 : nodes1 )
 
 2241                        for( 
const auto& gn2 : nodes2 )
 
 2242                            work_items.push_back( { gn1, gn2 } );
 
 2249    auto processWorkItems =
 
 2250            [&]( 
size_t idx ) -> 
bool 
 2252                auto& [gn1, gn2] = work_items[idx];
 
 2256                    std::vector<const BOARD_ITEM*> IgnoreForTest =
 
 2258                        gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
 
 2267                    std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
 
 2268                    std::lock_guard<std::mutex> lock( nodes_lock );
 
 2271                    if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
 
 2274                        gnt1->m_connectDirectly = 
false;
 
 2277                        if( gn1->m_parent->IsConductive() )
 
 2279                            if( std::shared_ptr<GRAPH_CONNECTION> gc = 
AddConnection( gn1, gnt1 ) )
 
 2280                                gc->m_path.m_show = 
false;
 
 2285                    if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
 
 2288                        gnt2->m_connectDirectly = 
false;
 
 2291                        if( gn2->m_parent->IsConductive() )
 
 2293                            if( std::shared_ptr<GRAPH_CONNECTION> gc = 
AddConnection( gn2, gnt2 ) )
 
 2294                                gc->m_path.m_show = 
false;
 
 2306    if( 
tp.get_tasks_total() >= 
tp.get_thread_count() - 4 )
 
 2308        for( 
size_t ii = 0; ii < work_items.size(); ii++ )
 
 2309            processWorkItems( ii );
 
 2313        auto ret = 
tp.submit_loop( 0, work_items.size(), processWorkItems );
 
 2315        for( 
size_t ii = 0; ii < ret.size(); ii++ )
 
 2322            while( r.wait_for( std::chrono::milliseconds( 100 ) ) != std::future_status::ready ){}
 
 
 2330    std::vector<std::shared_ptr<GRAPH_CONNECTION>> toRemove;
 
 2333    for( std::shared_ptr<GRAPH_CONNECTION>& gc : 
m_connections )
 
 2335        if( gc && ( gc->m_path.weight > aWeightLimit ) )
 
 2336            toRemove.push_back( gc );
 
 2340    for( 
const std::shared_ptr<GRAPH_CONNECTION>& gc : toRemove )
 
 
 2350    for( std::shared_ptr<GRAPH_NODE> gn : { aGc->n1, aGc->n2 } )
 
 2354            gn->m_node_conns.erase( aGc );
 
 2356            if( gn->m_node_conns.empty() && aDelete )
 
 2359                                        [&gn]( 
const std::shared_ptr<GRAPH_NODE>& node )
 
 2361                                            return node.get() == gn.get();
 
 
 2384    std::shared_ptr<GRAPH_NODE> gn = 
FindNode( aType, parent, pos );
 
 2389    gn = std::make_shared<GRAPH_NODE>( aType, parent, pos );
 
 
 2399    std::shared_ptr<GRAPH_NODE> gn = std::make_shared<GRAPH_NODE>( GRAPH_NODE::TYPE::VIRTUAL, 
nullptr );
 
 
 2407                                                                 std::shared_ptr<GRAPH_NODE>& aN2,
 
 2413    wxASSERT_MSG( ( aN1 != aN2 ), 
"Creepage: a connection connects a node to itself" );
 
 2415    std::shared_ptr<GRAPH_CONNECTION> gc = std::make_shared<GRAPH_CONNECTION>( aN1, aN2, aPc );
 
 2417    aN1->m_node_conns.insert( gc );
 
 2418    aN2->m_node_conns.insert( gc );
 
 
 2425                                                                 std::shared_ptr<GRAPH_NODE>& aN2 )
 
 
 2442    auto it = 
m_nodeset.find( std::make_shared<GRAPH_NODE>( aType, aParent, aPos ) );
 
 
 2455    virtualNode->m_net = aNetCode;
 
 2459        for( 
PAD* 
pad : footprint->Pads() )
 
 2461            if( 
pad->GetNetCode() != aNetCode || !
pad->IsOnLayer( aLayer ) )
 
 2464            if( std::shared_ptr<SHAPE> padShape = 
pad->GetEffectiveShape( aLayer ) )
 
 2471        if( track->GetNetCode() != aNetCode || !track->IsOnLayer( aLayer ) )
 
 2474        if( std::shared_ptr<SHAPE> shape = track->GetEffectiveShape() )
 
 2475            Addshape( *shape, virtualNode, track );
 
 2481        if( zone->GetNetCode() != aNetCode || !zone->IsOnLayer( aLayer ) )
 
 2484        if( std::shared_ptr<SHAPE> shape = zone->GetEffectiveShape( aLayer ) )
 
 2485            Addshape( *shape, virtualNode, zone );
 
 2488    const DRAWINGS drawings = 
m_board.Drawings();
 
 2492        if( drawing->IsConnected() )
 
 2500                Addshape( *shape, virtualNode, bci );
 
 
Creepage: a board edge arc.
 
std::pair< bool, bool > IsThereATangentPassingThroughPoint(const BE_SHAPE_POINT aPoint) const
 
EDA_ANGLE GetStartAngle() const override
 
int GetRadius() const override
 
BE_SHAPE_ARC(VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle, VECTOR2D aStartPoint, VECTOR2D aEndPoint)
 
VECTOR2I GetStartPoint() const override
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
 
EDA_ANGLE GetEndAngle() const override
 
VECTOR2I GetEndPoint() const override
 
EDA_ANGLE AngleBetweenStartAndEnd(const VECTOR2I aPoint) const
 
Creepage: a board edge circle.
 
int GetRadius() const override
 
BE_SHAPE_CIRCLE(VECTOR2I aPos=VECTOR2I(0, 0), int aRadius=0)
 
void ShortenChildDueToGV(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG, double aNormalWeight) const
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
 
Creepage: a board edge point.
 
BE_SHAPE_POINT(VECTOR2I aPos)
 
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
 
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
 
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
 
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
 
Represent basic circle geometry with utility geometry functions.
 
A graph with nodes and connections for creepage calculation.
 
std::shared_ptr< GRAPH_NODE > AddNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent=nullptr, const VECTOR2I &aPos=VECTOR2I())
 
std::shared_ptr< GRAPH_CONNECTION > AddConnection(std::shared_ptr< GRAPH_NODE > &aN1, std::shared_ptr< GRAPH_NODE > &aN2, const PATH_CONNECTION &aPc)
 
void SetTarget(double aTarget)
 
double Solve(std::shared_ptr< GRAPH_NODE > &aFrom, std::shared_ptr< GRAPH_NODE > &aTo, std::vector< std::shared_ptr< GRAPH_CONNECTION > > &aResult)
 
void Addshape(const SHAPE &aShape, std::shared_ptr< GRAPH_NODE > &aConnectTo, BOARD_ITEM *aParent=nullptr)
 
std::vector< CREEP_SHAPE * > m_shapeCollection
 
void TransformEdgeToCreepShapes()
 
std::shared_ptr< GRAPH_NODE > AddNodeVirtual()
 
void TransformCreepShapesToNodes(std::vector< CREEP_SHAPE * > &aShapes)
 
void Trim(double aWeightLimit)
 
SHAPE_POLY_SET * m_boardOutline
 
void RemoveDuplicatedShapes()
 
std::vector< BOARD_ITEM * > m_boardEdge
 
double m_creepageTargetSquared
 
std::unordered_set< std::shared_ptr< GRAPH_NODE >, GraphNodeHash, GraphNodeEqual > m_nodeset
 
void GeneratePaths(double aMaxWeight, PCB_LAYER_ID aLayer)
 
std::vector< std::shared_ptr< GRAPH_NODE > > m_nodes
 
std::vector< std::shared_ptr< GRAPH_CONNECTION > > m_connections
 
std::shared_ptr< GRAPH_NODE > AddNetElements(int aNetCode, PCB_LAYER_ID aLayer, int aMaxCreepage)
 
void RemoveConnection(const std::shared_ptr< GRAPH_CONNECTION > &, bool aDelete=false)
 
std::shared_ptr< GRAPH_NODE > FindNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, const VECTOR2I &aPos)
 
A class used to represent the shapes for creepage calculation.
 
CREEP_SHAPE::TYPE GetType() const
 
void SetParent(BOARD_ITEM *aParent)
 
virtual int GetRadius() const
 
virtual void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const
 
Creepage: a conductive arc.
 
VECTOR2I GetStartPoint() const override
 
EDA_ANGLE AngleBetweenStartAndEnd(const VECTOR2I aPoint) const
 
VECTOR2I GetEndPoint() const override
 
EDA_ANGLE GetStartAngle() const override
 
CU_SHAPE_ARC(VECTOR2I aPos, double aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle, VECTOR2D aStartPoint, VECTOR2D aEndPoint)
 
int GetRadius() const override
 
EDA_ANGLE GetEndAngle() const override
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
Creepage: a conductive circle.
 
int GetRadius() const override
 
CU_SHAPE_CIRCLE(VECTOR2I aPos, double aRadius=0)
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
Creepage: a conductive segment.
 
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
 
VECTOR2I GetStart() const
 
CU_SHAPE_SEGMENT(VECTOR2I aStart, VECTOR2I aEnd, double aWidth=0)
 
void SetCenter(const VECTOR2I &aCenter)
 
VECTOR2I getCenter() const
 
std::vector< VECTOR2I > GetPolyPoints() const
Duplicate the polygon outlines into a flat list of VECTOR2I points.
 
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
 
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
 
void SetStart(const VECTOR2I &aStart)
 
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
 
void SetEnd(const VECTOR2I &aEnd)
 
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
 
VECTOR2I GetArcMid() const
 
std::shared_ptr< GRAPH_NODE > n2
 
void GetShapes(std::vector< PCB_SHAPE > &aShapes)
 
std::shared_ptr< GRAPH_NODE > n1
 
std::set< std::shared_ptr< GRAPH_CONNECTION > > m_node_conns
 
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
 
const VECTOR2I & GetArcMid() const
 
int GetWidth() const override
 
const VECTOR2I & GetP1() const
 
const VECTOR2I & GetP0() const
 
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 VECTOR2I & CLastPoint() const
Return the last point in the line chain.
 
const std::vector< VECTOR2I > & CPoints() const
 
Represent a set of closed polygons.
 
CONST_SEGMENT_ITERATOR CIterateSegmentsWithHoles() const
Return an iterator object, for the aOutline-th outline in the set (with holes).
 
const VECTOR2I & GetPosition() const
 
const VECTOR2I GetSize() const
 
const SEG & GetSeg() const
 
int GetWidth() const override
 
An abstract shape on 2D plane.
 
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
 
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
 
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.
 
Handle a list of polygons defining a copper zone.
 
static bool empty(const wxTextEntryBase *aCtrl)
 
VECTOR2I closestPointOnSegment(const VECTOR2I &A, const VECTOR2I &B, const VECTOR2I &P)
 
bool SegmentIntersectsBoard(const VECTOR2I &aP1, const VECTOR2I &aP2, const std::vector< BOARD_ITEM * > &aBe, const std::vector< const BOARD_ITEM * > &aDontTestAgainst, int aMinGrooveWidth)
 
std::vector< PATH_CONNECTION > GetPaths(CREEP_SHAPE *aS1, CREEP_SHAPE *aS2, double aMaxWeight)
 
bool segmentIntersectsArc(const VECTOR2I &p1, const VECTOR2I &p2, const VECTOR2I ¢er, double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle, std::vector< VECTOR2I > *aIntersectionPoints=nullptr)
 
bool compareShapes(const CREEP_SHAPE *a, const CREEP_SHAPE *b)
 
bool segments_intersect(const VECTOR2I &p1, const VECTOR2I &q1, const VECTOR2I &p2, const VECTOR2I &q2, std::vector< VECTOR2I > &aIntersectionPoints)
 
bool areEquivalent(const CREEP_SHAPE *a, const CREEP_SHAPE *b)
 
bool segmentIntersectsCircle(const VECTOR2I &p1, const VECTOR2I &p2, const VECTOR2I ¢er, double radius, std::vector< VECTOR2I > *aIntersectPoints)
 
static constexpr EDA_ANGLE ANGLE_0
 
static constexpr EDA_ANGLE ANGLE_360
 
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
 
std::variant< LINE, HALF_LINE, SEG, CIRCLE, SHAPE_ARC, BOX2I > INTERSECTABLE_GEOM
A variant type that can hold any of the supported geometry types for intersection calculations.
 
PCB_LAYER_ID
A quick note on layer IDs:
 
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
 
@ SH_POLY_SET
set of polygons (with holes, etc.)
 
@ SH_RECT
axis-aligned rectangle
 
@ SH_LINE_CHAIN
line chain (polyline)
 
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
 
A visitor that visits INTERSECTABLE_GEOM variant objects with another (which is held as state: m_othe...
 
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
 
wxString result
Test unit parsing edge cases and error handling.
 
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
 
BS::thread_pool< 0 > thread_pool
 
VECTOR2< int32_t > VECTOR2I
 
VECTOR2< double > VECTOR2D