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 )
264 result.push_back( paths[1] );
273 result.push_back( pc );
276 if( behavesLikeCircle.second )
279 std::vector<PATH_CONNECTION> paths = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
281 if( paths.size() > 1 )
283 result.push_back( paths[0] );
292 result.push_back( pc );
299 double aMaxSquaredWeight )
const
301 std::vector<PATH_CONNECTION> result;
309 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
311 if( centerDistance + arcRadius < circleRadius )
327 result.push_back( pc );
330 if( result.size() == 4 )
341 arcEndAngle,
nullptr ) )
342 result.push_back( pc );
352 double aMaxSquaredWeight )
const
354 std::vector<PATH_CONNECTION> result;
360 double centerDistance = ( circleCenter - arcCenter ).EuclideanNorm();
362 if( centerDistance + arcRadius < circleRadius )
374 aMaxWeight, aMaxSquaredWeight ) )
379 result.push_back( pc );
383 .
Paths( aS2, aMaxWeight, aMaxSquaredWeight ) )
388 result.push_back( pc );
396 double aMaxSquaredWeight )
const
398 std::vector<PATH_CONNECTION> result;
403 VECTOR2D distSquared(
double( ( p2 - p1 ).x ),
double( ( p2 - p1 ).y ) );
409 double Rdiff = abs( R1 - R2 );
410 double Rsum = R1 + R2;
413 double weightSquared1 = weightSquared - Rdiff * Rdiff;
415 double weightSquared2 = weightSquared - Rsum * Rsum;
417 if( weightSquared1 <= aMaxSquaredWeight )
420 direction1 = direction1.
Resize( 1 );
423 double D = sqrt( weightSquared );
424 double ratio1 = ( R1 - R2 ) /
D;
425 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
429 pc.
weight = sqrt( weightSquared1 );
431 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
432 pc.
a2 = p2 + direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
434 result.push_back( pc );
436 pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
437 pc.
a2 = p2 + direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
439 result.push_back( pc );
441 if( weightSquared2 <= aMaxSquaredWeight )
444 direction1 = direction1.
Resize( 1 );
447 double D = sqrt( weightSquared );
448 double ratio1 = ( R1 + R2 ) /
D;
449 double ratio2 = sqrt( 1 - ratio1 * ratio1 );
453 pc.
weight = sqrt( weightSquared2 );
455 pc.
a1 = p1 + direction1 * R1 * ratio1 + direction2 * R1 * ratio2;
456 pc.
a2 = p2 - direction1 * R2 * ratio1 - direction2 * R2 * ratio2;
458 result.push_back( pc );
460 pc.
a1 = p1 + direction1 * R1 * ratio1 - direction2 * R1 * ratio2;
461 pc.
a2 = p2 - direction1 * R2 * ratio1 + direction2 * R2 * ratio2;
463 result.push_back( pc );
477 switch( p1->GetType() )
479 case CREEP_SHAPE::TYPE::POINT:
AddNode( GraphNode::TYPE::POINT, p1, p1->GetPos() );
break;
480 case CREEP_SHAPE::TYPE::CIRCLE:
AddNode( GraphNode::TYPE::CIRCLE, p1, p1->GetPos() );
break;
481 case CREEP_SHAPE::TYPE::ARC:
AddNode( GraphNode::TYPE::ARC, p1, p1->GetPos() );
break;
491 std::vector<CREEP_SHAPE*> newVector;
528 case SHAPE_T::SEGMENT:
536 case SHAPE_T::RECTANGLE:
550 std::vector<VECTOR2I> points;
553 for(
auto p : points )
560 case SHAPE_T::CIRCLE:
571 double tolerance = 10;
594 std::vector<PCB_SHAPE> shapes = std::vector<PCB_SHAPE>();
603 if(
n1->m_type == GraphNode::TYPE::VIRTUAL ||
n2->m_type == GraphNode::TYPE::VIRTUAL )
609 && (
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::CIRCLE ) )
616 if( R1.
Cross( R2 ) > 0 )
632 shapes.push_back( s );
637 &&
n1->m_parent->GetType() == CREEP_SHAPE::TYPE::ARC )
651 shapes.push_back( s );
661 if( R1.
Cross( R2 ) > 0 )
690 shapes.push_back( s );
699 shapes.push_back( s );
717 double aNormalWeight )
const
732 EDA_ANGLE maxAngle = angle1 > angle2 ? angle1 : angle2;
735 skipAngle += skipAngle;
736 EDA_ANGLE pointAngle = maxAngle - skipAngle;
747 pc.
a1 = maxAngle == angle2 ? a1->m_pos : a2->m_pos;
753 pc.
a2 = maxAngle == angle2 ? a2->m_pos : a1->m_pos;
756 std::shared_ptr<GraphConnection> gc = aG.
AddConnection( gnt, maxAngle == angle2 ? a2 : a1, pc );
759 gc->forceStraightLigne =
true;
772 VECTOR2D distI( a1->m_pos - a2->m_pos );
773 VECTOR2D distD(
double( distI.
x ),
double( distI.
y ) );
809 double weight = abs(
m_radius * ( angle2 - angle1 ).AsRadians() );
839 std::vector<VECTOR2I>* aIntersectPoints )
841 SEG segment( p1, p2 );
844 radius * sin( startAngle.
AsRadians() ) );
845 startPoint += center;
846 SHAPE_ARC arc( center, startPoint, endAngle - startAngle );
848 std::vector<VECTOR2I> intersectionPoints;
853 std::visit( visitor, geom1 );
855 if( aIntersectPoints )
857 for(
VECTOR2I& point : intersectionPoints )
858 aIntersectPoints->push_back( point );
861 return intersectionPoints.size() > 0;
865 double aMaxSquaredWeight )
const
867 std::vector<PATH_CONNECTION> result;
870 double halfWidth = this->
GetWidth() / 2;
874 double length = ( start - end ).EuclideanNorm();
875 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - start.
x )
876 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - start.
y );
880 if( projectedPos <= 0 )
882 newPoint = start + ( pointPos - start ).Resize( halfWidth );
884 else if( projectedPos >= length )
886 newPoint = end + ( pointPos - end ).Resize( halfWidth );
890 double posOnSegment = ( start - pointPos ).SquaredEuclideanNorm()
891 - ( end - pointPos ).SquaredEuclideanNorm();
892 posOnSegment = posOnSegment / ( 2 * length ) + length / 2;
894 newPoint = start + ( end - start ).Resize( posOnSegment );
895 newPoint += ( pointPos - newPoint ).Resize( halfWidth );
898 double weightSquared = ( pointPos - newPoint ).SquaredEuclideanNorm();
900 if( weightSquared > aMaxSquaredWeight )
906 pc.
weight = sqrt( weightSquared );
908 result.push_back( pc );
914 double aMaxSquaredWeight )
const
916 std::vector<PATH_CONNECTION> result;
919 double halfWidth = this->
GetWidth() / 2;
923 double length = ( start - end ).EuclideanNorm();
926 double weightSquared = std::numeric_limits<double>::infinity();
927 VECTOR2I PointOnTrack, PointOnCircle;
931 double projectedPos1 = cos( trackAngle.
AsRadians() ) * ( circleCenter.
x - start.
x )
932 + sin( trackAngle.
AsRadians() ) * ( circleCenter.
y - start.
y );
933 double projectedPos2 = projectedPos1 + circleRadius;
934 projectedPos1 = projectedPos1 - circleRadius;
936 double trackSide = ( end - start ).Cross( circleCenter - start ) > 0 ? 1 : -1;
938 if( ( projectedPos1 < 0 && projectedPos2 < 0 ) )
943 result.push_back( pc );
946 else if( ( projectedPos1 > length && projectedPos2 > length ) )
951 result.push_back( pc );
955 else if( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) && ( projectedPos2 >= 0 )
956 && ( projectedPos2 <= length ) )
959 PointOnTrack = start;
960 PointOnTrack += ( end - start ).Resize( projectedPos1 );
961 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
962 PointOnCircle = circleCenter - ( end - start ).Resize( circleRadius );
963 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
965 if( weightSquared < aMaxSquaredWeight )
968 pc.
a1 = PointOnTrack;
969 pc.
a2 = PointOnCircle;
970 pc.
weight = sqrt( weightSquared );
972 result.push_back( pc );
974 PointOnTrack = start;
975 PointOnTrack += ( end - start ).Resize( projectedPos2 );
976 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
977 PointOnCircle = circleCenter + ( end - start ).Resize( circleRadius );
980 pc.
a1 = PointOnTrack;
981 pc.
a2 = PointOnCircle;
983 result.push_back( pc );
986 else if( ( ( projectedPos1 >= 0 ) && ( projectedPos1 <= length ) )
987 && ( ( projectedPos2 > length ) || projectedPos2 < 0 ) )
990 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
995 result.push_back( pcs.at( trackSide == 1 ? 1 : 0 ) );
998 PointOnTrack = start;
999 PointOnTrack += ( end - start ).Resize( projectedPos1 );
1000 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1001 PointOnCircle = circleCenter - ( end - start ).Resize( circleRadius );
1002 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
1004 if( weightSquared < aMaxSquaredWeight )
1007 pc.
a1 = PointOnTrack;
1008 pc.
a2 = PointOnCircle;
1009 pc.
weight = sqrt( weightSquared );
1011 result.push_back( pc );
1014 else if( ( ( projectedPos2 >= 0 ) && ( projectedPos2 <= length ) )
1015 && ( ( projectedPos1 > length ) || projectedPos1 < 0 ) )
1018 std::vector<PATH_CONNECTION> pcs = csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1020 if( pcs.size() < 2 )
1023 result.push_back( pcs.at( trackSide == 1 ? 0 : 1 ) );
1025 PointOnTrack = start;
1026 PointOnTrack += ( end - start ).Resize( projectedPos2 );
1027 PointOnTrack += ( end - start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1028 PointOnCircle = circleCenter + ( end - start ).Resize( circleRadius );
1029 weightSquared = ( PointOnCircle - PointOnTrack ).SquaredEuclideanNorm();
1031 if( weightSquared < aMaxSquaredWeight )
1034 pc.
a1 = PointOnTrack;
1035 pc.
a2 = PointOnCircle;
1036 pc.
weight = sqrt( weightSquared );
1038 result.push_back( pc );
1047 double aMaxSquaredWeight )
const
1049 std::vector<PATH_CONNECTION> result;
1053 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1059 result.push_back( pc );
1063 if( result.size() < 2 )
1073 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1075 beArcEndAngle,
nullptr ) )
1076 result.push_back( pc );
1078 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1080 beArcEndAngle,
nullptr ) )
1081 result.push_back( pc );
1089 double aMaxSquaredWeight )
const
1091 std::vector<PATH_CONNECTION> result;
1099 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1105 result.push_back( pc );
1109 if( result.size() < 2 )
1114 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1116 beArcEndAngle,
nullptr ) )
1117 result.push_back( pc );
1119 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1121 beArcEndAngle,
nullptr ) )
1122 result.push_back( pc );
1128 double aMaxSquaredWeight )
const
1130 std::vector<PATH_CONNECTION> result;
1134 for(
auto& pc : this->
Paths( csc, aMaxWeight, aMaxSquaredWeight ) )
1140 result.push_back( pc );
1144 if( result.size() < 2 )
1149 for(
auto& pc : this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight ) )
1150 result.push_back( pc );
1152 for(
auto& pc : this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight ) )
1153 result.push_back( pc );
1161 double aMaxSquaredWeight )
const
1163 std::vector<PATH_CONNECTION> result;
1171 for(
auto& pc : this->
Paths( bsc, aMaxWeight, aMaxSquaredWeight ) )
1177 result.push_back( pc );
1181 if( result.size() < 2 )
1186 for(
auto& pc : this->
Paths( bsp1, aMaxWeight, aMaxSquaredWeight ) )
1188 beArcEndAngle,
nullptr ) )
1189 result.push_back( pc );
1191 for(
auto& pc : this->
Paths( bsp2, aMaxWeight, aMaxSquaredWeight ) )
1193 beArcEndAngle,
nullptr ) )
1194 result.push_back( pc );
1202 double aMaxSquaredWeight )
const
1204 std::vector<PATH_CONNECTION> result;
1209 double weight = ( center - point ).EuclideanNorm() - R;
1211 if( weight > aMaxWeight )
1217 pc.
a1 = center + ( point - center ).Resize( R );
1219 result.push_back( pc );
1225 double aMaxSquaredWeight )
const
1227 std::vector<PATH_CONNECTION> result;
1234 if( ( C1 - C2 ).SquaredEuclideanNorm() < ( R1 - R2 ) * ( R1 - R2 ) )
1240 double weight = ( C1 - C2 ).EuclideanNorm() - R1 - R2;
1242 if( weight > aMaxWeight || weight < 0 )
1247 pc.
a1 = ( C2 - C1 ).Resize( R1 ) + C1;
1248 pc.
a2 = ( C1 - C2 ).Resize( R2 ) + C2;
1249 result.push_back( pc );
1255 double aMaxSquaredWeight )
const
1257 std::vector<PATH_CONNECTION> result;
1261 double halfWidth = this->
GetWidth() / 2;
1263 EDA_ANGLE trackAngle( s_end - s_start );
1266 double length = ( s_start - s_end ).EuclideanNorm();
1267 double projectedPos = cos( trackAngle.
AsRadians() ) * ( pointPos.
x - s_start.
x )
1268 + sin( trackAngle.
AsRadians() ) * ( pointPos.
y - s_start.
y );
1270 if( ( projectedPos <= 0 ) || ( s_start == s_end ) )
1273 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1275 if( projectedPos >= length )
1278 return csc.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1282 double trackSide = ( s_end - s_start ).Cross( pointPos - s_start ) > 0 ? 1 : -1;
1285 pc.
a1 = s_start + ( s_end - s_start ).Resize( projectedPos )
1286 + ( s_end - s_start ).Perpendicular().
Resize( halfWidth ) * trackSide;
1287 pc.
a2 = ( pc.
a1 - pointPos ).Resize( radius ) + pointPos;
1288 pc.
weight = ( pc.
a2 - pc.
a1 ).SquaredEuclideanNorm();
1290 if( pc.
weight <= aMaxSquaredWeight )
1293 result.push_back( pc );
1300 double aMaxSquaredWeight )
const
1302 std::vector<PATH_CONNECTION> result;
1307 double circleRadius = this->
GetRadius();
1315 if( ( circlePos - arcPos ).EuclideanNorm() > arcRadius + circleRadius )
1317 std::vector<PATH_CONNECTION> pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1319 if( pcs.size() == 1 )
1325 result.push_back( pcs[0] );
1337 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
1338 std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1342 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1348 if( !bestPath || ( ( bestPath->
weight > pc.weight ) && ( pc.weight > 0 ) ) )
1356 if( ( circlePos - arcPos ).SquaredEuclideanNorm() < arcRadius * arcRadius )
1358 if( circlePos != arcPos )
1364 pc3.
weight = arcRadius - ( circlePos - arcPos ).EuclideanNorm() - circleRadius;
1365 pc3.
a1 = circlePos + ( circlePos - arcPos ).Resize( circleRadius );
1366 pc3.
a2 = arcPos + ( circlePos - arcPos ).Resize( arcRadius - aS2.
GetWidth() / 2 );
1374 if( bestPath && bestPath->
weight > 0 )
1376 result.push_back( *bestPath );
1384 double aMaxSquaredWeight )
const
1386 std::vector<PATH_CONNECTION> result;
1390 double halfWidth1 = this->
GetWidth() / 2;
1394 double halfWidth2 = aS2.
GetWidth() / 2;
1399 std::vector<PATH_CONNECTION> pcs;
1400 pcs = this->
Paths( csc, aMaxWeight, aMaxSquaredWeight );
1402 if( pcs.size() < 1 )
1408 if( pcs.size() > 0 )
1410 circlePoint = pcs[0].a1;
1413 if( testAngle < aS2.
GetEndAngle() && pcs.size() > 0 )
1415 result.push_back( pcs[0] );
1424 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc1, aMaxWeight, aMaxSquaredWeight );
1428 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1434 std::vector<PATH_CONNECTION> pcs2 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1438 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1447 std::vector<PATH_CONNECTION> pcs3 = csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1451 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1458 std::vector<PATH_CONNECTION> pcs4 = csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1462 if( !bestPath || ( bestPath->
weight > pc.weight ) )
1470 result.push_back( *bestPath );
1490 t = std::max( 0.0, std::min( 1.0, t ) );
1492 return A + ( AB * t );
1498 double aMaxSquaredWeight )
const
1500 std::vector<PATH_CONNECTION> result;
1504 double halfWidth1 = this->
GetWidth() / 2;
1509 double halfWidth2 = aS2.
GetWidth() / 2;
1517 double dist1 = ( P1 -
C ).SquaredEuclideanNorm();
1518 double dist2 = ( P2 -
D ).SquaredEuclideanNorm();
1519 double dist3 = ( P3 -
A ).SquaredEuclideanNorm();
1520 double dist4 = ( P4 -
B ).SquaredEuclideanNorm();
1523 double min_dist = dist1;
1527 if( dist2 < min_dist )
1534 if( dist3 < min_dist )
1541 if( dist4 < min_dist )
1550 pc.
a1 = closest1 + ( closest2 - closest1 ).Resize( halfWidth1 );
1551 pc.
a2 = closest2 + ( closest1 - closest2 ).Resize( halfWidth2 );
1552 pc.
weight = sqrt( min_dist ) - halfWidth1 - halfWidth2;
1554 if( pc.
weight <= aMaxWeight )
1556 result.push_back( pc );
1563 double aMaxSquaredWeight )
const
1565 std::vector<PATH_CONNECTION> result;
1571 double dist = ( center1 - center2 ).EuclideanNorm();
1573 if( dist > aMaxWeight || dist == 0 )
1578 double weight = sqrt( dist * dist - R2 * R2 ) - R1;
1579 double theta = asin( R2 / dist );
1580 double psi = acos( R2 / dist );
1582 if( weight > aMaxWeight )
1595 pStart =
VECTOR2I( R1 * cos( theta + circleAngle ), R1 * sin( theta + circleAngle ) );
1597 pEnd =
VECTOR2I( -R2 * cos( psi - circleAngle ), R2 * sin( psi - circleAngle ) );
1603 result.push_back( pc );
1605 pStart =
VECTOR2I( R1 * cos( -theta + circleAngle ), R1 * sin( -theta + circleAngle ) );
1607 pEnd =
VECTOR2I( -R2 * cos( -psi - circleAngle ), R2 * sin( -psi - circleAngle ) );
1613 result.push_back( pc );
1619 double aMaxSquaredWeight )
const
1621 std::vector<PATH_CONNECTION> result;
1637 if( ( point - arcCenter ).SquaredEuclideanNorm() > radius * radius )
1640 return circle.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1645 pc.
weight = ( radius - width / 2 ) - ( point - arcCenter ).EuclideanNorm();
1646 pc.
a1 = ( point - arcCenter ).Resize( radius - width / 2 ) + arcCenter;
1650 result.push_back( pc );
1659 if( ( point - this->
GetStartPoint() ).SquaredEuclideanNorm()
1660 > ( point - this->
GetEndPoint() ).SquaredEuclideanNorm() )
1666 return circle.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1673 double aMaxSquaredWeight )
const
1675 std::vector<PATH_CONNECTION> result;
1684 bestPath.
weight = std::numeric_limits<double>::infinity();
1693 std::vector<PATH_CONNECTION> pcs0 = csc1.
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1695 std::vector<PATH_CONNECTION> pcs1 = this->
Paths( csc2, aMaxWeight, aMaxSquaredWeight );
1696 std::vector<PATH_CONNECTION> pcs2 = csc1.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1698 std::vector<PATH_CONNECTION> pcs3 = this->
Paths( csc5, aMaxWeight, aMaxSquaredWeight );
1699 std::vector<PATH_CONNECTION> pcs4 = this->
Paths( csc6, aMaxWeight, aMaxSquaredWeight );
1701 std::vector<PATH_CONNECTION> pcs5 = csc3.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1702 std::vector<PATH_CONNECTION> pcs6 = csc4.
Paths( aS2, aMaxWeight, aMaxSquaredWeight );
1704 for( std::vector<PATH_CONNECTION> pcs : { pcs0, pcs1, pcs2 } )
1712 && ( bestPath.
weight > pc.weight ) )
1719 for( std::vector<PATH_CONNECTION> pcs : { pcs3, pcs4, pcs5, pcs6 } )
1723 if( bestPath.
weight > pc.weight )
1730 if( bestPath.
weight != std::numeric_limits<double>::infinity() )
1732 result.push_back( bestPath );
1740 std::vector<VECTOR2I>* aIntersectPoints )
1742 SEG segment( p1, p2 );
1743 CIRCLE circle( center, radius );
1745 std::vector<VECTOR2I> intersectionPoints;
1750 std::visit( visitor, geom1 );
1752 if( aIntersectPoints )
1754 for(
VECTOR2I& point : intersectionPoints )
1756 aIntersectPoints->push_back( point );
1760 return intersectionPoints.size() > 0;
1764 const std::vector<BOARD_ITEM*>& aBe,
1765 const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
1766 int aMinGrooveWidth )
1768 std::vector<VECTOR2I> intersectionPoints;
1769 bool TestGrooveWidth = aMinGrooveWidth > 0;
1773 if( count( aDontTestAgainst.begin(), aDontTestAgainst.end(), be ) > 0 )
1787 if( intersects && !TestGrooveWidth )
1798 bool intersects =
false;
1804 if( intersects && !TestGrooveWidth )
1812 std::vector<VECTOR2I> points;
1815 if( points.size() < 2 )
1817 VECTOR2I prevPoint = points.back();
1819 bool intersects =
false;
1821 for(
auto p : points )
1826 if( intersects && !TestGrooveWidth )
1840 if( intersects && !TestGrooveWidth )
1858 if( intersects && !TestGrooveWidth )
1869 if( intersectionPoints.size() <= 0 )
1872 if( intersectionPoints.size() % 2 != 0 )
1875 int minx = intersectionPoints[0].x;
1876 int maxx = intersectionPoints[0].x;
1877 int miny = intersectionPoints[0].y;
1878 int maxy = intersectionPoints[0].y;
1880 for(
VECTOR2I v : intersectionPoints )
1882 minx = v.x < minx ? v.x : minx;
1883 maxx = v.x > maxx ? v.x : maxx;
1884 miny = v.x < miny ? v.x : miny;
1885 maxy = v.x > maxy ? v.x : maxy;
1887 if( abs( maxx - minx ) > abs( maxy - miny ) )
1889 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1897 std::sort( intersectionPoints.begin(), intersectionPoints.end(),
1904 int GVSquared = aMinGrooveWidth * aMinGrooveWidth;
1906 for(
size_t i = 0; i < intersectionPoints.size(); i += 2 )
1908 if( intersectionPoints[i].SquaredDistance( intersectionPoints[i + 1] ) > GVSquared )
1917 std::vector<const BOARD_ITEM*> aDontTestAgainst )
1924 double maxWeight = aMaxWeight;
1925 double maxWeightSquared = maxWeight * maxWeight;
1926 std::vector<PATH_CONNECTION> result;
1945 if( cuarc1 && cuarc2 )
1946 return cuarc1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1947 if( cuarc1 && cucircle2 )
1948 return cuarc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1949 if( cuarc1 && cusegment2 )
1950 return cuarc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1951 if( cucircle1 && cuarc2 )
1952 return cucircle1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1953 if( cucircle1 && cucircle2 )
1954 return cucircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1955 if( cucircle1 && cusegment2 )
1956 return cucircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1957 if( cusegment1 && cuarc2 )
1958 return cusegment1->
Paths( *cuarc2, maxWeight, maxWeightSquared );
1959 if( cusegment1 && cucircle2 )
1960 return cusegment1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1961 if( cusegment1 && cusegment2 )
1962 return cusegment1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
1967 if( cuarc1 && bearc2 )
1968 return cuarc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1969 if( cuarc1 && becircle2 )
1970 return cuarc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1971 if( cuarc1 && bepoint2 )
1972 return cuarc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1973 if( cucircle1 && bearc2 )
1974 return cucircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1975 if( cucircle1 && becircle2 )
1976 return cucircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1977 if( cucircle1 && bepoint2 )
1978 return cucircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1979 if( cusegment1 && bearc2 )
1980 return cusegment1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1981 if( cusegment1 && becircle2 )
1982 return cusegment1->
Paths( *becircle2, maxWeight, maxWeightSquared );
1983 if( cusegment1 && bepoint2 )
1984 return cusegment1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
1989 if( cuarc2 && bearc1 )
1990 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1991 if( cuarc2 && becircle1 )
1992 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1993 if( cuarc2 && bepoint1 )
1994 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
1995 if( cucircle2 && bearc1 )
1996 return bearc1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1997 if( cucircle2 && becircle1 )
1998 return becircle1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
1999 if( cucircle2 && bepoint1 )
2000 return bepoint1->
Paths( *cucircle2, maxWeight, maxWeightSquared );
2001 if( cusegment2 && bearc1 )
2002 return bearc1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2003 if( cusegment2 && becircle1 )
2004 return becircle1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2005 if( cusegment2 && bepoint1 )
2006 return bepoint1->
Paths( *cusegment2, maxWeight, maxWeightSquared );
2011 if( bearc1 && bearc2 )
2012 return bearc1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2013 if( bearc1 && becircle2 )
2014 return bearc1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2015 if( bearc1 && bepoint2 )
2016 return bearc1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2017 if( becircle1 && bearc2 )
2018 return becircle1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2019 if( becircle1 && becircle2 )
2020 return becircle1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2021 if( becircle1 && bepoint2 )
2022 return becircle1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2023 if( bepoint1 && bearc2 )
2024 return bepoint1->
Paths( *bearc2, maxWeight, maxWeightSquared );
2025 if( bepoint1 && becircle2 )
2026 return bepoint1->
Paths( *becircle2, maxWeight, maxWeightSquared );
2027 if( bepoint1 && bepoint2 )
2028 return bepoint1->
Paths( *bepoint2, maxWeight, maxWeightSquared );
2034 std::shared_ptr<GraphNode>& aFrom, std::shared_ptr<GraphNode>& aTo,
2035 std::vector<std::shared_ptr<GraphConnection>>& aResult )
2037 if( !aFrom || !aTo )
2044 std::unordered_map<GraphNode*, double> distances;
2045 std::unordered_map<GraphNode*, GraphNode*> previous;
2049 if( distances[
left] == distances[
right] )
2051 return distances[
left] > distances[
right];
2053 std::priority_queue<GraphNode*, std::vector<GraphNode*>,
decltype( cmp )> pq( cmp );
2056 for( std::shared_ptr<GraphNode> node :
m_nodes )
2058 if( node !=
nullptr )
2059 distances[node.get()] = std::numeric_limits<double>::infinity();
2061 distances[aFrom.get()] = 0.0;
2062 distances[aTo.get()] = std::numeric_limits<double>::infinity();
2063 pq.push( aFrom.get() );
2066 while( !pq.empty() )
2071 if( current == aTo.get() )
2077 for( std::shared_ptr<GraphConnection> connection : current->
m_connections )
2079 GraphNode* neighbor = ( connection->n1 ).get() == current ? ( connection->n2 ).get()
2080 : ( connection->n1 ).get();
2085 double alt = distances[current]
2086 + connection->m_path.weight;
2088 if( alt < distances[neighbor] )
2090 distances[neighbor] = alt;
2091 previous[neighbor] = current;
2092 pq.push( neighbor );
2097 double pathWeight = distances[aTo.get()];
2100 if( pathWeight == std::numeric_limits<double>::infinity() )
2102 return std::numeric_limits<double>::infinity();
2108 while( step != aFrom.get() )
2111 for( std::shared_ptr<GraphConnection> connection : step->
m_connections )
2113 if( ( ( connection->n1 ).get() == prevNode && ( connection->n2 ).get() == step )
2114 || ( ( connection->n1 ).get() == step && ( connection->n2 ).get() == prevNode ) )
2116 aResult.push_back( connection );
2134 switch( aShape.
Type() )
2148 newshape =
dynamic_cast<CREEP_SHAPE*
>( cucircle );
2157 EDA_SHAPE edaArc( SHAPE_T::ARC, 0, FILL_T::NO_FILL );
2162 start = arc.
GetP0();
2168 start = arc.
GetP1();
2182 int nbShapes =
static_cast<const SHAPE_COMPOUND*
>( &aShape )->Shapes().size();
2188 if( !( ( subshape->Type() ==
SH_RECT ) && ( nbShapes == 5 ) ) )
2189 Addshape( *subshape, aConnectTo, aParent );
2200 const SEG object = *it;
2202 Addshape( segment, aConnectTo, aParent );
2212 for(
auto point : lineChain.
CPoints() )
2216 Addshape( segment, aConnectTo, aParent );
2241 std::shared_ptr<GraphNode> gnShape =
nullptr;
2245 switch( aShape.
Type() )
2256 gnShape->m_net = aConnectTo->m_net;
2257 std::shared_ptr<GraphConnection> gc =
AddConnection( gnShape, aConnectTo );
2260 gc->m_path.m_show =
false;
2270 bool aGenerateBoardEdges )
2272 std::vector<std::shared_ptr<GraphNode>> nodes1 =
m_nodes;
2273 std::vector<std::shared_ptr<GraphNode>> nodes2 =
m_nodes;
2276 for( std::shared_ptr<GraphNode> gn1 : nodes1 )
2278 nodes2.erase( nodes2.begin() );
2283 if( !gn1->m_parent )
2286 if( !gn1->m_connectDirectly )
2289 if( gn1->m_type == GraphNode::TYPE::VIRTUAL )
2293 for( std::shared_ptr<GraphNode> gn2 : nodes2 )
2298 if( !gn2->m_parent )
2301 if( gn1->m_parent == gn2->m_parent )
2304 if( !gn2->m_connectDirectly )
2307 if( gn2->m_type == GraphNode::TYPE::VIRTUAL )
2310 if( !aGenerateBoardEdges && !gn1->m_parent->IsConductive()
2311 && !gn2->m_parent->IsConductive() )
2314 if( ( gn1->m_net == gn2->m_net ) && ( gn1->m_parent->IsConductive() )
2315 && ( gn2->m_parent->IsConductive() ) )
2320 std::vector<const BOARD_ITEM*> IgnoreForTest;
2321 IgnoreForTest.push_back( gn1->m_parent->GetParent() );
2322 IgnoreForTest.push_back( gn2->m_parent->GetParent() );
2328 std::shared_ptr<GraphNode>* connect1 = &gn1;
2329 std::shared_ptr<GraphNode>* connect2 = &gn2;
2330 std::shared_ptr<GraphNode> gnt1 =
nullptr;
2331 std::shared_ptr<GraphNode> gnt2 =
nullptr;
2333 if ( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2336 gnt1->m_connectDirectly =
false;
2338 if( gn1->m_parent->IsConductive() )
2340 std::shared_ptr<GraphConnection> gc =
AddConnection( gn1, gnt1 );
2343 gc->m_path.m_show =
false;
2348 if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
2351 gnt2->m_connectDirectly =
false;
2353 if( gn2->m_parent->IsConductive() )
2355 std::shared_ptr<GraphConnection> gc =
AddConnection( gn2, gnt2 );
2358 gc->m_path.m_show =
false;
2372 std::vector<std::shared_ptr<GraphConnection>> toRemove;
2377 if( gc && ( gc->m_path.weight > aWeightLimit ) )
2379 toRemove.push_back( gc );
2384 for(
const std::shared_ptr<GraphConnection>& gc : toRemove )
2395 for( std::shared_ptr<GraphNode> gn : { aGc->n1, aGc->n2 } )
2399 auto& nConns = gn->m_connections;
2400 nConns.erase( std::remove( nConns.begin(), nConns.end(), aGc ), nConns.end() );
2402 if( nConns.empty() && aDelete )
2405 [&gn](
const std::shared_ptr<GraphNode> node )
2407 return node.get() == gn.get();
2429 std::shared_ptr<GraphNode> gn =
FindNode( aType, parent, pos );
2433 gn = std::make_shared<GraphNode>( aType, parent, pos );
2441 std::shared_ptr<GraphNode> gn =
2442 std::make_shared<GraphNode>( GraphNode::TYPE::VIRTUAL,
nullptr );
2449 std::shared_ptr<GraphNode>& aN2,
2455 wxASSERT_MSG( ( aN1 != aN2 ),
"Creepage: a connection connects a node to itself" );
2457 std::shared_ptr<GraphConnection> gc = std::make_shared<GraphConnection>( aN1, aN2, aPc );
2459 aN1->m_connections.push_back( gc );
2460 aN2->m_connections.push_back( gc );
2466 std::shared_ptr<GraphNode>& aN2 )
2482 for( std::shared_ptr<GraphNode> gn :
m_nodes )
2484 if( aPos == gn->m_pos && aParent == gn->
m_parent && aType == gn->m_type )
2497 virtualNode->m_net = aNetCode;
2501 for(
PAD*
pad : footprint->Pads() )
2503 if(
pad->GetNetCode() != aNetCode )
2506 std::shared_ptr<SHAPE> padShape =
pad->GetEffectiveShape( aLayer );
2520 if( track->GetNetCode() != aNetCode )
2523 if( !track->IsOnLayer( aLayer ) )
2526 if( track->GetEffectiveShape() ==
nullptr )
2529 Addshape( *( track->GetEffectiveShape() ), virtualNode, track );
2538 if( zone->GetNetCode() != aNetCode )
2541 if( zone->GetEffectiveShape( aLayer ) ==
nullptr )
2544 Addshape( *( zone->GetEffectiveShape( aLayer ) ), virtualNode, zone );
2554 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
EDA_ANGLE GetEndAngle() const override
void ConnectChildren(std::shared_ptr< GraphNode > &a1, std::shared_ptr< GraphNode > &a2, CreepageGraph &aG) const override
VECTOR2I GetEndPoint() const override
EDA_ANGLE AngleBetweenStartAndEnd(const VECTOR2I aPoint) const
Creepage: a board edge circle.
void ShortenChildDueToGV(std::shared_ptr< GraphNode > &a1, std::shared_ptr< GraphNode > &a2, CreepageGraph &aG, double aNormalWeight) const
int GetRadius() const override
void ConnectChildren(std::shared_ptr< GraphNode > &a1, std::shared_ptr< GraphNode > &a2, CreepageGraph &aG) const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
Creepage: a board edge point.
void ConnectChildren(std::shared_ptr< GraphNode > &a1, std::shared_ptr< GraphNode > &a2, CreepageGraph &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.
A class used to represent the shapes for creepage calculation.
CREEP_SHAPE::TYPE GetType() const
void SetParent(BOARD_ITEM *aParent)
virtual void ConnectChildren(std::shared_ptr< GraphNode > &a1, std::shared_ptr< GraphNode > &a2, CreepageGraph &aG) const
virtual int GetRadius() 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
A graph with nodes and connections for creepage calculation.
std::vector< CREEP_SHAPE * > m_shapeCollection
void RemoveDuplicatedShapes()
std::vector< std::shared_ptr< GraphNode > > m_nodes
std::shared_ptr< GraphNode > FindNode(GraphNode::TYPE aType, CREEP_SHAPE *aParent, VECTOR2I aPos)
double m_creepageTargetSquared
std::shared_ptr< GraphNode > AddNodeVirtual()
std::shared_ptr< GraphNode > AddNode(GraphNode::TYPE aType, CREEP_SHAPE *aParent=nullptr, VECTOR2I aPos=VECTOR2I())
std::shared_ptr< GraphNode > AddNetElements(int aNetCode, PCB_LAYER_ID aLayer, int aMaxCreepage)
std::vector< std::shared_ptr< GraphConnection > > m_connections
void SetTarget(double aTarget)
void TransformCreepShapesToNodes(std::vector< CREEP_SHAPE * > &aShapes)
double Solve(std::shared_ptr< GraphNode > &aFrom, std::shared_ptr< GraphNode > &aTo, std::vector< std::shared_ptr< GraphConnection > > &aResult)
std::vector< BOARD_ITEM * > m_boardEdge
void TransformEdgeToCreepShapes()
void Addshape(const SHAPE &aShape, std::shared_ptr< GraphNode > &aConnectTo, BOARD_ITEM *aParent=nullptr)
void GeneratePaths(double aMaxWeight, PCB_LAYER_ID aLayer, bool aGenerateBoardEdges=true)
SHAPE_POLY_SET * m_boardOutline
std::shared_ptr< GraphConnection > AddConnection(std::shared_ptr< GraphNode > &aN1, std::shared_ptr< GraphNode > &aN2, const PATH_CONNECTION &aPc)
void Trim(double aWeightLimit)
void RemoveConnection(std::shared_ptr< GraphConnection >, bool aDelete=false)
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::shared_ptr< GraphNode > n1
std::vector< PCB_SHAPE > GetShapes()
std::shared_ptr< GraphNode > n2
std::vector< std::shared_ptr< GraphConnection > > m_connections
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
@ ARC
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...
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D