Jump to content
  • Advertisement
Sign in to follow this  
andy82

Mouse cursor inside rotated rectangle

This topic is 4410 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm looking for a way to determine if the mouse cursor is inside my rotated rectangle. For example I have an rectangle defined by x1,y1,x2,y2 and the rotation angle alpha. Now I want to find out when the mouse cursor is inside that rectangle and when it is outside. The standard 2D collision detection between two rectangles does not work here because the rectangle is rotated. Furthermore, I do not have the rotated rectangle as a gfx bitmap in memory, so I cannot check if the pixels are transparent or opaque either. Anyone got a idea for this case? Thanks in advance! Andy

Share this post


Link to post
Share on other sites
Advertisement
For the purposes of this test, is the mouse cursor represented as a point or a rectangle? (I couldn't quite tell from your post...)

Share this post


Link to post
Share on other sites
You can either rotate the cursor around the same origin that the rectangle is rotated and then run the intersection, or unrotate the rectangle and 'unrotate' the cursor with the rectangle. The important thing here is to bring both the entities into the same space. When the rectangle is rotated and the cursor is not, the rectangle is in world space and the cursor in screen space, even though though they are both views in screen space:


*
* *
* * C
* *
* *
* *
*

TO:
                       C

* * * *
* *
* *
* * * *

The bottom one is the rectangle unrotated and the cursor rotated back to keep it in the right place. You can then do your simple bounds checking.

There are other algorithms for doing this ofcourse.

Dave

Share this post


Link to post
Share on other sites
@jyk: The cursor is just represented as a point.
@Dave: Ok, sounds good, thanks. I'll try to do it that way.

Andy

Share this post


Link to post
Share on other sites
Hmm. I've some problems implementing the version suggested by Dave. Specifically, I don't know how to check the collision after rotating the pointer coordinates.

Here's what I do (pseudo-code):


drawrect(0, 0, 100, 100, 45) ; 100x100 rect at 0:0 - by rotated 45 degrees

function onmousemove(mousex, mousey)

angle = (360 - 45) * PI / 180

; move to same origin as rectangle
mousex = mousex - 100 / 2
mousey = mousey - 100 / 2

; rotate
rx = mousex * cos(angle) - mousey * sin(angle)
ry = mousey * sin(angle) + mousey * cos(angle)

; move back
rx = rx + 100 / 2
ry = ry + 100 / 2

endfunction



Now the question is: How do I check the collision between rx,ry and the rotated rectangle? I've problems imagining the solution... I mean, now I have the rotated mouse cursor coordinates rx,ry but I still do not see how I could use them to check if they're inside the rotated rectangle which looks like this in 45 degrees.


*
* *
* *
* *
* *
* *
*

Share this post


Link to post
Share on other sites
You shouldn't be thinking of this rotation as a straightforward rotation in 2-space, but as a coordinate transformation. Imagine the image of a horizontal line (moving your mouse from side to side) under this transformation: it is a (generally) diagonal line parallel to two of the sides of the rectangle. Similarly, vertical mouse movenment will transform to be parallel to the other two sides.

So the transformation has aligned the two coordinate systems, and hence the intersection test is simple. Allow me to generalise your pseudocode somewhat:

drawrect(RECT_L, RECT_T, RECT_R, RECT_B, RECT_ORIENTATION) ; (RECT_R - RECT_L)x(RECT_B - RECT_T) rect at (RECT_L, RECT_T) rotated by RECT_ORIENTATION degrees clockwise

bool IsMouseInRect(mousex, mousey)

angle = (360 - RECT_ORIENTATION) * PI / 180

; move to same origin as rectangle
mousex = mousex - (RECT_R + RECT_L) / 2
mousey = mousey - (RECT_B + RECT_T) / 2

; rotate
rx = mousex * cos(RECT_ORIENTATION) - mousey * sin(RECT_ORIENTATION)
ry = mousey * sin(RECT_ORIENTATION) + mousey * cos(RECT_ORIENTATION)

; move back
rx = rx + (RECT_R + RECT_L) / 2
ry = ry + (RECT_B + RECT_T) / 2

if (rx > RECT_R) return false
if (rx < RECT_L) return false
if (ry > RECT_B) return false
if (ry < RECT_T) return false

return true
endfunction


Regards
Admiral

Share this post


Link to post
Share on other sites
Regarding my suggestion, the idea is to rotate the rectangle so that it is squared up, but with it you rotate the cursor position, around the same origin as the rectangle. This is keeping the cursor in the same position relative to the rectangle. You can then do regular bounds testing.

Dave

Share this post


Link to post
Share on other sites
Thanks guys. It's working now. I'm doing it the way Dave suggested, i.e. unrotate the rectangle and the cursor coordinates, then check if the two things collide.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!