detect mouse position

Im trying to detect when my mouse is over a item.
i can get it working if its a square shape an stuff.
 
(LOWORD(lParam) > 133) && (LOWORD(lParam) < 154) && (HIWORD(lParam) > 0) && (HIWORD(lParam) < 21)


but how would i detect if its over the white spot in this image?
http://oi43.tinypic.com/kbc20i.jpg

i just drew a simple shape i need to detect from more edges but i just want a idea on how to do it thanks.
Last edited on
There are a number of ways to do this. Most of them involve some basic linear algebra.

Since the shape is convex, you have more options available to you. The way I'd do it is to form lines connecting the four corners of that rectangle. Make sure the lines are all oriented so they go clockwise:

Lower Left - Upper Left
Upper Left - Upper Right
Upper Right - Lower Right
Lower Right - Lower Left


You can then use the perpendicular dot product to determine whether or not a point is to the "right" or to the "left" of a given line.

Since all lines are oriented clockwise, in order for the point to be inside the shape... it must be to the "right" of all 4 lines. Therefore you just check the point against all 4 lines and if it is to the left of any of them, you know it is outside the area.

Perpendicular dot product is pretty simple. Assuming you have a 'Vector' or 'Point' class (that has x,y components):

inline double perpDot(const Vector& a, const Vector& b) { return (a.y*b.x) - (a.x*b.y); }

perpDot gives you sin(theta) * length(a) * length(b) where 'theta' is the angle between vectors a,b.

This will be 0 if 'a' and 'b' are parallel. It will be > 0 if 'b' is clockwise of 'a' (assuming +Y is up), or < 0 if 'b' is ccw of 'a'.

Since +Y is down in your case, this will be reversed (>0 means 'b' is ccw. <0 is cw)

To apply:

1
2
3
4
5
6
7
bool isPointCwOfLine(const Vector& line1, const Vector& line2, const Vector& pt)
{
    Vector a = line2 - line1;
    Vector b = pt - line1;

    return (perpDot(a,b) <= 0);
}




EDIT:

Another option (if you don't have a convex shape) is to form a ray from the target point, and count how many sides of the shape that ray intersects. Even number = point is outside the shape, odd number = point is inside the shape.

The math to do this efficiently is a little more involved so I won't get into it here. The above solution is easier.
Last edited on
thanks for the help.
lol seems hard im not good with maths

what i have is a image i use as a button but i would like to detect if mouse click is in part of the image. its not a normal shape.

so i thought is there away to get the pos of the mouse click on the displayed image an then compare that with a image in resource thats a image mask.
so that it checks if the mouse click clicked at position of a white pixel?

1
2
3
4
HBITMAP Img_ON_MASK	= NULL;
HBITMAP Img_ON		= NULL;
Img_ON_MASK = LoadBitmap(hInstance, MAKEINTRESOURCE(IMG_ON_MASK));
Img_ON = LoadBitmap(hInstance, MAKEINTRESOURCE(IMG_ON));
That's certainly possible.

The easiest way to do that is to put the mask image in a DC and call GetPixel to retrieve the RGB value of the pixel at a given coord.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// do once at setup
HDC mdc = CreateCompatibleDC(NULL);
HBITMAP mask = LoadImage( ... );  // note LoadBitmap is deprecated, and you
   // should use LoadImage instead, IIRC
HBITMAP bmpold = (HBITMAP)SelectObject(mdc,mask);


// when you want a pixel
COLORREF pixel = GetPixel( mdc, x, y );
   // (check 'pixel' here)


// to clean up (do once at shutdown)
SelectObject(mdc, bmpold);
DeleteObject(mask);
DeleteDC(mdc);



Of course this is if you need pixel-perfect detection, which usually is not necessary. It's often easier to do bounding-box or similar collision detection.
is there any examples of bounding-box or collision detection?
to work on any shape i like?
Well... bounding boxes only work on boxes.

Depending on what you're doing... that might be good enough. The user usually won't be able to tell whether or not collision detection is pixel-perfect, so you can often just create a box that approximates the area of the object.

But again it depends. I'm not really sure what it is you're going for, I'm just throwing out ideas.
well my button is part of a image an its a irregular shape
so thats why i thought about the image map to do it that way but didnt know if thats the best way

how come you needed to
SelectObject(mdc, bmpold);
at clean up?
i understand the others
Last edited on
Topic archived. No new replies allowed.