Skip to content

Commit 3881d2a

Browse files
authored
Fix: Detect collision if one line is almost vertical (#5510) (#5531)
1 parent f43e049 commit 3881d2a

1 file changed

Lines changed: 18 additions & 18 deletions

File tree

src/rshapes.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2365,30 +2365,30 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
23652365
// Check the collision between two lines defined by two points each, returns collision point by reference
23662366
bool CheckCollisionLines(Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2 *collisionPoint)
23672367
{
2368-
bool collision = false;
2368+
// According to https://en.wikipedia.org/wiki/Line–line_intersection#Given_two_points_on_each_line_segment
2369+
float rx = endPos1.x - startPos1.x;
2370+
float ry = endPos1.y - startPos1.y;
2371+
float sx = endPos2.x - startPos2.x;
2372+
float sy = endPos2.y - startPos2.y;
23692373

2370-
float div = (endPos2.y - startPos2.y)*(endPos1.x - startPos1.x) - (endPos2.x - startPos2.x)*(endPos1.y - startPos1.y);
2374+
float div = rx * sy - ry * sx;
23712375

2372-
if (fabsf(div) >= FLT_EPSILON)
2373-
{
2374-
collision = true;
2376+
if (fabsf(div) < FLT_EPSILON) {
2377+
return false;
2378+
}
23752379

2376-
float xi = ((startPos2.x - endPos2.x)*(startPos1.x*endPos1.y - startPos1.y*endPos1.x) - (startPos1.x - endPos1.x)*(startPos2.x*endPos2.y - startPos2.y*endPos2.x))/div;
2377-
float yi = ((startPos2.y - endPos2.y)*(startPos1.x*endPos1.y - startPos1.y*endPos1.x) - (startPos1.y - endPos1.y)*(startPos2.x*endPos2.y - startPos2.y*endPos2.x))/div;
2380+
float s12x = startPos2.x - startPos1.x;
2381+
float s12y = startPos2.y - startPos1.y;
23782382

2379-
if (((fabsf(startPos1.x - endPos1.x) > FLT_EPSILON) && (xi < fminf(startPos1.x, endPos1.x) || (xi > fmaxf(startPos1.x, endPos1.x)))) ||
2380-
((fabsf(startPos2.x - endPos2.x) > FLT_EPSILON) && (xi < fminf(startPos2.x, endPos2.x) || (xi > fmaxf(startPos2.x, endPos2.x)))) ||
2381-
((fabsf(startPos1.y - endPos1.y) > FLT_EPSILON) && (yi < fminf(startPos1.y, endPos1.y) || (yi > fmaxf(startPos1.y, endPos1.y)))) ||
2382-
((fabsf(startPos2.y - endPos2.y) > FLT_EPSILON) && (yi < fminf(startPos2.y, endPos2.y) || (yi > fmaxf(startPos2.y, endPos2.y))))) collision = false;
2383+
float t = (s12x * sy - s12y * sx) / div;
2384+
float u = (s12x * ry - s12y * rx) / div;
23832385

2384-
if (collision && (collisionPoint != 0))
2385-
{
2386-
collisionPoint->x = xi;
2387-
collisionPoint->y = yi;
2388-
}
2386+
if (0.0f <= t && t <= 1.0f && 0.0f <= u && u <= 1.0f) {
2387+
collisionPoint->x = startPos1.x + t * rx;
2388+
collisionPoint->y = startPos1.y + t * ry;
2389+
return true;
23892390
}
2390-
2391-
return collision;
2391+
return false;
23922392
}
23932393

23942394
// Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold]

0 commit comments

Comments
 (0)