Collision Detection

edited January 2016 in Share Your Work

In the following code, there is a boolean function doing collisions for circles, rectangles, and lines.

I have another post that includes triangles here: https://forum.processing.org/two/discussion/14408/collision-detection-triangles (split out because including all 4 in a single post has too many characters).

If the function returns false, there is no collision, and if the function returns true, there is a collision. The input for the function is usually pretty self explanatory by the variable names, but I have commented in some help above each function on the variables if you need.

//circle x, circle y, circle radius, rectangle x, rectangle y, rect x size, rect y size
boolean circRectColl(float cx, float cy, float cr, float sx, float sy, float sxs, float sys) {
  if (cx + cr < sx || cx - cr > sx + sxs || cy + cr < sy || cy - cr > sy + sys) {
    return false;
  }
  if (dist(cx, cy, sx, sy) <= cr) {
    return true;
  }
  if (dist(cx, cy, sx + sxs, sy) <= cr) {
    return true;
  }
  if (dist(cx, cy, sx, sy + sys) <= cr) {
    return true;
  }
  if (dist(cx, cy, sx + sxs, sy + sys) <= cr) {
    return true;
  }
  if (cx + cr >= sx && cx <= sx + sxs && cy >= sy && cy <= sy + sys) {
    return true;
  }
  if (cx - cr <= sx + sxs && cx >= sx && cy >= sy && cy <= sy + sys) {
    return true;
  }
  if (cy + cr >= sy && cy <= sy + sys && cx >= sx && cx <= sx + sxs) {
    return true;
  }
  if (cy - cr <= sy + sys && cy >= sy && cx >= sx && cx <= sx + sxs) {
    return true;
  }
  return false;
}

//circ 1 x, circ 1 y, circ 1 radius, circ 2 x, circ 2 y, circ 2 radius
boolean circCircColl(float x1, float y1, float r1, float x2, float y2, float r2) {
  if (dist(x1, y1, x2, y2) <= r1 + r2) {
    return true;
  }
  return false;
}

//line x 1, line y 1, line x 2, line y 2, circle x, circle y, circle radius
boolean lineCircColl(float xL1, float yL1, float xL2, float yL2, float cx, float cy, float cr) {
  if (dist(xL1, yL1, cx, cy) <= cr) {
    return true;
  }
  if (dist(xL2, yL2, cx, cy) <= cr) {
    return true;
  }
  float yInter;
  float xDif;
  float yDif;
  float pYInter;
  PVector intersection = new PVector(0, 0);
  xDif = xL1 - xL2;
  yDif = yL1 - yL2;
  yInter = yL1 - (xL1 * yDif) / xDif;
  pYInter = cy - (cx * xDif) / - yDif;
  intersection.x = (yInter - pYInter) / ((xDif / - yDif) - (yDif / xDif));
  intersection.y = (intersection.x * yDif) / xDif + yInter;
  if (dist(intersection.x, intersection.y, cx, cy) <= cr && ((intersection.x <= xL1 && intersection.x >= xL2) || (intersection.x >= xL1 && intersection.x <= xL2))) {
    return true;
  }
  return false;
}

//line 1 x 1, line 1 y 1, line 1 x 2, line 1 y 2, line 2 x 1, line 2 y 1, line 2 x 2, line 2 y 2
boolean lineLineColl(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2) {
  if ((l1x1 - l1x2) / (l1y1 - l1y2) == (l2x1 - l2x2) / (l2y1 - l2y2)) {
    return false;
  }
  float y1Inter = l1y1 - l1x1 * (l1y1 - l1y2) / (l1x1 - l1x2);
  float y2Inter = l2y1 - l2x1 * (l2y1 - l2y2) / (l2x1 - l2x2);
  PVector intersection = new PVector((y2Inter - y1Inter) / ((l1y1 - l1y2) / (l1x1 - l1x2) - (l1y1 - l1y2) / (l1x1 - l1x2)), 5);
  intersection.y = intersection.x * (l1y1 - l1y2) / (l1x1 - l1x2) + y1Inter;
  if ((intersection.x <= l1x1 && intersection.x >= l1x2) || (intersection.x >= l1x1 && intersection.x <= l1x2)) {
    return true;
  }
  return false;
}

//rect 1 x, rect 1 y, rect 1 x size, rect 1 y size, rect 2 x, rect 2 y, rect 2 x size, rect 2 y size
boolean rectRectColl(float x1, float y1, float sx1, float sy1, float x2, float y2, float sx2, float sy2) {
  if (x1 + sx1 >= x2 && x1 <= x2 + sx2 && y1 <= y2 + sy2 && y1 + sy1 >= y2) {
    return true;
  }
  return false;
}

//line x 1, line y 1, line x 2, line y 2, rect x, rect y, rect x size, rect y size
boolean lineRectColl(float x1L, float y1L, float x2L, float y2L, float xr, float yr, float xs, float ys) {
  if ((xr > x1L && xr > x2L) || (xr + xs < x1L && xr + xs < x2L)) {
    return false;
  }
  PVector Ldif = new PVector(0, 0);
  Ldif.x = x1L - x2L;
  Ldif.y = y1L - y2L;
  float yInter = y1L - (x1L * Ldif.y / Ldif.x);
  if ((xr * Ldif.y / Ldif.x + yInter >= yr && xr * Ldif.y / Ldif.x + yInter <= yr + ys && ((xr <= x1L && xr >= x2L) || (xr >= x1L && xr <= x2L))) || ((xr + xs) * Ldif.y / Ldif.x + yInter >= yr && (xr + xs) * Ldif.y / Ldif.x + yInter <= yr + ys && ((xr + xs <= x1L && xr + xs >= x2L) || (xr + xs >= x1L && xr + xs <= x2L)))) {
    return true;
  }
  if (((yr + yInter) * Ldif.x / Ldif.y >= xr && (yr + yInter) * Ldif.x / Ldif.y <= xr + xs && ((yr <= y1L && yr >= y2L) || (yr >= y1L && yr <= y2L))) || ((yr + ys + yInter) * Ldif.x / Ldif.y >= xr && (yr + ys + yInter) * Ldif.x / Ldif.y <= xr + xs && ((yr + ys <= y1L && yr + ys >= y2L) || (yr + ys >= y1L && yr + ys <= y2L)))) {
    return true;
  }
  return false;
}

Comments

  • thanks a ton for sharing!

  • You're welcome!

  • Warning! My lineLineCollision was put in incorrectly! This is the correct version: boolean lineLineColl(float l1x1, float l1y1, float l1x2, float l1y2, float l2x1, float l2y1, float l2x2, float l2y2) { if ((l1y1 - l1y2) / (l1x1 - l1x2) == (l2y1 - l2y2) / (l2x1 - l2x2)) { return false; } float y1Inter = l1y1 - l1x1 * (l1y1 - l1y2) / (l1x1 - l1x2); float y2Inter = l2y1 - l2x1 * (l2y1 - l2y2) / (l2x1 - l2x2); PVector intersection = new PVector((y1Inter - y2Inter) / ((l2y1 - l2y2) / (l2x1 - l2x2) - (l1y1 - l1y2) / (l1x1 - l1x2)), 0); intersection.y = intersection.x * (l1y1 - l1y2) / (l1x1 - l1x2) + y1Inter; if (((intersection.x <= l1x1 && intersection.x >= l1x2) || (intersection.x >= l1x1 && intersection.x <= l1x2)) && ((intersection.x <= l2x1 && intersection.x >= l2x2) || (intersection.x >= l2x1 && intersection.x <= l2x2))) { return true; } return false; }

  • You can edit posts. And format the code nicely.

Sign In or Register to comment.