2

In C++, in 2D, how can I find the point of intersection between a ray (defined by one point and a direction-vector) and a rectangle (defined by x, y, w, h)?

                   ________
                  |        |
                  |        |
------------------|        |
                  |________|

This is for a none frame based simulation, so I am not quite sure how to tackle the problem.

Ben
  • 15,938
  • 19
  • 92
  • 138

2 Answers2

5

Rectangle in 2D = 4 line segments.

So your question actually is: How do I determine whether or not two lines intersect, and if they do, at what x,y point?

You calculate intersection for all line segments and than choose closes one based on |A-Xi|, where A is vector origin, Xi is intersect point and || represents length of vector (sqrt(A.x*Xi.x + A.y*Xi.y), you don't actually need to use sqrt() if you just need to compare distances and don't need exact number).

Community
  • 1
  • 1
Vyktor
  • 20,559
  • 6
  • 64
  • 96
  • The linked question is subtly different; lines are not line segments. Also, this is apparently a special case where the rectangle isn't angled w.r.t. the major axis, i.e it's not a ♢ – MSalters Feb 03 '12 at 13:57
  • @MSalters Maybe it's not the exact answer he needs but I think thinking of rectangle as 4 lines is definitely the way to go in 2D (as long as he don't need internal coordinates just boundary/outside intersect point) and this is great place for him to start. If you have link to better solution I'll be glad to update my answer. – Vyktor Feb 03 '12 at 14:03
  • @MSalters and if my dictionary is right `line = infinite line segment` (or if you want `line segment = line with boundaries`) and than the check is really easy: `if( (((p1.x >= x.x) && (p2.x <= x.x)) || ((p1.x <= x.x) && (p2.x >= x.x))) && (((p1.y >= x.y) && (p2.y <= x.y)) || ((p1.y <= x.y) && (p2.y >= x.y)))` (I hope I got indexes right), where the `p1` and `p2` are end points of rectangle line and `x` is intersection point. – Vyktor Feb 03 '12 at 14:08
  • Oh, this solution will work; it's just not the most efficient. – MSalters Feb 07 '12 at 09:28
  • @MSalters if you have any enhancements or your own solution I'll be glad to edit or read your answer, because I can't imagine anything faster right now. Maybe when you're using parametric line definition such as: `y = px + q` but I'm afraid it would be the same... – Vyktor Feb 07 '12 at 10:33
2

Your ray is defined by y=px+q. Defining your box as {R,B,L=R+w,T=B+h}, that means the right edge is intersected at y=pR+q; the left edge at y=pL+q, the bottom at x=(B-q)/p and the top at x=(T-q)/p.

To check that these intersections are with the line segments defining your box, you'll have to check that R <=x && x <= L and B <= y && y <= T respectively.

MSalters
  • 173,980
  • 10
  • 155
  • 350