How to know if a line intersects a rectangle

后端 未结 8 545
梦谈多话
梦谈多话 2020-12-01 14:51

I have checked out this question, but the answer is very large for me:

How to know if a line intersects a plane in C#? - Basic 2D geometry

Is there any .NET

相关标签:
8条回答
  • 2020-12-01 15:23

    I took HABJAN's solution, which worked well, and converted it to Objective-C. The Objective-C code is as follows:

    bool LineIntersectsLine(CGPoint l1p1, CGPoint l1p2, CGPoint l2p1, CGPoint l2p2)
    {
        CGFloat q = (l1p1.y - l2p1.y) * (l2p2.x - l2p1.x) - (l1p1.x - l2p1.x) * (l2p2.y - l2p1.y);
        CGFloat d = (l1p2.x - l1p1.x) * (l2p2.y - l2p1.y) - (l1p2.y - l1p1.y) * (l2p2.x - l2p1.x);
    
        if( d == 0 )
        {
            return false;
        }
    
        float r = q / d;
    
        q = (l1p1.y - l2p1.y) * (l1p2.x - l1p1.x) - (l1p1.x - l2p1.x) * (l1p2.y - l1p1.y);
        float s = q / d;
    
        if( r < 0 || r > 1 || s < 0 || s > 1 )
        {
            return false;
        }
    
        return true;
    }
    
    bool LineIntersectsRect(CGPoint p1, CGPoint p2, CGRect r)
    {
        return LineIntersectsLine(p1, p2, CGPointMake(r.origin.x, r.origin.y), CGPointMake(r.origin.x + r.size.width, r.origin.y)) ||
        LineIntersectsLine(p1, p2, CGPointMake(r.origin.x + r.size.width, r.origin.y), CGPointMake(r.origin.x + r.size.width, r.origin.y + r.size.height)) ||
        LineIntersectsLine(p1, p2, CGPointMake(r.origin.x + r.size.width, r.origin.y + r.size.height), CGPointMake(r.origin.x, r.origin.y + r.size.height)) ||
        LineIntersectsLine(p1, p2, CGPointMake(r.origin.x, r.origin.y + r.size.height), CGPointMake(r.origin.x, r.origin.y)) ||
        (CGRectContainsPoint(r, p1) && CGRectContainsPoint(r, p2));
    }
    

    Many thanks HABJAN. I will note that at first I wrote my own routine which checked each point along the gradient, and I did everything I could do to maximize performance, but this was immediately far faster.

    0 讨论(0)
  • 2020-12-01 15:27

    Unfortunately the wrong answer has been voted up. It is much to expensive to compute the actual intersection points, you only need comparisons. The keyword to look for is "Line Clipping" (http://en.wikipedia.org/wiki/Line_clipping). Wikipedia recommends the Cohen-Sutherland algorithm (http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland) when you want fast rejects, which is probably the most common scenario. There is a C++-implementation on the wikipedia page. If you are not interested in actually clipping the line, you can skip most of it. The answer of @Johann looks very similar to that algorithm, but I didn't look at it in detail.

    0 讨论(0)
提交回复
热议问题