| 538 | |
| 539 | template <typename DataType> |
| 540 | typename Polygon<DataType>::IntersectResult Polygon<DataType>::satIntersection(Polygon const& p) const { |
| 541 | // "Accumulates" the shortest separating distance and axis of this poly and |
| 542 | // the given poly, after projecting all the vertexes of each poly onto a |
| 543 | // given axis. Used by SAT intersection, meant to be called with each tested |
| 544 | // axis. |
| 545 | auto accumSeparator = [this](Polygon const& p, Vertex const& axis, DataType& shortestOverlap, Vertex& finalSepDir) { |
| 546 | DataType myProjectionLow = std::numeric_limits<DataType>::max(); |
| 547 | DataType targetProjectionHigh = std::numeric_limits<DataType>::lowest(); |
| 548 | |
| 549 | for (auto const& v : m_vertexes) { |
| 550 | DataType p = axis[0] * v[0] + axis[1] * v[1]; |
| 551 | if (p < myProjectionLow) |
| 552 | myProjectionLow = p; |
| 553 | } |
| 554 | |
| 555 | for (auto const& v : p.m_vertexes) { |
| 556 | DataType p = axis[0] * v[0] + axis[1] * v[1]; |
| 557 | if (p > targetProjectionHigh) |
| 558 | targetProjectionHigh = p; |
| 559 | } |
| 560 | |
| 561 | float overlap = targetProjectionHigh - myProjectionLow; |
| 562 | if (overlap < shortestOverlap) { |
| 563 | shortestOverlap = overlap; |
| 564 | finalSepDir = axis; |
| 565 | } |
| 566 | }; |
| 567 | |
| 568 | DataType overlap = std::numeric_limits<DataType>::max(); |
| 569 | Vertex separatingDir = Vertex(); |
| 570 | |
| 571 | if (!m_vertexes.empty()) { |
| 572 | Vertex pv = m_vertexes[m_vertexes.size() - 1]; |
| 573 | for (auto const& v : m_vertexes) { |
| 574 | Vertex sideNormal = pv - v; |
| 575 | if (sideNormal != Vertex()) { |
| 576 | sideNormal = sideNormal.rot90().normalized(); |
| 577 | accumSeparator(p, -sideNormal, overlap, separatingDir); |
| 578 | } |
| 579 | pv = v; |
| 580 | } |
| 581 | } |
| 582 | |
| 583 | if (!p.m_vertexes.empty()) { |
| 584 | Vertex pv = p.m_vertexes[p.m_vertexes.size() - 1]; |
| 585 | for (auto const& v : p.m_vertexes) { |
| 586 | Vertex sideNormal = pv - v; |
| 587 | if (sideNormal != Vertex()) { |
| 588 | sideNormal = sideNormal.rot90().normalized(); |
| 589 | accumSeparator(p, sideNormal, overlap, separatingDir); |
| 590 | } |
| 591 | pv = v; |
| 592 | } |
| 593 | } |
| 594 | |
| 595 | IntersectResult isect; |
| 596 | isect.intersects = (overlap > 0); |
| 597 | isect.overlap = separatingDir * overlap; |
no test coverage detected