31 std::vector<VECTOR2I>* aIntersectPoints );
37 std::vector<VECTOR2I>* aIntersectPoints )
39 if( p1 == p2 || p1 == q2 || q1 == p2 || q1 == q2 )
42 SEG segment1( p1, q1 );
43 SEG segment2( p2, q2 );
45 std::vector<VECTOR2I> intersectionPoints;
53 std::visit( visitor, geom1 );
55 if( aIntersectPoints )
57 for(
VECTOR2I& point : intersectionPoints )
58 aIntersectPoints->push_back( point );
62 return intersectionPoints.size() > 0;
78 if( a->
GetType() == CREEP_SHAPE::TYPE::UNDEFINED )
88 if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
101 if( ( !a && b ) || ( a && !b ) )
109 if( a->
GetType() == CREEP_SHAPE::TYPE::POINT )
113 if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
122 double aMaxSquaredWeight )
const
124 std::vector<PATH_CONNECTION> result;
126 double weight = ( this->
GetPos() - aS2.
GetPos() ).SquaredEuclideanNorm();
128 if( weight > aMaxSquaredWeight )
134 pc.
weight = sqrt( weight );
136 result.push_back( pc );
141 double aMaxSquaredWeight )
const
143 std::vector<PATH_CONNECTION> result;
153 double pointToCenterDistanceSquared = ( pointPos - circleCenter ).SquaredEuclideanNorm();
154 double weightSquared = pointToCenterDistanceSquared - (float) radius * (
float) radius;
156 if( weightSquared > aMaxSquaredWeight )
161 direction1 = direction1.
Resize( 1 );
165 double radiusSquared = double( radius ) * double( radius );
167 double distance = sqrt( pointToCenterDistanceSquared );
168 double value1 = radiusSquared /
distance;
169 double value2 = sqrt( radiusSquared - value1 * value1 );
175 pc.
weight = sqrt( weightSquared );
177 resultPoint = direction1 * value1 + direction2 * value2 + circleCenter;
178 pc.
a2.
x = int( resultPoint.
x );
179 pc.
a2.
y = int( resultPoint.
y );
180 result.push_back( pc );
182 resultPoint = direction1 * value1 - direction2 * value2 + circleCenter;
183 pc.
a2.
x = int( resultPoint.
x );
184 pc.
a2.
y = int( resultPoint.
y );
185 result.push_back( pc );
193 std::pair<bool, bool> result;
201 result.first =
false;
202 result.second =
false;
210 double pointAngle = testAngle.
AsRadians();
213 bool connectToEndPoint;
215 connectToEndPoint = ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y >= R );
218 connectToEndPoint &= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R );
220 connectToEndPoint |= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R )
221 && ( pointAngle >= endAngle || pointAngle <= startAngle );
224 result.first = !connectToEndPoint;
226 connectToEndPoint = ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y >= R );
230 ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R );
232 connectToEndPoint |= ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R )
233 && ( pointAngle >= endAngle || pointAngle <= startAngle );
236 result.second = !connectToEndPoint;
241 double aMaxSquaredWeight )
const
243 std::vector<PATH_CONNECTION> result;
249 std::pair<bool, bool> behavesLikeCircle;
252 if( behavesLikeCircle.first && behavesLikeCircle.second )
255 return this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
258 if( behavesLikeCircle.first )
261 std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
263 if( paths.size() > 1 )
265 result.push_back( paths[1] );
274 result.push_back( pc );
277 if( behavesLikeCircle.second )
280 std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
282 if( paths.size() > 1 )
284 result.push_back( paths[0] );
293 result.push_back( pc );
300 double aMaxSquaredWeight )
const
302 std::vector<PATH_CONNECTION> result;
310 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
312 if( centerDistance + arcRadius < circleRadius )
328 result.push_back( pc );
331 if( result.size() == 4 )
342 arcEndAngle,
nullptr ) )
343 result.push_back( pc );
353 double aMaxSquaredWeight )
const
355 std::vector<PATH_CONNECTION> result;
361 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
363 if( centerDistance + arcRadius < circleRadius )
375 aMaxWeight, aMaxSquaredWeight ) )
380 result.push_back( pc );
384 .
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) )
389 result.push_back( pc );
397 double aMaxSquaredWeight )
const
399 std::vector<PATH_CONNECTION> result;
404 VECTOR2D distSquared(
double( ( p2 - p1 ).x ),
double( ( p2 - p1 ).y ) );
410 double Rdiff = abs( R1 - R2 );
411 double Rsum = R1 + R2;
414 double weightSquared1 = weightSquared - Rdiff * Rdiff;
416 double weightSquared2 = weightSquared - Rsum * Rsum;
418 if( weightSquared1 <= aMaxSquaredWeight )
421 direction1 = direction1.
Resize( 1 );
424 double D = sqrt( weightSquared );
425 double ratio1 = ( R1 - R2 ) /
D;
426 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
430 pc.
weight = sqrt( weightSquared1 );
432 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
433 pc.
a2 = p2 + direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
435 result.push_back( pc );
437 pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
438 pc.
a2 = p2 + direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
440 result.push_back( pc );
442 if( weightSquared2 <= aMaxSquaredWeight )
445 direction1 = direction1.
Resize( 1 );
448 double D = sqrt( weightSquared );
449 double ratio1 = ( R1 + R2 ) /
D;
450 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
454 pc.
weight = sqrt( weightSquared2 );
456 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
457 pc.
a2 = p2 - direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
459 result.push_back( pc );
461 pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
462 pc.
a2 = p2 - direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
464 result.push_back( pc );
478 switch( p1->GetType() )
480 case CREEP_SHAPE::TYPE::POINT:
AddNode( GRAPH_NODE::TYPE::POINT, p1, p1->GetPos() );
break;
481 case CREEP_SHAPE::TYPE::CIRCLE:
AddNode( GRAPH_NODE::TYPE::CIRCLE, p1, p1->GetPos() );
break;
482 case CREEP_SHAPE::TYPE::ARC:
AddNode( GRAPH_NODE::TYPE::ARC, p1, p1->GetPos() );
break;
492 std::vector<CREEP_SHAPE*> newVector;
529 case SHAPE_T::SEGMENT:
537 case SHAPE_T::RECTANGLE:
551 std::vector<VECTOR2I> points;
554 for(
auto p : points )
561 case SHAPE_T::CIRCLE:
572 double tolerance = 10;
595 std::vector<PCB_SHAPE> shapes = std::vector<PCB_SHAPE>();
604 if(
n1->m_type == GRAPH_NODE::TYPE::VIRTUAL ||
n2->m_type == GRAPH_NODE::TYPE::VIRTUAL )
610 && (
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::CIRCLE ) )
617 if( R1.
Cross( R2 ) > 0 )
633 shapes.push_back( s );
638 &&
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::ARC )
652 shapes.push_back( s );
662 if( R1.
Cross( R2 ) > 0 )
691 shapes.push_back( s );
700 shapes.push_back( s );
718 double aNormalWeight )
const
733 EDA_ANGLE maxAngle = angle1 > angle2 ? angle1 : angle2;
736 skipAngle += skipAngle;
737 EDA_ANGLE pointAngle = maxAngle - skipAngle;
748 pc.
a1 = maxAngle == angle2 ? a1->m_pos : a2->m_pos;
754 pc.
a2 = maxAngle == angle2 ? a2->m_pos : a1->m_pos;
757 std::shared_ptr<GRAPH_CONNECTION> gc = aG.
AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
760 gc->m_forceStraightLine =
true;
773 VECTOR2D distI( a1->m_pos - a2->m_pos );
774 VECTOR2D distD(
double( distI.
x ),
double( distI.
y ) );
810 double weight = abs(
m_radius * ( angle2 - angle1 ).AsRadians() );
840 std::vector<VECTOR2I>* aIntersectPoints )
842 SEG segment( p1, p2 );
845 radius * sin( startAngle.
AsRadians() ) );
846 startPoint += center;
847 SHAPE_ARC arc( center, startPoint, endAngle - startAngle );
849 std::vector<VECTOR2I> intersectionPoints;
854 std::visit( visitor, geom1 );
856 if( aIntersectPoints )
858 for(
VECTOR2I& point : intersectionPoints )
859 aIntersectPoints->push_back( point );
862 return intersectionPoints.size() > 0;
866 double aMaxSquaredWeight )
const
868 std::vector<PATH_CONNECTION> result;
871 double halfWidth = this->
GetWidth() / 2;
875 double length = ( start - end ).EuclideanNorm();
876 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - start.
x )
877 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - start.
y );
881 if( projectedPos <= 0 )
883 newPoint = start + ( pointPos - start ).Resize( halfWidth );
885 else if( projectedPos >= length )
887 newPoint = end + ( pointPos - end ).Resize( halfWidth );
891 double posOnSegment = ( start - pointPos ).SquaredEuclideanNorm()
892 - ( end - pointPos ).SquaredEuclideanNorm();
893 posOnSegment = posOnSegment / ( 2 * length ) + length / 2;
895 newPoint = start + ( end - start ).Resize( posOnSegment );
896 newPoint += ( pointPos - newPoint ).Resize( halfWidth );
899 double weightSquared = ( pointPos - newPoint ).SquaredEuclideanNorm();
901 if( weightSquared > aMaxSquaredWeight )
907 pc.
weight = sqrt( weightSquared );
909 result.push_back( pc );
915 double aMaxSquaredWeight )
const
917 std::vector<PATH_CONNECTION> result;
920 double halfWidth = this->
GetWidth() / 2;
924 double length = ( start - end ).EuclideanNorm();
927 double weightSquared = std::numeric_limits<double>::infinity();
928 VECTOR2I PointOnTrack, PointOnCircle;
932 double projectedPos1 = cos( trackAngle.
AsRadians() ) * ( circleCenter.
x - start.
x )
933 + sin( trackAngle.
AsRadians() ) * ( circleCenter.
y - start.
y );
934 double projectedPos2 = projectedPos1 + circleRadius;
935 projectedPos1 = projectedPos1 - circleRadius;
937 double trackSide = ( end - start ).Cross( circleCenter - start ) > 0 ? 1 : -1;
939 if( ( projectedPos1 < 0 && projectedPos2 < 0 ) )
944 result.push_back( pc );
947 else if( ( projectedPos1 > length && projectedPos2 > length ) )
952 result.push_back( pc );
956 else if( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) && ( projectedPos2 >= 0 )
957 && ( projectedPos2 <= length ) )
960 PointOnTrack = start;
961 PointOnTrack += ( end - start ).Resize( projectedPos1 );
962 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
963 PointOnCircle = circleCenter - ( end - start ).Resize( circleRadius );
964 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
966 if( weightSquared < aMaxSquaredWeight )
969 pc.
a1 = PointOnTrack;
970 pc.
a2 = PointOnCircle;
971 pc.
weight = sqrt( weightSquared );
973 result.push_back( pc );
975 PointOnTrack = start;
976 PointOnTrack += ( end - start ).Resize( projectedPos2 );
977 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
978 PointOnCircle = circleCenter + ( end - start ).Resize( circleRadius );
981 pc.
a1 = PointOnTrack;
982 pc.
a2 = PointOnCircle;
984 result.push_back( pc );
987 else if( ( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) )
988 && ( ( projectedPos2 > length ) || projectedPos2 < 0 ) )
991 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
996 result.push_back( pcs.at( trackSide == 1 ? 1 : 0 ) );
999 PointOnTrack = start;
1000 PointOnTrack += ( end - start ).Resize( projectedPos1 );
1001 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1002 PointOnCircle = circleCenter - ( end - start ).Resize( circleRadius );
1003 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
1005 if( weightSquared < aMaxSquaredWeight )
1008 pc.
a1 = PointOnTrack;
1009 pc.
a2 = PointOnCircle;
1010 pc.
weight = sqrt( weightSquared );
1012 result.push_back( pc );
1015 else if( ( ( projectedPos2 >= 0 ) && ( projectedPos2 <= length ) )
1016 && ( ( projectedPos1 > length ) || projectedPos1 < 0 ) )
1019 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1021 if( pcs.size() < 2 )
1024 result.push_back( pcs.at( trackSide == 1 ? 0 : 1 ) );
1026 PointOnTrack = start;
1027 PointOnTrack += ( end - start ).Resize( projectedPos2 );
1028 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1029 PointOnCircle = circleCenter + ( end - start ).Resize( circleRadius );
1030 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
1032 if( weightSquared < aMaxSquaredWeight )
1035 pc.
a1 = PointOnTrack;
1036 pc.
a2 = PointOnCircle;
1037 pc.
weight = sqrt( weightSquared );
1039 result.push_back( pc );
1048 double aMaxSquaredWeight )
const
1050 std::vector<PATH_CONNECTION> result;
1054 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1060 result.push_back( pc );
1064 if( result.size() < 2 )
1074 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1076 beArcEndAngle,
nullptr ) )
1077 result.push_back( pc );
1079 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1081 beArcEndAngle,
nullptr ) )
1082 result.push_back( pc );
1090 double aMaxSquaredWeight )
const
1092 std::vector<PATH_CONNECTION> result;
1100 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1106 result.push_back( pc );
1110 if( result.size() < 2 )
1115 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1117 beArcEndAngle,
nullptr ) )
1118 result.push_back( pc );
1120 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1122 beArcEndAngle,
nullptr ) )
1123 result.push_back( pc );
1129 double aMaxSquaredWeight )
const
1131 std::vector<PATH_CONNECTION> result;
1135 for(
auto& pc : this->
Paths( csc, aMaxWeight, aMaxSquaredWeight ) )
1141 result.push_back( pc );
1145 if( result.size() < 2 )
1150 for(
auto& pc : this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight ) )
1151 result.push_back( pc );
1153 for(
auto& pc : this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight ) )
1154 result.push_back( pc );
1162 double aMaxSquaredWeight )
const
1164 std::vector<PATH_CONNECTION> result;
1172 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1178 result.push_back( pc );
1182 if( result.size() < 2 )
1187 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1189 beArcEndAngle,
nullptr ) )
1190 result.push_back( pc );
1192 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1194 beArcEndAngle,
nullptr ) )
1195 result.push_back( pc );
1203 double aMaxSquaredWeight )
const
1205 std::vector<PATH_CONNECTION> result;
1210 double weight = ( center - point ).EuclideanNorm() - R;
1212 if( weight > aMaxWeight )
1218 pc.
a1 = center + ( point - center ).Resize( R );
1220 result.push_back( pc );
1226 double aMaxSquaredWeight )
const
1228 std::vector<PATH_CONNECTION> result;
1235 if( ( C1 - C2 ).SquaredEuclideanNorm() < ( R1 - R2 ) * ( R1 - R2 ) )
1241 double weight = ( C1 - C2 ).EuclideanNorm() - R1 - R2;
1243 if( weight > aMaxWeight || weight < 0 )
1248 pc.
a1 = ( C2 - C1 ).Resize( R1 ) + C1;
1249 pc.
a2 = ( C1 - C2 ).Resize( R2 ) + C2;
1250 result.push_back( pc );
1256 double aMaxSquaredWeight )
const
1258 std::vector<PATH_CONNECTION> result;
1262 double halfWidth = this->
GetWidth() / 2;
1264 EDA_ANGLE trackAngle( s_end - s_start );
1267 double length = ( s_start - s_end ).EuclideanNorm();
1268 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - s_start.
x )
1269 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - s_start.
y );
1271 if( ( projectedPos <= 0 ) || ( s_start == s_end ) )
1274 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1276 if( projectedPos >= length )
1279 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1283 double trackSide = ( s_end - s_start ).Cross( pointPos - s_start ) > 0 ? 1 : -1;
1286 pc.
a1 = s_start + ( s_end - s_start ).Resize( projectedPos )
1287 + ( s_end - s_start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1288 pc.
a2 = ( pc.
a1 - pointPos ).Resize( radius ) + pointPos;
1289 pc.
weight = ( pc.
a2 - pc.
a1 ).SquaredEuclideanNorm();
1291 if( pc.
weight <= aMaxSquaredWeight )
1294 result.push_back( pc );
1301 double aMaxSquaredWeight )
const
1303 std::vector<PATH_CONNECTION> result;
1308 double circleRadius = this->
GetRadius();
1316 if( ( circlePos - arcPos ).EuclideanNorm() > arcRadius + circleRadius )
1318 std::vector<PATH_CONNECTION> pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1320 if( pcs.size() == 1 )
1326 result.push_back( pcs[0] );
1338 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
1339 std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1343 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1349 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1357 if( ( circlePos - arcPos ).SquaredEuclideanNorm() < arcRadius * arcRadius )
1359 if( circlePos != arcPos )
1365 pc3.
weight = arcRadius - ( circlePos - arcPos ).EuclideanNorm() - circleRadius;
1366 pc3.
a1 = circlePos + ( circlePos - arcPos ).Resize( circleRadius );
1367 pc3.
a2 = arcPos + ( circlePos - arcPos ).Resize( arcRadius - aS2.
GetWidth() / 2 );
1375 if( bestPath && bestPath->
weight > 0 )
1377 result.push_back( *bestPath );
1385 double aMaxSquaredWeight )
const
1387 std::vector<PATH_CONNECTION> result;
1391 double halfWidth1 = this->
GetWidth() / 2;
1395 double halfWidth2 = aS2.
GetWidth() / 2;
1400 std::vector<PATH_CONNECTION> pcs;
1401 pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1403 if( pcs.size() < 1 )
1409 if( pcs.size() > 0 )
1411 circlePoint = pcs[0].a1;
1414 if( testAngle < aS2.
GetEndAngle() && pcs.size() > 0 )
1416 result.push_back( pcs[0] );
1425 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
1429 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1435 std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1439 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1448 std::vector<PATH_CONNECTION> pcs3 = csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1452 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1459 std::vector<PATH_CONNECTION> pcs4 = csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1463 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1471 result.push_back( *bestPath );
1491 t = std::max( 0.0, std::min( 1.0, t ) );
1493 return A + ( AB * t );
1499 double aMaxSquaredWeight )
const
1501 std::vector<PATH_CONNECTION> result;
1505 double halfWidth1 = this->
GetWidth() / 2;
1510 double halfWidth2 = aS2.
GetWidth() / 2;
1518 double dist1 = ( P1 -
C ).SquaredEuclideanNorm();
1519 double dist2 = ( P2 -
D ).SquaredEuclideanNorm();
1520 double dist3 = ( P3 -
A ).SquaredEuclideanNorm();
1521 double dist4 = ( P4 -
B ).SquaredEuclideanNorm();
1524 double min_dist = dist1;
1528 if( dist2 < min_dist )
1535 if( dist3 < min_dist )
1542 if( dist4 < min_dist )
1551 pc.
a1 = closest1 + ( closest2 - closest1 ).Resize( halfWidth1 );
1552 pc.
a2 = closest2 + ( closest1 - closest2 ).Resize( halfWidth2 );
1553 pc.
weight = sqrt( min_dist ) - halfWidth1 - halfWidth2;
1555 if( pc.
weight <= aMaxWeight )
1557 result.push_back( pc );
1564 double aMaxSquaredWeight )
const
1566 std::vector<PATH_CONNECTION> result;
1572 double dist = ( center1 - center2 ).EuclideanNorm();
1574 if( dist > aMaxWeight || dist == 0 )
1579 double weight = sqrt( dist * dist - R2 * R2 ) - R1;
1580 double theta = asin( R2 / dist );
1581 double psi = acos( R2 / dist );
1583 if( weight > aMaxWeight )
1596 pStart =
VECTOR2I( R1 * cos( theta + circleAngle ), R1 * sin( theta + circleAngle ) );
1598 pEnd =
VECTOR2I( -R2 * cos( psi - circleAngle ), R2 * sin( psi - circleAngle ) );
1604 result.push_back( pc );
1606 pStart =
VECTOR2I( R1 * cos( -theta + circleAngle ), R1 * sin( -theta + circleAngle ) );
1608 pEnd =
VECTOR2I( -R2 * cos( -psi - circleAngle ), R2 * sin( -psi - circleAngle ) );
1614 result.push_back( pc );
1620 double aMaxSquaredWeight )
const
1622 std::vector<PATH_CONNECTION> result;
1638 if( ( point - arcCenter ).SquaredEuclideanNorm() > radius * radius )
1641 return circle.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1646 pc.
weight = ( radius - width / 2 ) - ( point - arcCenter ).EuclideanNorm();
1647 pc.
a1 = ( point - arcCenter ).Resize( radius - width / 2 ) + arcCenter;
1651 result.push_back( pc );
1660 if( ( point - this->
GetStartPoint() ).SquaredEuclideanNorm()
1661 > ( point - this->
GetEndPoint() ).SquaredEuclideanNorm() )
1667 return circle.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1674 double aMaxSquaredWeight )
const
1676 std::vector<PATH_CONNECTION> result;
1685 bestPath.
weight = std::numeric_limits<double>::infinity();
1694 std::vector<PATH_CONNECTION> pcs0 = csc1.
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1696 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1697 std::vector<PATH_CONNECTION> pcs2 = csc1.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1699 std::vector<PATH_CONNECTION> pcs3 = this->
Paths( csc5, aMaxWeight, aMaxSquaredWeight );
1700 std::vector<PATH_CONNECTION> pcs4 = this->
Paths( csc6, aMaxWeight, aMaxSquaredWeight );
1702 std::vector<PATH_CONNECTION> pcs5 = csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1703 std::vector<PATH_CONNECTION> pcs6 = csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1705 for( std::vector<PATH_CONNECTION> pcs : { pcs0, pcs1, pcs2 } )
1713 && ( bestPath.
weight > pc.weight ) )
1720 for( std::vector<PATH_CONNECTION> pcs : { pcs3, pcs4, pcs5, pcs6 } )
1724 if( bestPath.
weight > pc.weight )
1731 if( bestPath.
weight != std::numeric_limits<double>::infinity() )
1733 result.push_back( bestPath );
1741 std::vector<VECTOR2I>* aIntersectPoints )
1743 SEG segment( p1, p2 );
1744 CIRCLE circle( center, radius );
1746 std::vector<VECTOR2I> intersectionPoints;
1751 std::visit( visitor, geom1 );
1753 if( aIntersectPoints )
1755 for(
VECTOR2I& point : intersectionPoints )
1757 aIntersectPoints->push_back( point );
1761 return intersectionPoints.size() > 0;
1765 const std::vector<BOARD_ITEM*>& aBe,
1766 const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
1767 int aMinGrooveWidth )
1769 std::vector<VECTOR2I> intersectionPoints;
1770 bool TestGrooveWidth = aMinGrooveWidth > 0;
1774 if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
1788 if( intersects && !TestGrooveWidth )
1799 bool intersects =
false;
1805 if( intersects && !TestGrooveWidth )
1813 std::vector<VECTOR2I> points;
1816 if( points.size() < 2 )
1818 VECTOR2I prevPoint = points.back();
1820 bool intersects =
false;
1822 for(
auto p : points )
1827 if( intersects && !TestGrooveWidth )
1841 if( intersects && !TestGrooveWidth )
1859 if( intersects && !TestGrooveWidth )
1870 if( intersectionPoints.size() <= 0 )
1873 if( intersectionPoints.size() % 2 != 0 )
1876 int minx = intersectionPoints[0].x;
1877 int maxx = intersectionPoints[0].x;
1878 int miny = intersectionPoints[0].y;
1879 int maxy = intersectionPoints[0].y;
1881 for(
VECTOR2I v : intersectionPoints )
1883 minx = v.x < minx ? v.x : minx;
1884 maxx = v.x > maxx ? v.x : maxx;
1885 miny = v.x < miny ? v.x : miny;
1886 maxy = v.x > maxy ? v.x : maxy;
1888 if( abs( maxx - minx ) > abs( maxy - miny ) )
1890 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1898 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1905 int GVSquared = aMinGrooveWidth * aMinGrooveWidth;
1907 for(
size_t i = 0; i < intersectionPoints.size(); i += 2 )
1909 if( intersectionPoints[i].SquaredDistance( intersectionPoints[i + 1] ) > GVSquared )
1918 std::vector<const BOARD_ITEM*> aDontTestAgainst )
1925 double maxWeight = aMaxWeight;
1926 double maxWeightSquared = maxWeight * maxWeight;
1927 std::vector<PATH_CONNECTION> result;
1946 if( cuarc1 && cuarc2 )
1947 return cuarc1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1948 if( cuarc1 && cucircle2 )
1949 return cuarc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1950 if( cuarc1 && cusegment2 )
1951 return cuarc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1952 if( cucircle1 && cuarc2 )
1953 return cucircle1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1954 if( cucircle1 && cucircle2 )
1955 return cucircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1956 if( cucircle1 && cusegment2 )
1957 return cucircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1958 if( cusegment1 && cuarc2 )
1959 return cusegment1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1960 if( cusegment1 && cucircle2 )
1961 return cusegment1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1962 if( cusegment1 && cusegment2 )
1963 return cusegment1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1968 if( cuarc1 && bearc2 )
1969 return cuarc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1970 if( cuarc1 && becircle2 )
1971 return cuarc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1972 if( cuarc1 && bepoint2 )
1973 return cuarc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1974 if( cucircle1 && bearc2 )
1975 return cucircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1976 if( cucircle1 && becircle2 )
1977 return cucircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1978 if( cucircle1 && bepoint2 )
1979 return cucircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1980 if( cusegment1 && bearc2 )
1981 return cusegment1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1982 if( cusegment1 && becircle2 )
1983 return cusegment1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1984 if( cusegment1 && bepoint2 )
1985 return cusegment1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1990 if( cuarc2 && bearc1 )
1991 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1992 if( cuarc2 && becircle1 )
1993 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1994 if( cuarc2 && bepoint1 )
1995 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1996 if( cucircle2 && bearc1 )
1997 return bearc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1998 if( cucircle2 && becircle1 )
1999 return becircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
2000 if( cucircle2 && bepoint1 )
2001 return bepoint1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
2002 if( cusegment2 && bearc1 )
2003 return bearc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2004 if( cusegment2 && becircle1 )
2005 return becircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2006 if( cusegment2 && bepoint1 )
2007 return bepoint1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2012 if( bearc1 && bearc2 )
2013 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2014 if( bearc1 && becircle2 )
2015 return bearc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2016 if( bearc1 && bepoint2 )
2017 return bearc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2018 if( becircle1 && bearc2 )
2019 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2020 if( becircle1 && becircle2 )
2021 return becircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2022 if( becircle1 && bepoint2 )
2023 return becircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2024 if( bepoint1 && bearc2 )
2025 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2026 if( bepoint1 && becircle2 )
2027 return bepoint1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2028 if( bepoint1 && bepoint2 )
2029 return bepoint1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2035 std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
2036 std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult )
2038 if( !aFrom || !aTo )
2045 std::unordered_map<GRAPH_NODE*, double> distances;
2046 std::unordered_map<GRAPH_NODE*, GRAPH_NODE*> previous;
2050 if( distances[
left] == distances[
right] )
2052 return distances[
left] > distances[
right];
2054 std::priority_queue<GRAPH_NODE*, std::vector<GRAPH_NODE*>,
decltype( cmp )> pq( cmp );
2057 for( std::shared_ptr<GRAPH_NODE> node :
m_nodes )
2059 if( node !=
nullptr )
2060 distances[node.get()] = std::numeric_limits<double>::infinity();
2062 distances[aFrom.get()] = 0.0;
2063 distances[aTo.get()] = std::numeric_limits<double>::infinity();
2064 pq.push( aFrom.get() );
2067 while( !pq.empty() )
2072 if( current == aTo.get() )
2078 for( std::shared_ptr<GRAPH_CONNECTION> connection : current->
m_node_conns )
2080 GRAPH_NODE* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
2081 : ( connection->n1 ).get();
2086 double alt = distances[current]
2087 + connection->m_path.weight;
2089 if( alt < distances[neighbor] )
2091 distances[neighbor] = alt;
2092 previous[neighbor] = current;
2093 pq.push( neighbor );
2098 double pathWeight = distances[aTo.get()];
2101 if( pathWeight == std::numeric_limits<double>::infinity() )
2103 return std::numeric_limits<double>::infinity();
2109 while( step != aFrom.get() )
2113 for( std::shared_ptr<GRAPH_CONNECTION> node_conn : step->
m_node_conns )
2115 if( ( ( node_conn->n1 ).get() == prevNode && ( node_conn->n2 ).get() == step )
2116 || ( ( node_conn->n1 ).get() == step && ( node_conn->n2 ).get() == prevNode ) )
2118 aResult.push_back( node_conn );
2136 switch( aShape.
Type() )
2150 newshape =
dynamic_cast<CREEP_SHAPE*
>( cucircle );
2159 EDA_SHAPE edaArc( SHAPE_T::ARC, 0, FILL_T::NO_FILL );
2164 start = arc.
GetP0();
2170 start = arc.
GetP1();
2184 int nbShapes =
static_cast<const SHAPE_COMPOUND*
>( &aShape )->Shapes().size();
2190 if( !( ( subshape->Type() ==
SH_RECT ) && ( nbShapes == 5 ) ) )
2191 Addshape( *subshape, aConnectTo, aParent );
2202 const SEG object = *it;
2204 Addshape( segment, aConnectTo, aParent );
2214 for(
auto point : lineChain.
CPoints() )
2218 Addshape( segment, aConnectTo, aParent );
2243 std::shared_ptr<GRAPH_NODE> gnShape =
nullptr;
2247 switch( aShape.
Type() )
2258 gnShape->m_net = aConnectTo->m_net;
2259 std::shared_ptr<GRAPH_CONNECTION> gc =
AddConnection( gnShape, aConnectTo );
2262 gc->m_path.m_show =
false;
2273 std::vector<std::shared_ptr<GRAPH_NODE>> nodes;
2274 std::mutex nodes_lock;
2277 std::copy_if(
m_nodes.begin(),
m_nodes.end(), std::back_inserter( nodes ),
2278 [&]( std::shared_ptr<GRAPH_NODE> gn )
2280 return !!gn && gn->m_parent && gn->m_connectDirectly
2281 && ( gn->m_type != GRAPH_NODE::TYPE::VIRTUAL );
2284 auto processNodes = [&](
size_t i,
size_t j ) ->
bool
2286 for(
size_t ii = i; ii < j; ii++ )
2288 std::shared_ptr<GRAPH_NODE> gn1 = nodes[ii];
2290 for(
size_t jj = ii + 1; jj < nodes.size(); jj++ )
2292 std::shared_ptr<GRAPH_NODE> gn2 = nodes[jj];
2294 if( gn1->m_parent->GetParent() == gn2->m_parent->GetParent() )
2297 if( ( gn1->m_net == gn2->m_net ) && ( gn1->m_parent->IsConductive() )
2298 && ( gn2->m_parent->IsConductive() ) )
2303 std::vector<const BOARD_ITEM*> IgnoreForTest;
2304 IgnoreForTest.push_back( gn1->m_parent->GetParent() );
2305 IgnoreForTest.push_back( gn2->m_parent->GetParent() );
2311 std::shared_ptr<GRAPH_NODE>* connect1 = &gn1;
2312 std::shared_ptr<GRAPH_NODE>* connect2 = &gn2;
2313 std::shared_ptr<GRAPH_NODE> gnt1 =
nullptr;
2314 std::shared_ptr<GRAPH_NODE> gnt2 =
nullptr;
2315 std::lock_guard<std::mutex> lock( nodes_lock );
2317 if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2320 gnt1->m_connectDirectly =
false;
2322 if( gn1->m_parent->IsConductive() )
2324 std::shared_ptr<GRAPH_CONNECTION> gc =
AddConnection( gn1, gnt1 );
2327 gc->m_path.m_show =
false;
2332 if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2335 gnt2->m_connectDirectly =
false;
2337 if( gn2->m_parent->IsConductive() )
2339 std::shared_ptr<GRAPH_CONNECTION> gc =
AddConnection( gn2, gnt2 );
2342 gc->m_path.m_show =
false;
2358 processNodes( 0, nodes.size() );
2361 auto ret =
tp.parallelize_loop( nodes.size(), processNodes );
2363 for(
size_t ii = 0; ii < ret.size(); ii++ )
2365 std::future<bool>& r = ret[ii];
2369 std::future_status status = r.wait_for( std::chrono::seconds( 0 ) );
2371 while( status != std::future_status::ready )
2373 status = r.wait_for( std::chrono::milliseconds( 100 ) );
2382 std::vector<std::shared_ptr<GRAPH_CONNECTION>> toRemove;
2385 for( std::shared_ptr<GRAPH_CONNECTION>& gc :
m_connections )
2387 if( gc && ( gc->m_path.weight > aWeightLimit ) )
2389 toRemove.push_back( gc );
2394 for(
const std::shared_ptr<GRAPH_CONNECTION>& gc : toRemove )
2405 for( std::shared_ptr<GRAPH_NODE> gn : { aGc->n1, aGc->n2 } )
2409 gn->m_node_conns.erase( aGc );
2411 if( gn->m_node_conns.empty() && aDelete )
2414 [&gn](
const std::shared_ptr<GRAPH_NODE> node )
2416 return node.get() == gn.get();
2439 std::shared_ptr<GRAPH_NODE> gn =
FindNode( aType, parent, pos );
2443 gn = std::make_shared<GRAPH_NODE>( aType, parent, pos );
2452 std::shared_ptr<GRAPH_NODE> gn =
2453 std::make_shared<GRAPH_NODE>( GRAPH_NODE::TYPE::VIRTUAL,
nullptr );
2461 std::shared_ptr<GRAPH_NODE>& aN2,
2467 wxASSERT_MSG( ( aN1 != aN2 ),
"Creepage: a connection connects a node to itself" );
2469 std::shared_ptr<GRAPH_CONNECTION> gc = std::make_shared<GRAPH_CONNECTION>( aN1, aN2, aPc );
2471 aN1->m_node_conns.insert( gc );
2472 aN2->m_node_conns.insert( gc );
2478 std::shared_ptr<GRAPH_NODE>& aN2 )
2494 auto it =
m_nodeset.find( std::make_shared<GRAPH_NODE>( aType, aParent, aPos ) );
2507 virtualNode->m_net = aNetCode;
2511 for(
PAD*
pad : footprint->Pads() )
2513 if(
pad->GetNetCode() != aNetCode )
2516 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( aLayer );
2530 if( track->GetNetCode() != aNetCode )
2533 if( !track->IsOnLayer( aLayer ) )
2536 if( track->GetEffectiveShape() ==
nullptr )
2539 Addshape( *( track->GetEffectiveShape() ), virtualNode, track );
2548 if( zone->GetNetCode() != aNetCode )
2551 if( zone->GetEffectiveShape( aLayer ) ==
nullptr )
2554 Addshape( *( zone->GetEffectiveShape( aLayer ) ), virtualNode, zone );
2564 if( !drawing->IsConnected() )
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
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
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.
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.
const ZONES & Zones() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
const DRAWINGS & Drawings() const
Represent basic circle geometry with utility geometry functions.
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)
void RemoveConnection(std::shared_ptr< GRAPH_CONNECTION >, bool aDelete=false)
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
std::shared_ptr< GRAPH_NODE > AddNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent=nullptr, VECTOR2I aPos=VECTOR2I())
void TransformEdgeToCreepShapes()
std::shared_ptr< GRAPH_NODE > AddNodeVirtual()
void TransformCreepShapesToNodes(std::vector< CREEP_SHAPE * > &aShapes)
void Trim(double aWeightLimit)
SHAPE_POLY_SET * m_boardOutline
std::shared_ptr< GRAPH_NODE > FindNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, VECTOR2I aPos)
void RemoveDuplicatedShapes()
void GeneratePaths(double aMaxWeight, PCB_LAYER_ID aLayer, bool aClearance)
std::vector< BOARD_ITEM * > m_boardEdge
double m_creepageTargetSquared
std::unordered_set< std::shared_ptr< GRAPH_NODE >, GraphNodeHash, GraphNodeEqual > m_nodeset
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)
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
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
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
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
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)
void DupPolyPointsList(std::vector< VECTOR2I > &aBuffer) const
Duplicate the list of corners in a std::vector<VECTOR2I>.
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.
void SetWidth(int aWidth)
VECTOR2I GetArcMid() const
std::vector< PCB_SHAPE > GetShapes()
std::shared_ptr< GRAPH_NODE > n2
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.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
SHAPE_TYPE Type() const
Return the type of the shape.
const VECTOR2I GetCenter() const
const std::vector< SHAPE * > & Shapes() const
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
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.
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)
bool segmentIntersectsArc(const VECTOR2I &p1, const VECTOR2I &p2, const VECTOR2I ¢er, double radius, EDA_ANGLE startAngle, EDA_ANGLE endAngle, std::vector< VECTOR2I > *aIntersectPoints)
std::vector< PATH_CONNECTION > GetPaths(CREEP_SHAPE *aS1, CREEP_SHAPE *aS2, double aMaxWeight)
bool compareShapes(const CREEP_SHAPE *a, const CREEP_SHAPE *b)
bool CheckPathValidity(VECTOR2I aP1, VECTOR2I aP2, std::vector< BOARD_ITEM * > aBe, std::vector< const BOARD_ITEM * > aDontTestAgainst)
bool segmentIntersectsCircle(VECTOR2I p1, VECTOR2I p2, VECTOR2I center, double radius, std::vector< VECTOR2I > *aIntersectPoints)
bool segments_intersect(VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2, std::vector< VECTOR2I > *aIntersectPoints)
bool areEquivalent(const CREEP_SHAPE *a, const CREEP_SHAPE *b)
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...
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D