Hello,
I'm fairly new to programming, and I'm not exactly sure how to do line-rect collision detection. If it helps, I'm using SFML 2. Can someone explain to me how I would go about coding line-rect collision detection?
Thanks in advance.

Dani AI

Generated

Quick, practical answer for SFML/C++ (for ): treat your line as a segment and test it against an axis-aligned rectangle. Two common approaches are (a) test the segment against the rectangle's four edges (easy to understand) or (b) use a parametric clipping test (Liang–Barsky) which is compact and faster. pointed to good background material; below is a concise SFML-friendly implementation you can drop into your code.

Liang–Barsky idea in plain terms: parametrize the segment p(t) = p0 + t*(p1 - p0) with t in [0,1]. Each rectangle side gives a constraint on t; applying all four constraints produces an interval [t0,t1]. If that interval overlaps [0,1], the segment hits the rectangle. Important details: treat parallel cases with a small epsilon, decide whether a touch at the border counts as a hit, and compute the intersection point using t if you need it.

bool segmentIntersectsRect(const sf::Vector2f& p0, const sf::Vector2f& p1,
                           const sf::FloatRect& r, sf::Vector2f* outHit = nullptr)
{
    float t0 = 0.0f, t1 = 1.0f;
    float dx = p1.x - p0.x;
    float dy = p1.y - p0.y;
    const float EPS = 1e-8f;
    auto clip = [&](float p, float q) -> bool {
        if (fabs(p) < EPS) return q >= 0.0f; // parallel: inside only if q>=0
        float t = q / p;
        if (p < 0.0f) { if (t > t1) return false; if (t > t0) t0 = t; }
        else          { if (t < t0) return false; if (t < t1) t1 = t; }
        return true;
    };
    if (!clip(-dx, p0.x - r.left)) return false;
    if (!clip( dx, r.left + r.width  - p0.x)) return false;
    if (!clip(-dy, p0.y - r.top))  return false;
    if (!clip( dy, r.top  + r.height - p0.y)) return false;
    if (t0 > t1) return false;
    float t = (t0 >= 0.0f) ? t0 : t1;
    if (t < 0.0f || t > 1.0f) return false;
    if (outHit) { outHit->x = p0.x + dx * t; outHit->y = p0.y + dy * t; }
    return true;
}

Notes and pitfalls: for rotated rectangles transform the segment into the rectangle's local space (use sf::Transform::getInverse()). Watch SFML's y-down coordinate system, decide whether “touching” counts as collision, handle zero-length segments, and use a tiny EPS to avoid missed hits on near-parallel lines. If you need swept collisions for moving objects, consider a time-of-impact test or expand the rect by the line thickness.

Recommended Answers

All 3 Replies

Thanks :)

Always Welcome :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.