Mouse hit test/know when mouse is over something.

Started by
16 comments, last by szecs 14 years, 3 months ago
Hopefully the answer to this will be fairly simple. I'm using Win32 and Direct2D and I need to know when the mouse is over something so I can move/rotate it only when the mouse is over it and is down. I know how to rotate/move stuff and how to tell when the mouse is down and up, all I need to know is when it's over something, like a simple square or circle. Could someone tell me how that is done?
Advertisement
Catch the WM_MOUSEMOVE event. The coordinates of the mouse are accessed via LOWORD(lParam) and HIWORD(lParam) respectively. For the square, you can check if the mouse is over it with 4 'if' statements. For the circle you can use the distance formula;
if((mX-cX)^2 + (mY-cY)^2 <= circleRadius^2)
// Mouse in circle
What if I had 50+ items that can be selected by the mouse. Surely it can't be efficient to check if the mouse is over every single one of them every-time the mouse moves?
Quote:Surely it can't be efficient to check if the mouse is over every single one..

Why not? The number of checks you make will just increase linearly with the number of items. It will still be a very quick operation, particularly if you code the if statements correctly.

When checking things like mouseX < boxMinX OR mouseX > boxMaxX OR .., the if statement will "abort" on the first true comparison and the remainder of the checks for that item won't be performed.

If you want to get fancy, you could use some sort of quadtree (or similar) but, unless you have many, many items, simple bounding box checks will be faster.

By the way, for rectangular items you can use PtInRect. Probably won't be any faster but I seriously doubt you'll notice any change in performance.

[Edited by - Buckeye on December 27, 2009 10:35:26 AM]

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

You can divide the screen into sections and record which object is in which. Then you can determine in O(1) which section the mouse is in, and thus cut down on the number of objects that need to be checked.
That's what you'd need to do if you had, say, 10 million objects to check against.
One thing I was experimenting with using GDI+ and drawing to a panel control (C#) was how to catch the MouseDown, ~Move, etc. No matter which way I looked, all the suggestions pointed towards using a 'foreach' loop to determine the mouse coordinates. Only problem is that the foreach cannot keep up with fast movement of the mouse.

I published static events in the panel that each GDI+ object (Rectangle, etc.) then subscribed to (if it cared). Then, each of my GDI+ objects were made aware of mouse events. I was even told that this was effectively no different than a 'foreach' loop, but performance differences between the two implementations tells a different story.

I know there may be some differences between Direct2D and GDI+, but this solution shouldn't be affected by those differences - at least I wouldn't think so. I, admittedly, am not experienced with any graphics other than GDI+ (yet).
Quote:Original post by taz0010
Catch the WM_MOUSEMOVE event. The coordinates of the mouse are accessed via LOWORD(lParam) and HIWORD(lParam) respectively. For the square, you can check if the mouse is over it with 4 'if' statements. For the circle you can use the distance formula;
if((mX-cX)^2 + (mY-cY)^2 <= circleRadius^2)
// Mouse in circle


A little OT, but: How well do the WM_MOUSEMOVE, ~DOWN, etc. port to other platforms?
Quote:Original post by ddboarm
A little OT, but: How well do the WM_MOUSEMOVE, ~DOWN, etc. port to other platforms?

Assuming you mean mac, linux etc. It's part of the Win API so not very well unless they're using WINE or something.

Looks like I'll be doing the loop check for each object every time I move the mouse then.
Thanks for the help, I'll reply later to say if it's working good or not.
How is this going to work with transforms? My movement is going to be done by changing the positions stuff is to be drawn, so I'll know where my objects are after moving them which is fine for this. But my rotations are going to done with a rotate transformation, so how will I know their locations then?

Also a bit off-topic. Do games have to do the same thing? So like in menu's etc. it has do use this process of checking every single item if the mouse is over it every time the mouse moves? Or is the stuff supplied by OpenGL and Direct3D?
Why is it so unbelievable that checking is so fast, that you don't have to worry about it?
It will be much-much slower to draw the items.

And why would you rotate the items?

This topic is closed to new replies.

Advertisement