We are about to switch to a new forum software. Until then we have removed the registration on this forum.
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.