MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / replaceLineSegmentsWithCircularArcs

Function replaceLineSegmentsWithCircularArcs

source/MRVoxels/MRToolPath.cpp:1359–1488  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1357}
1358
1359std::vector<GCommand> replaceLineSegmentsWithCircularArcs( const std::span<GCommand>& path, float eps, float maxRadius, Axis axis )
1360{
1361 if ( path.size() < 5 )
1362 return {};
1363
1364 std::vector<GCommand> res;
1365
1366 int startIdx = 0, endIdx = 0;
1367 Vector2f bestArcCenter, bestArcStart, bestArcEnd;
1368 bool CCWrotation = false;
1369 double bestArcR = 0;
1370 for ( int i = startIdx + 2; i < path.size(); ++i )
1371 {
1372 const GCommand& d2 = path[i];
1373 const int middleI = ( i + startIdx ) / 2;
1374 const GCommand& d1 = path[middleI];
1375
1376 const Vector2f p0 = project( path[startIdx], axis );
1377 const Vector2f p1 = project( d1, axis );
1378 const Vector2f p2 = project( d2, axis );
1379
1380 const Vector2f dif1 = p1 - p0;
1381 const Vector2f dif2 = p2 - p1;
1382
1383 Vector2f pCenter;
1384 if ( dot( dif1, dif2 ) > 0
1385 && calcCircleCenter( p0, p1, p2, pCenter ) )
1386 {
1387 const double rArc = ( pCenter - p0 ).length();
1388 const double r2Max = sqr( rArc + eps );
1389 const double r2Min = sqr( rArc - eps );
1390
1391 const bool ccwRotation = cross( dif1, dif2 ) > 0;
1392
1393 Vector2f dirStart = rotate90( p0 - pCenter );
1394 Vector2f dirEnd = rotateMinus90( p2 - pCenter );
1395 if ( ccwRotation )
1396 {
1397 dirStart = -dirStart;
1398 dirEnd = -dirEnd;
1399 }
1400
1401 bool allInTolerance = true;
1402 Vector2f pPrev = p0;
1403 for ( int k = startIdx + 1; k <= i; ++k )
1404 {
1405 const Vector2f pk = project( path[k], axis );
1406 double r2k = ( pCenter - pk ).lengthSq();
1407 const Vector2f pkMiddle = ( pk + pPrev ) * 0.5f;
1408 double r2kMiddle = ( pCenter - pkMiddle ).lengthSq();
1409 if ( r2k < r2Min || r2k > r2Max
1410 || r2kMiddle < r2Min || r2kMiddle > r2Max )
1411 {
1412 allInTolerance = false;
1413 break;
1414 }
1415 bool insideArc = dot( dirStart, pk - p0 ) >= 0 && dot( dirEnd, pk - p2 ) >= 0;
1416 if ( !insideArc )

Callers 1

interpolateArcsFunction · 0.85

Calls 11

projectFunction · 0.85
calcCircleCenterFunction · 0.85
rotate90Function · 0.85
rotateMinus90Function · 0.85
push_backMethod · 0.80
dotFunction · 0.50
sqrFunction · 0.50
crossFunction · 0.50
sizeMethod · 0.45
lengthMethod · 0.45
lengthSqMethod · 0.45

Tested by

no test coverage detected