| 601 | |
| 602 | template <typename DataType> |
| 603 | typename Polygon<DataType>::IntersectResult Polygon<DataType>::directionalSatIntersection( |
| 604 | Polygon const& p, Vertex const& direction, bool chooseSign) const { |
| 605 | // A "directional" version of accumSeparator, that when intersecting only |
| 606 | // ever tries to separate in the given direction. |
| 607 | auto directionalAccumSeparator = [this](Polygon const& p, Vertex axis, DataType& shortestOverlap, |
| 608 | Vertex const& separatingDir, Vertex& finalSepDir, bool chooseDir) { |
| 609 | DataType myProjectionLow = std::numeric_limits<DataType>::max(); |
| 610 | DataType targetProjectionHigh = std::numeric_limits<DataType>::lowest(); |
| 611 | |
| 612 | for (auto const& v : m_vertexes) { |
| 613 | DataType p = axis[0] * v[0] + axis[1] * v[1]; |
| 614 | if (p < myProjectionLow) |
| 615 | myProjectionLow = p; |
| 616 | } |
| 617 | |
| 618 | for (auto const& v : p.m_vertexes) { |
| 619 | DataType p = axis[0] * v[0] + axis[1] * v[1]; |
| 620 | if (p > targetProjectionHigh) |
| 621 | targetProjectionHigh = p; |
| 622 | } |
| 623 | |
| 624 | float overlap = targetProjectionHigh - myProjectionLow; |
| 625 | |
| 626 | // Separation was found, skip the rest of the method. |
| 627 | if (overlap <= 0) { |
| 628 | if (overlap < shortestOverlap) { |
| 629 | shortestOverlap = overlap; |
| 630 | finalSepDir = axis; |
| 631 | } |
| 632 | return; |
| 633 | } |
| 634 | |
| 635 | DataType axisDot = separatingDir * axis; |
| 636 | |
| 637 | // Now, if we don't have separation and the axis is perpendicular to |
| 638 | // requested, we can do nothing, return. |
| 639 | if (axisDot == 0) |
| 640 | return; |
| 641 | |
| 642 | // Separate along the given separating direction enough to separate as |
| 643 | // determined by this axis. |
| 644 | DataType projOverlap = overlap / axisDot; |
| 645 | if (chooseDir) { |
| 646 | DataType absProjOverlap = (projOverlap >= 0) ? projOverlap : -projOverlap; |
| 647 | if (absProjOverlap < shortestOverlap) { |
| 648 | shortestOverlap = absProjOverlap; |
| 649 | finalSepDir = separatingDir * (projOverlap / absProjOverlap); |
| 650 | } |
| 651 | } else if (projOverlap >= 0) { |
| 652 | if (projOverlap < shortestOverlap) { |
| 653 | shortestOverlap = projOverlap; |
| 654 | finalSepDir = separatingDir; |
| 655 | } |
| 656 | } |
| 657 | }; |
| 658 | |
| 659 | DataType overlap = std::numeric_limits<DataType>::max(); |
| 660 | Vertex separatingDir = Vertex(); |
no test coverage detected