| 1592 | |
| 1593 | |
| 1594 | std::vector<GCommand> replaceStraightSegmentsWithOneLine( const std::span<GCommand>& path, float eps, float maxLength, Axis axis ) |
| 1595 | { |
| 1596 | if ( path.size() < 3 ) |
| 1597 | return {}; |
| 1598 | |
| 1599 | std::vector<GCommand> res; |
| 1600 | |
| 1601 | const float epsSq = eps * eps; |
| 1602 | const float maxLengthSq = maxLength * maxLength; |
| 1603 | int startIdx = 0, endIdx = 0; |
| 1604 | for ( int i = startIdx + 2; i < path.size(); ++i ) |
| 1605 | { |
| 1606 | const auto& d0 = path[startIdx]; |
| 1607 | const auto& d2 = path[i]; |
| 1608 | |
| 1609 | const Vector2f p0 = project( d0, axis ); |
| 1610 | const Vector2f p2 = project( d2, axis ); |
| 1611 | |
| 1612 | if ( ( p0 - p2 ).lengthSq() < maxLengthSq ) // don't merge too long lines |
| 1613 | { |
| 1614 | bool allInTolerance = true; |
| 1615 | for ( int k = startIdx + 1; k < i; ++k ) |
| 1616 | { |
| 1617 | const auto& dk = path[k]; |
| 1618 | |
| 1619 | const Vector2f pk = project( dk, axis ); |
| 1620 | const float dist2 = distSqrToLineSegment( pk, p0, p2 ); |
| 1621 | if ( dist2 > epsSq ) |
| 1622 | { |
| 1623 | allInTolerance = false; |
| 1624 | break; |
| 1625 | } |
| 1626 | } |
| 1627 | if ( allInTolerance ) |
| 1628 | { |
| 1629 | endIdx = i; |
| 1630 | if ( i < path.size() - 1 ) // don't continue on last point, do interpolation |
| 1631 | continue; |
| 1632 | } |
| 1633 | } |
| 1634 | |
| 1635 | res.push_back( path[endIdx] ); |
| 1636 | startIdx = ( startIdx <= endIdx ) ? endIdx + 1 : endIdx; |
| 1637 | endIdx = startIdx; |
| 1638 | i = startIdx + 1; |
| 1639 | } |
| 1640 | |
| 1641 | for ( int i = startIdx; i < path.size(); ++i ) |
| 1642 | { |
| 1643 | res.push_back( path[i] ); |
| 1644 | } |
| 1645 | |
| 1646 | return res; |
| 1647 | } |
| 1648 | |
| 1649 | Expected<void> interpolateLines( std::vector<GCommand>& commands, const LineInterpolationParams& params, Axis axis ) |
| 1650 | { |
no test coverage detected