30 std::vector<VECTOR2I>* aIntersectPoints );
36 std::vector<VECTOR2I>* aIntersectPoints )
38 if( p1 == p2 || p1 == q2 || q1 == p2 || q1 == q2 )
41 SEG segment1( p1, q1 );
42 SEG segment2( p2, q2 );
44 std::vector<VECTOR2I> intersectionPoints;
52 std::visit( visitor, geom1 );
54 if( aIntersectPoints )
56 for(
VECTOR2I& point : intersectionPoints )
57 aIntersectPoints->push_back( point );
61 return intersectionPoints.size() > 0;
77 if( a->
GetType() == CREEP_SHAPE::TYPE::UNDEFINED )
87 if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
100 if( ( !a && b ) || ( a && !b ) )
108 if( a->
GetType() == CREEP_SHAPE::TYPE::POINT )
112 if( a->
GetType() == CREEP_SHAPE::TYPE::CIRCLE )
121 double aMaxSquaredWeight )
const
123 std::vector<PATH_CONNECTION> result;
125 double weight = ( this->
GetPos() - aS2.
GetPos() ).SquaredEuclideanNorm();
127 if( weight > aMaxSquaredWeight )
133 pc.
weight = sqrt( weight );
135 result.push_back( pc );
140 double aMaxSquaredWeight )
const
142 std::vector<PATH_CONNECTION> result;
152 double pointToCenterDistanceSquared = ( pointPos - circleCenter ).SquaredEuclideanNorm();
153 double weightSquared = pointToCenterDistanceSquared - (float)
radius * (
float)
radius;
155 if( weightSquared > aMaxSquaredWeight )
160 direction1 = direction1.
Resize( 1 );
164 double radiusSquared = double(
radius ) * double(
radius );
166 double distance = sqrt( pointToCenterDistanceSquared );
167 double value1 = radiusSquared /
distance;
168 double value2 = sqrt( radiusSquared - value1 * value1 );
174 pc.
weight = sqrt( weightSquared );
176 resultPoint = direction1 * value1 + direction2 * value2 + circleCenter;
177 pc.
a2.
x = int( resultPoint.
x );
178 pc.
a2.
y = int( resultPoint.
y );
179 result.push_back( pc );
181 resultPoint = direction1 * value1 - direction2 * value2 + circleCenter;
182 pc.
a2.
x = int( resultPoint.
x );
183 pc.
a2.
y = int( resultPoint.
y );
184 result.push_back( pc );
192 std::pair<bool, bool> result;
200 result.first =
false;
201 result.second =
false;
209 double pointAngle = testAngle.
AsRadians();
212 bool connectToEndPoint;
214 connectToEndPoint = ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y >= R );
217 connectToEndPoint &= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R );
219 connectToEndPoint |= ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y <= R )
220 && ( pointAngle >= endAngle || pointAngle <= startAngle );
223 result.first = !connectToEndPoint;
225 connectToEndPoint = ( cos( endAngle ) * newPoint.
x + sin( endAngle ) * newPoint.
y >= R );
229 ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R );
231 connectToEndPoint |= ( cos( startAngle ) * newPoint.
x + sin( startAngle ) * newPoint.
y <= R )
232 && ( pointAngle >= endAngle || pointAngle <= startAngle );
235 result.second = !connectToEndPoint;
240 double aMaxSquaredWeight )
const
242 std::vector<PATH_CONNECTION> result;
248 std::pair<bool, bool> behavesLikeCircle;
251 if( behavesLikeCircle.first && behavesLikeCircle.second )
254 return this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
257 if( behavesLikeCircle.first )
260 std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
262 if( paths.size() > 1 )
263 result.push_back( paths[1] );
270 result.push_back( pc );
272 if( behavesLikeCircle.second )
275 std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
277 if( paths.size() > 1 )
279 result.push_back( paths[0] );
287 result.push_back( pc );
293 double aMaxSquaredWeight )
const
295 std::vector<PATH_CONNECTION> result;
303 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
305 if( centerDistance + arcRadius < circleRadius )
321 result.push_back( pc );
324 if( result.size() == 4 )
335 arcEndAngle,
nullptr ) )
337 result.push_back( pc );
348 double aMaxSquaredWeight )
const
350 std::vector<PATH_CONNECTION> result;
356 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
358 if( centerDistance + arcRadius < circleRadius )
370 aMaxWeight, aMaxSquaredWeight ) )
375 result.push_back( pc );
379 .
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) )
384 result.push_back( pc );
392 double aMaxSquaredWeight )
const
394 std::vector<PATH_CONNECTION> result;
399 VECTOR2D distSquared(
double( ( p2 - p1 ).x ),
double( ( p2 - p1 ).y ) );
405 double Rdiff = abs( R1 - R2 );
406 double Rsum = R1 + R2;
409 double weightSquared1 = weightSquared - Rdiff * Rdiff;
411 double weightSquared2 = weightSquared - Rsum * Rsum;
413 if( weightSquared1 <= aMaxSquaredWeight )
416 direction1 = direction1.
Resize( 1 );
419 double D = sqrt( weightSquared );
420 double ratio1 = ( R1 - R2 ) /
D;
421 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
425 pc.
weight = sqrt( weightSquared1 );
427 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
428 pc.
a2 = p2 + direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
430 result.push_back( pc );
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 if( weightSquared2 <= aMaxSquaredWeight )
440 direction1 = direction1.
Resize( 1 );
443 double D = sqrt( weightSquared );
444 double ratio1 = ( R1 + R2 ) /
D;
445 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
449 pc.
weight = sqrt( weightSquared2 );
451 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
452 pc.
a2 = p2 - direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
454 result.push_back( pc );
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 );
473 switch( p1->GetType() )
475 case CREEP_SHAPE::TYPE::POINT:
AddNode( GRAPH_NODE::TYPE::POINT, p1, p1->GetPos() );
break;
476 case CREEP_SHAPE::TYPE::CIRCLE:
AddNode( GRAPH_NODE::TYPE::CIRCLE, p1, p1->GetPos() );
break;
477 case CREEP_SHAPE::TYPE::ARC:
AddNode( GRAPH_NODE::TYPE::ARC, p1, p1->GetPos() );
break;
487 std::vector<CREEP_SHAPE*> newVector;
524 case SHAPE_T::SEGMENT:
532 case SHAPE_T::RECTANGLE:
546 std::vector<VECTOR2I> points;
549 for(
auto p : points )
556 case SHAPE_T::CIRCLE:
567 double tolerance = 10;
590 std::vector<PCB_SHAPE> shapes = std::vector<PCB_SHAPE>();
599 if(
n1->m_type == GRAPH_NODE::TYPE::VIRTUAL ||
n2->m_type == GRAPH_NODE::TYPE::VIRTUAL )
605 && (
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::CIRCLE ) )
612 if( R1.
Cross( R2 ) > 0 )
628 shapes.push_back( s );
633 &&
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::ARC )
647 shapes.push_back( s );
657 if( R1.
Cross( R2 ) > 0 )
686 shapes.push_back( s );
695 shapes.push_back( s );
713 double aNormalWeight )
const
728 EDA_ANGLE maxAngle = angle1 > angle2 ? angle1 : angle2;
731 skipAngle += skipAngle;
732 EDA_ANGLE pointAngle = maxAngle - skipAngle;
743 pc.
a1 = maxAngle == angle2 ? a1->m_pos : a2->m_pos;
749 pc.
a2 = maxAngle == angle2 ? a2->m_pos : a1->m_pos;
752 std::shared_ptr<GRAPH_CONNECTION> gc = aG.
AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
755 gc->m_forceStraightLine =
true;
767 VECTOR2D distI( a1->m_pos - a2->m_pos );
768 VECTOR2D distD(
double( distI.
x ),
double( distI.
y ) );
780 pc.
weight = std::max( weight, 0.0 );
801 double weight = abs(
m_radius * ( angle2 - angle1 ).AsRadians() );
829 std::vector<VECTOR2I>* aIntersectPoints )
831 SEG segment( p1, p2 );
838 std::vector<VECTOR2I> intersectionPoints;
843 std::visit( visitor, geom1 );
845 if( aIntersectPoints )
847 for(
VECTOR2I& point : intersectionPoints )
848 aIntersectPoints->push_back( point );
851 return intersectionPoints.size() > 0;
855 double aMaxSquaredWeight )
const
857 std::vector<PATH_CONNECTION> result;
860 double halfWidth = this->
GetWidth() / 2;
864 double length = ( start -
end ).EuclideanNorm();
865 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - start.
x )
866 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - start.
y );
870 if( projectedPos <= 0 )
872 newPoint = start + ( pointPos - start ).Resize( halfWidth );
874 else if( projectedPos >= length )
876 newPoint =
end + ( pointPos -
end ).Resize( halfWidth );
880 double posOnSegment = ( start - pointPos ).SquaredEuclideanNorm()
881 - (
end - pointPos ).SquaredEuclideanNorm();
882 posOnSegment = posOnSegment / ( 2 * length ) + length / 2;
884 newPoint = start + (
end - start ).Resize( posOnSegment );
885 newPoint += ( pointPos - newPoint ).Resize( halfWidth );
888 double weightSquared = ( pointPos - newPoint ).SquaredEuclideanNorm();
890 if( weightSquared > aMaxSquaredWeight )
896 pc.
weight = sqrt( weightSquared );
898 result.push_back( pc );
904 double aMaxSquaredWeight )
const
906 std::vector<PATH_CONNECTION> result;
909 double halfWidth = this->
GetWidth() / 2;
913 double length = ( start -
end ).EuclideanNorm();
916 double weightSquared = std::numeric_limits<double>::infinity();
917 VECTOR2I PointOnTrack, PointOnCircle;
921 double projectedPos1 = cos( trackAngle.
AsRadians() ) * ( circleCenter.
x - start.
x )
922 + sin( trackAngle.
AsRadians() ) * ( circleCenter.
y - start.
y );
923 double projectedPos2 = projectedPos1 + circleRadius;
924 projectedPos1 = projectedPos1 - circleRadius;
926 double trackSide = (
end - start ).Cross( circleCenter - start ) > 0 ? 1 : -1;
928 if( ( projectedPos1 < 0 && projectedPos2 < 0 ) )
933 result.push_back( pc );
936 else if( ( projectedPos1 > length && projectedPos2 > length ) )
941 result.push_back( pc );
944 else if( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) && ( projectedPos2 >= 0 )
945 && ( projectedPos2 <= length ) )
948 PointOnTrack = start;
949 PointOnTrack += (
end - start ).Resize( projectedPos1 );
950 PointOnTrack += (
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
951 PointOnCircle = circleCenter - (
end - start ).Resize( circleRadius );
952 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
954 if( weightSquared < aMaxSquaredWeight )
957 pc.
a1 = PointOnTrack;
958 pc.
a2 = PointOnCircle;
959 pc.
weight = sqrt( weightSquared );
961 result.push_back( pc );
963 PointOnTrack = start;
964 PointOnTrack += (
end - start ).Resize( projectedPos2 );
965 PointOnTrack += (
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
966 PointOnCircle = circleCenter + (
end - start ).Resize( circleRadius );
969 pc.
a1 = PointOnTrack;
970 pc.
a2 = PointOnCircle;
972 result.push_back( pc );
975 else if( ( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) )
976 && ( ( projectedPos2 > length ) || projectedPos2 < 0 ) )
979 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
984 result.push_back( pcs.at( trackSide == 1 ? 1 : 0 ) );
987 PointOnTrack = start;
988 PointOnTrack += (
end - start ).Resize( projectedPos1 );
989 PointOnTrack += (
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
990 PointOnCircle = circleCenter - (
end - start ).Resize( circleRadius );
991 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
993 if( weightSquared < aMaxSquaredWeight )
996 pc.
a1 = PointOnTrack;
997 pc.
a2 = PointOnCircle;
998 pc.
weight = sqrt( weightSquared );
1000 result.push_back( pc );
1003 else if( ( ( projectedPos2 >= 0 ) && ( projectedPos2 <= length ) )
1004 && ( ( projectedPos1 > length ) || projectedPos1 < 0 ) )
1007 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1009 if( pcs.size() < 2 )
1012 result.push_back( pcs.at( trackSide == 1 ? 0 : 1 ) );
1014 PointOnTrack = start;
1015 PointOnTrack += (
end - start ).Resize( projectedPos2 );
1016 PointOnTrack += (
end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1017 PointOnCircle = circleCenter + (
end - start ).Resize( circleRadius );
1018 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
1020 if( weightSquared < aMaxSquaredWeight )
1023 pc.
a1 = PointOnTrack;
1024 pc.
a2 = PointOnCircle;
1025 pc.
weight = sqrt( weightSquared );
1027 result.push_back( pc );
1036 double aMaxSquaredWeight )
const
1038 std::vector<PATH_CONNECTION> result;
1047 result.push_back( pc );
1050 if( result.size() < 2 )
1063 beArcEndAngle,
nullptr ) )
1065 result.push_back( pc );
1072 beArcEndAngle,
nullptr ) )
1074 result.push_back( pc );
1084 double aMaxSquaredWeight )
const
1086 std::vector<PATH_CONNECTION> result;
1099 result.push_back( pc );
1102 if( result.size() < 2 )
1110 beArcEndAngle,
nullptr ) )
1112 result.push_back( pc );
1119 beArcEndAngle,
nullptr ) )
1121 result.push_back( pc );
1129 double aMaxSquaredWeight )
const
1131 std::vector<PATH_CONNECTION> result;
1140 result.push_back( pc );
1143 if( result.size() < 2 )
1149 result.push_back( pc );
1152 result.push_back( pc );
1160 double aMaxSquaredWeight )
const
1162 std::vector<PATH_CONNECTION> result;
1175 result.push_back( pc );
1178 if( result.size() < 2 )
1186 beArcEndAngle,
nullptr ) )
1188 result.push_back( pc );
1195 beArcEndAngle,
nullptr ) )
1197 result.push_back( pc );
1207 double aMaxSquaredWeight )
const
1209 std::vector<PATH_CONNECTION> result;
1214 double weight = (
center - point ).EuclideanNorm() - R;
1216 if( weight > aMaxWeight )
1220 pc.
weight = std::max( weight, 0.0 );
1224 result.push_back( pc );
1230 double aMaxSquaredWeight )
const
1232 std::vector<PATH_CONNECTION> result;
1239 if( ( C1 - C2 ).SquaredEuclideanNorm() < ( R1 - R2 ) * ( R1 - R2 ) )
1245 double weight = ( C1 - C2 ).EuclideanNorm() - R1 - R2;
1247 if( weight > aMaxWeight || weight < 0 )
1251 pc.
weight = std::max( weight, 0.0 );
1252 pc.
a1 = ( C2 - C1 ).Resize( R1 ) + C1;
1253 pc.
a2 = ( C1 - C2 ).Resize( R2 ) + C2;
1254 result.push_back( pc );
1260 double aMaxSquaredWeight )
const
1262 std::vector<PATH_CONNECTION> result;
1266 double halfWidth = this->
GetWidth() / 2;
1268 EDA_ANGLE trackAngle( s_end - s_start );
1271 double length = ( s_start - s_end ).EuclideanNorm();
1272 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - s_start.
x )
1273 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - s_start.
y );
1275 if( ( projectedPos <= 0 ) || ( s_start == s_end ) )
1278 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1281 if( projectedPos >= length )
1284 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1288 double trackSide = ( s_end - s_start ).Cross( pointPos - s_start ) > 0 ? 1 : -1;
1291 pc.
a1 = s_start + ( s_end - s_start ).Resize( projectedPos )
1292 + ( s_end - s_start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1293 pc.
a2 = ( pc.
a1 - pointPos ).Resize(
radius ) + pointPos;
1294 pc.
weight = ( pc.
a2 - pc.
a1 ).SquaredEuclideanNorm();
1296 if( pc.
weight <= aMaxSquaredWeight )
1299 result.push_back( pc );
1307 double aMaxSquaredWeight )
const
1309 std::vector<PATH_CONNECTION> result;
1314 double circleRadius = this->
GetRadius();
1322 if( ( circlePos - arcPos ).EuclideanNorm() > arcRadius + circleRadius )
1324 const std::vector<PATH_CONNECTION>& pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1326 if( pcs.size() == 1 )
1332 result.push_back( pcs[0] );
1344 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
1345 std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1349 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1355 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1363 if( ( circlePos - arcPos ).SquaredEuclideanNorm() < arcRadius * arcRadius )
1365 if( circlePos != arcPos )
1371 pc3.
weight = std::max( arcRadius - ( circlePos - arcPos ).EuclideanNorm() - circleRadius, 0.0 );
1372 pc3.
a1 = circlePos + ( circlePos - arcPos ).Resize( circleRadius );
1373 pc3.
a2 = arcPos + ( circlePos - arcPos ).Resize( arcRadius - aS2.
GetWidth() / 2 );
1381 if( bestPath && bestPath->
weight > 0 )
1383 result.push_back( *bestPath );
1391 double aMaxSquaredWeight )
const
1393 std::vector<PATH_CONNECTION> result;
1397 double halfWidth1 = this->
GetWidth() / 2;
1401 double halfWidth2 = aS2.
GetWidth() / 2;
1406 std::vector<PATH_CONNECTION> pcs;
1407 pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1409 if( pcs.size() < 1 )
1415 if( pcs.size() > 0 )
1417 circlePoint = pcs[0].a1;
1421 if( testAngle < aS2.
GetEndAngle() && pcs.size() > 0 )
1423 result.push_back( pcs[0] );
1433 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1439 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1448 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1455 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1460 result.push_back( *bestPath );
1479 t = std::max( 0.0, std::min( 1.0, t ) );
1481 return A + ( AB * t );
1487 double aMaxSquaredWeight )
const
1489 std::vector<PATH_CONNECTION> result;
1493 double halfWidth1 = this->
GetWidth() / 2;
1498 double halfWidth2 = aS2.
GetWidth() / 2;
1506 double dist1 = ( P1 -
C ).SquaredEuclideanNorm();
1507 double dist2 = ( P2 -
D ).SquaredEuclideanNorm();
1508 double dist3 = ( P3 -
A ).SquaredEuclideanNorm();
1509 double dist4 = ( P4 -
B ).SquaredEuclideanNorm();
1512 double min_dist = dist1;
1516 if( dist2 < min_dist )
1523 if( dist3 < min_dist )
1530 if( dist4 < min_dist )
1539 pc.
a1 = closest1 + ( closest2 - closest1 ).Resize( halfWidth1 );
1540 pc.
a2 = closest2 + ( closest1 - closest2 ).Resize( halfWidth2 );
1541 pc.
weight = std::max( sqrt( min_dist ) - halfWidth1 - halfWidth2, 0.0 );
1543 if( pc.
weight <= aMaxWeight )
1544 result.push_back( pc );
1551 double aMaxSquaredWeight )
const
1553 std::vector<PATH_CONNECTION> result;
1559 double dist = ( center1 - center2 ).EuclideanNorm();
1561 if( dist > aMaxWeight || dist == 0 )
1564 double weight = sqrt( dist * dist - R2 * R2 ) - R1;
1565 double theta = asin( R2 / dist );
1566 double psi = acos( R2 / dist );
1568 if( weight > aMaxWeight )
1572 pc.
weight = std::max( weight, 0.0 );
1579 pStart =
VECTOR2I( R1 * cos( theta + circleAngle ), R1 * sin( theta + circleAngle ) );
1581 pEnd =
VECTOR2I( -R2 * cos( psi - circleAngle ), R2 * sin( psi - circleAngle ) );
1586 result.push_back( pc );
1588 pStart =
VECTOR2I( R1 * cos( -theta + circleAngle ), R1 * sin( -theta + circleAngle ) );
1590 pEnd =
VECTOR2I( -R2 * cos( -psi - circleAngle ), R2 * sin( -psi - circleAngle ) );
1596 result.push_back( pc );
1602 double aMaxSquaredWeight )
const
1604 std::vector<PATH_CONNECTION> result;
1620 if( ( point - arcCenter ).SquaredEuclideanNorm() >
radius *
radius )
1623 return circle.Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1628 pc.
weight = std::max( (
radius - width / 2 ) - ( point - arcCenter ).EuclideanNorm(), 0.0 );
1629 pc.
a1 = ( point - arcCenter ).Resize(
radius - width / 2 ) + arcCenter;
1633 result.push_back( pc );
1642 if( ( point - this->
GetStartPoint() ).SquaredEuclideanNorm()
1643 > ( point - this->
GetEndPoint() ).SquaredEuclideanNorm() )
1653 return circle.Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1661 double aMaxSquaredWeight )
const
1663 std::vector<PATH_CONNECTION> result;
1672 bestPath.
weight = std::numeric_limits<double>::infinity();
1681 for(
const std::vector<PATH_CONNECTION>& pcs : { csc1.
Paths( csc2, aMaxWeight, aMaxSquaredWeight ),
1682 this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight ),
1683 csc1.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) } )
1695 for(
const std::vector<PATH_CONNECTION>& pcs : { this->
Paths( csc5, aMaxWeight, aMaxSquaredWeight ),
1696 this->
Paths( csc6, aMaxWeight, aMaxSquaredWeight ),
1697 csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ),
1698 csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) } )
1702 if( bestPath.
weight > pc.weight )
1707 if( bestPath.
weight != std::numeric_limits<double>::infinity() )
1708 result.push_back( bestPath );
1715 std::vector<VECTOR2I>* aIntersectPoints )
1717 SEG segment( p1, p2 );
1720 std::vector<VECTOR2I> intersectionPoints;
1725 std::visit( visitor, geom1 );
1727 if( aIntersectPoints )
1729 for(
VECTOR2I& point : intersectionPoints )
1730 aIntersectPoints->push_back( point );
1733 return intersectionPoints.size() > 0;
1737 const std::vector<BOARD_ITEM*>& aBe,
1738 const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
1739 int aMinGrooveWidth )
1741 std::vector<VECTOR2I> intersectionPoints;
1742 bool TestGrooveWidth = aMinGrooveWidth > 0;
1746 if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
1758 &intersectionPoints );
1760 if( intersects && !TestGrooveWidth )
1773 bool intersects =
false;
1779 if( intersects && !TestGrooveWidth )
1787 std::vector<VECTOR2I> points;
1790 if( points.size() < 2 )
1793 VECTOR2I prevPoint = points.back();
1795 bool intersects =
false;
1803 if( intersects && !TestGrooveWidth )
1816 if( intersects && !TestGrooveWidth )
1832 if( intersects && !TestGrooveWidth )
1843 if( intersectionPoints.size() <= 0 )
1846 if( intersectionPoints.size() % 2 != 0 )
1849 int minx = intersectionPoints[0].x;
1850 int maxx = intersectionPoints[0].x;
1851 int miny = intersectionPoints[0].y;
1852 int maxy = intersectionPoints[0].y;
1854 for(
const VECTOR2I& v : intersectionPoints )
1856 minx = v.x < minx ? v.x : minx;
1857 maxx = v.x > maxx ? v.x : maxx;
1858 miny = v.x < miny ? v.x : miny;
1859 maxy = v.x > maxy ? v.x : maxy;
1862 if( abs( maxx - minx ) > abs( maxy - miny ) )
1864 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1872 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1879 int GVSquared = aMinGrooveWidth * aMinGrooveWidth;
1881 for(
size_t i = 0; i < intersectionPoints.size(); i += 2 )
1883 if( intersectionPoints[i].SquaredDistance( intersectionPoints[i + 1] ) > GVSquared )
1893 double maxWeight = aMaxWeight;
1894 double maxWeightSquared = maxWeight * maxWeight;
1895 std::vector<PATH_CONNECTION> result;
1914 if( cuarc1 && cuarc2 )
1915 return cuarc1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1916 if( cuarc1 && cucircle2 )
1917 return cuarc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1918 if( cuarc1 && cusegment2 )
1919 return cuarc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1920 if( cucircle1 && cuarc2 )
1921 return cucircle1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1922 if( cucircle1 && cucircle2 )
1923 return cucircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1924 if( cucircle1 && cusegment2 )
1925 return cucircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1926 if( cusegment1 && cuarc2 )
1927 return cusegment1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1928 if( cusegment1 && cucircle2 )
1929 return cusegment1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1930 if( cusegment1 && cusegment2 )
1931 return cusegment1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1936 if( cuarc1 && bearc2 )
1937 return cuarc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1938 if( cuarc1 && becircle2 )
1939 return cuarc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1940 if( cuarc1 && bepoint2 )
1941 return cuarc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1942 if( cucircle1 && bearc2 )
1943 return cucircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1944 if( cucircle1 && becircle2 )
1945 return cucircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1946 if( cucircle1 && bepoint2 )
1947 return cucircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1948 if( cusegment1 && bearc2 )
1949 return cusegment1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1950 if( cusegment1 && becircle2 )
1951 return cusegment1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1952 if( cusegment1 && bepoint2 )
1953 return cusegment1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1958 if( cuarc2 && bearc1 )
1959 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1960 if( cuarc2 && becircle1 )
1961 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1962 if( cuarc2 && bepoint1 )
1963 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1964 if( cucircle2 && bearc1 )
1965 return bearc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1966 if( cucircle2 && becircle1 )
1967 return becircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1968 if( cucircle2 && bepoint1 )
1969 return bepoint1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1970 if( cusegment2 && bearc1 )
1971 return bearc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1972 if( cusegment2 && becircle1 )
1973 return becircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1974 if( cusegment2 && bepoint1 )
1975 return bepoint1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1980 if( bearc1 && bearc2 )
1981 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1982 if( bearc1 && becircle2 )
1983 return bearc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1984 if( bearc1 && bepoint2 )
1985 return bearc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1986 if( becircle1 && bearc2 )
1987 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1988 if( becircle1 && becircle2 )
1989 return becircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1990 if( becircle1 && bepoint2 )
1991 return becircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1992 if( bepoint1 && bearc2 )
1993 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1994 if( bepoint1 && becircle2 )
1995 return bepoint1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1996 if( bepoint1 && bepoint2 )
1997 return bepoint1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2003 std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult )
2005 if( !aFrom || !aTo )
2012 std::unordered_map<GRAPH_NODE*, double> distances;
2013 std::unordered_map<GRAPH_NODE*, GRAPH_NODE*> previous;
2017 double distLeft = distances[
left];
2018 double distRight = distances[
right];
2020 if( distLeft == distRight )
2022 return distLeft > distRight;
2024 std::priority_queue<GRAPH_NODE*, std::vector<GRAPH_NODE*>,
decltype( cmp )> pq( cmp );
2027 for(
const std::shared_ptr<GRAPH_NODE>& node :
m_nodes )
2029 if( node !=
nullptr )
2030 distances[node.get()] = std::numeric_limits<double>::infinity();
2033 distances[aFrom.get()] = 0.0;
2034 distances[aTo.get()] = std::numeric_limits<double>::infinity();
2035 pq.push( aFrom.get() );
2038 while( !pq.empty() )
2043 if( current == aTo.get() )
2049 for(
const std::shared_ptr<GRAPH_CONNECTION>& connection : current->
m_node_conns )
2051 GRAPH_NODE* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
2052 : ( connection->n1 ).get();
2058 if( connection->m_path.weight < 0.0 )
2060 wxLogTrace(
"CREEPAGE",
"Negative weight connection found. Ignoring connection." );
2065 double alt = distances[current] + connection->m_path.weight;
2067 if( alt < distances[neighbor] )
2069 distances[neighbor] = alt;
2070 previous[neighbor] = current;
2071 pq.push( neighbor );
2076 double pathWeight = distances[aTo.get()];
2079 if( pathWeight == std::numeric_limits<double>::infinity() )
2080 return std::numeric_limits<double>::infinity();
2085 while( step != aFrom.get() )
2089 for(
const std::shared_ptr<GRAPH_CONNECTION>& node_conn : step->
m_node_conns )
2091 if( ( ( node_conn->n1 ).get() == prevNode && ( node_conn->n2 ).get() == step )
2092 || ( ( node_conn->n1 ).get() == step && ( node_conn->n2 ).get() == prevNode ) )
2094 aResult.push_back( node_conn );
2112 switch( aShape.
Type() )
2126 newshape =
dynamic_cast<CREEP_SHAPE*
>( cucircle );
2135 EDA_SHAPE edaArc( SHAPE_T::ARC, 0, FILL_T::NO_FILL );
2140 start = arc.
GetP0();
2146 start = arc.
GetP1();
2160 int nbShapes =
static_cast<const SHAPE_COMPOUND*
>( &aShape )->Shapes().size();
2166 if( !( ( subshape->Type() ==
SH_RECT ) && ( nbShapes == 5 ) ) )
2167 Addshape( *subshape, aConnectTo, aParent );
2178 const SEG object = *it;
2180 Addshape( segment, aConnectTo, aParent );
2194 Addshape( segment, aConnectTo, aParent );
2220 std::shared_ptr<GRAPH_NODE> gnShape =
nullptr;
2224 switch( aShape.
Type() )
2235 gnShape->m_net = aConnectTo->m_net;
2236 std::shared_ptr<GRAPH_CONNECTION> gc =
AddConnection( gnShape, aConnectTo );
2239 gc->m_path.m_show =
false;
2250 std::vector<std::shared_ptr<GRAPH_NODE>> nodes;
2251 std::mutex nodes_lock;
2254 std::copy_if(
m_nodes.begin(),
m_nodes.end(), std::back_inserter( nodes ),
2255 [&](
const std::shared_ptr<GRAPH_NODE>& gn )
2257 return !!gn && gn->m_parent && gn->m_connectDirectly
2258 && ( gn->m_type != GRAPH_NODE::TYPE::VIRTUAL );
2261 std::sort( nodes.begin(), nodes.end(),
2262 [](
const std::shared_ptr<GRAPH_NODE>& gn1,
const std::shared_ptr<GRAPH_NODE>& gn2 )
2264 return ( gn1->m_parent < gn2->m_parent ) || ( gn1->m_parent == gn2->m_parent
2265 && gn1->m_net < gn2->m_net );
2269 std::unordered_map<const BOARD_ITEM*, std::unordered_map<int, std::vector<std::shared_ptr<GRAPH_NODE>>>> parent_net_groups;
2270 std::vector<const BOARD_ITEM*> parent_keys;
2272 for(
const auto& gn : nodes )
2276 if( parent_net_groups[parent].
empty() )
2277 parent_keys.push_back( parent );
2279 parent_net_groups[parent][gn->m_net].push_back( gn );
2284 std::shared_ptr<GRAPH_NODE> node1, node2;
2286 std::vector<WorkItem> work_items;
2288 for(
size_t i = 0; i < parent_keys.size(); ++i )
2290 for(
size_t j = i + 1; j < parent_keys.size(); ++j )
2292 const auto& group1_nets = parent_net_groups[parent_keys[i]];
2293 const auto& group2_nets = parent_net_groups[parent_keys[j]];
2295 for(
const auto& [net1, nodes1] : group1_nets )
2297 for(
const auto& [net2, nodes2] : group2_nets )
2302 bool all_conductive_1 = std::all_of( nodes1.begin(), nodes1.end(),
2303 [](
const auto& n ) { return n->m_parent->IsConductive(); } );
2304 bool all_conductive_2 = std::all_of( nodes2.begin(), nodes2.end(),
2305 [](
const auto& n ) { return n->m_parent->IsConductive(); } );
2307 if( all_conductive_1 && all_conductive_2 )
2312 for(
const auto& gn1 : nodes1 )
2313 for(
const auto& gn2 : nodes2 )
2314 work_items.push_back( { gn1, gn2 } );
2320 auto processWorkItems = [&](
size_t start_idx,
size_t end_idx ) ->
bool
2322 for(
size_t idx = start_idx; idx < end_idx; ++idx )
2324 auto [gn1, gn2] = work_items[idx];
2328 std::vector<const BOARD_ITEM*> IgnoreForTest = {
2329 gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
2336 std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
2337 std::lock_guard<std::mutex> lock( nodes_lock );
2340 if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2343 gnt1->m_connectDirectly =
false;
2346 if( gn1->m_parent->IsConductive() )
2349 gc->m_path.m_show =
false;
2354 if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2357 gnt2->m_connectDirectly =
false;
2360 if( gn2->m_parent->IsConductive() )
2363 gc->m_path.m_show =
false;
2375 if(
tp.get_tasks_total() >=
tp.get_thread_count() - 4 )
2377 processWorkItems( 0, work_items.size() );
2381 auto ret =
tp.parallelize_loop( work_items.size(), processWorkItems );
2383 for(
size_t ii = 0; ii < ret.size(); ii++ )
2385 std::future<bool>& r = ret[ii];
2390 while( r.wait_for( std::chrono::milliseconds( 100 ) ) != std::future_status::ready ){}
2398 std::vector<std::shared_ptr<GRAPH_CONNECTION>> toRemove;
2401 for( std::shared_ptr<GRAPH_CONNECTION>& gc :
m_connections )
2403 if( gc && ( gc->m_path.weight > aWeightLimit ) )
2404 toRemove.push_back( gc );
2408 for(
const std::shared_ptr<GRAPH_CONNECTION>& gc : toRemove )
2417 for( std::shared_ptr<GRAPH_NODE> gn : { aGc->n1, aGc->n2 } )
2421 gn->m_node_conns.erase( aGc );
2423 if( gn->m_node_conns.empty() && aDelete )
2426 [&gn](
const std::shared_ptr<GRAPH_NODE>& node )
2428 return node.get() == gn.get();
2451 std::shared_ptr<GRAPH_NODE> gn =
FindNode( aType, parent, pos );
2456 gn = std::make_shared<GRAPH_NODE>( aType, parent, pos );
2465 std::shared_ptr<GRAPH_NODE> gn = std::make_shared<GRAPH_NODE>( GRAPH_NODE::TYPE::VIRTUAL,
nullptr );
2473 std::shared_ptr<GRAPH_NODE>& aN2,
2479 wxASSERT_MSG( ( aN1 != aN2 ),
"Creepage: a connection connects a node to itself" );
2481 std::shared_ptr<GRAPH_CONNECTION> gc = std::make_shared<GRAPH_CONNECTION>( aN1, aN2, aPc );
2483 aN1->m_node_conns.insert( gc );
2484 aN2->m_node_conns.insert( gc );
2490 std::shared_ptr<GRAPH_NODE>& aN2 )
2506 auto it =
m_nodeset.find( std::make_shared<GRAPH_NODE>( aType, aParent, aPos ) );
2519 virtualNode->m_net = aNetCode;
2523 for(
PAD*
pad : footprint->Pads() )
2525 if(
pad->GetNetCode() != aNetCode )
2528 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( aLayer );
2542 if( track->GetNetCode() != aNetCode )
2545 if( !track->IsOnLayer( aLayer ) )
2548 if( track->GetEffectiveShape() ==
nullptr )
2551 Addshape( *( track->GetEffectiveShape() ), virtualNode, track );
2560 if( zone->GetNetCode() != aNetCode )
2563 if( zone->GetEffectiveShape( aLayer ) ==
nullptr )
2566 Addshape( *( zone->GetEffectiveShape( aLayer ) ), virtualNode, zone );
2576 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_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
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
EDA_ITEM * GetParent() const
EDA_ITEM * m_parent
Owner.
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.
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)
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 segments_intersect(VECTOR2I p1, VECTOR2I q1, VECTOR2I p2, VECTOR2I q2, std::vector< VECTOR2I > *aIntersectPoints)
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)
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D