jeffThompson / CollisionDetection

A book and examples on collision detection
418 stars 53 forks source link

Missing case for poly-poly collision #34

Open BuyMyBeard opened 1 year ago

BuyMyBeard commented 1 year ago

The code here to tests for polygon on polygon collision takes into account that second polygon can be fully inside first polygon. It checks if a point of poly2 is inside poly1. the issue is that it doesn't check if first polygon is inside second.

// POLYGON/POLYGON
boolean polyPoly(PVector[] p1, PVector[] p2) {

  // go through each of the vertices, plus the next
  // vertex in the list
  int next = 0;
  for (int current=0; current<p1.length; current++) {

    // get next vertex in list
    // if we've hit the end, wrap around to 0
    next = current+1;
    if (next == p1.length) next = 0;

    // get the PVectors at our current position
    // this makes our if statement a little cleaner
    PVector vc = p1[current];    // c for "current"
    PVector vn = p1[next];       // n for "next"

    // now we can use these two points (a line) to compare
    // to the other polygon's vertices using polyLine()
    boolean collision = polyLine(p2, vc.x,vc.y,vn.x,vn.y);
    if (collision) return true;

    // optional: check if the 2nd polygon is INSIDE the first
    collision = polyPoint(p1, p2[0].x, p2[0].y);
    if (collision) return true;
  }

  return false;
}

Now some code I wrote in Typescript that allows to test for both cases since you only need to check one vertex of each polygon inside the other one:

public collidesWithPolygon(polygon : PolygonCollider) {
    if (this.collidesWithPoint(polygon.vertices[0]) || polygon.collidesWithPoint(this.vertices[0])) {
      return true;
    }
    for (const s1 of this.edges) {
      for (const s2 of polygon.edges) {
        if (this.segmentsIntersect2(s1, s2)) {
          return true;
        }
      }
    }
    return false;
  }