Point within rectangle problem...

Started by
4 comments, last by RegularKid 15 years, 2 months ago
Hi! I'm currently writing some code to detect if a given point is within a non-axis aligned rectangle ( to see if I clicked on the rect ). Here's what I have so far:

VEC diff;
diff.x = xMouse - x;
diff.y = yMouse - y;

VEC boxAxisX, boxAxisY;

boxAxisX.x = COS( curRotation );
boxAxisX.y = SIN( curRotation );
boxAxisY.x = -boxAxisX.y;
boxAxisY.y = boxAxisX.x;

float aax = VEC::Dot(&diff, &boxAxisX);
float aay = VEC::Dot(&diff, &boxAxisY);

if( abs( aax ) < rectHalfWidth && abs( aay ) < rectHalfHeight )
{
	return true;
}

return false;

Just FYI, my COS and SIN macros takes degrees rather than radians. Anyways, that works just fine. However, now I'm adding functionality for rotating my rectangle around a specified pivot point rather than it's origin. In order to do this, I have changed my rectangle render code to look like this:

glPushMatrix();
glTranslatef( xRect, yRect );
glRotatef( -curRotation, 0.0f, 0.0f, 1.0f );
glTranslatef( xPivot, yPivot, 0.0f );

// Now render my rectangle with no rotation at the origin...

glPushMatrix();

So, this all works great, except once the rectangle has a pivot point other than it's origin and is rotated about that new pivot point, my detection code to see if I have clicked on it no longer works ( of course ). I'm trying to wrap my head around what I need to change in order to get it working again. I need help with the math :) Any help would be great! Thanks!
Advertisement
I haven't really gone over your code with a fine tooth comb but from your description it sounds like you're not taking the pivot point into account when you're calculating whether the point is inside the rectangle. So basically when you're trying to detect whether the point is inside the rectangle you're assuming that the object has been rotated about the origin of the object as oppose to being offset by the pivot. You'll need to take the pivot point into account when determining where the user has clicked.
Right, it's something to do with taking into account the pivot point as well as the current angle.

I actually should call xPivot and yPivot something else because here's what happens:

Ex. 1:x=100.0fy=100.0fxPivot=0.0fyPivot=0.0f;curRotation=45.0fOutput: My rectangle is rendered at ( 100, 100 ) with a rotation of 45 degrees about its center point ( which is 100, 100 ).



Ex. 2:x=100.0fy=100.0fxPivot=50.0fyPivot=0.0f;curRotation=0.0fOutput: My rectangle is rendered at ( 150, 100 ) with no rotation since the xPivot pushed the rectangle 50 units to the right.



Ex. 3:x=100.0fy=100.0fxPivot=50.0fyPivot=0.0f;curRotation=45.0fOutput: My rectangle is rendered at ( 150, 100 ) with a rotation of 45 degrees about the object center ( which is at 100, 100 ).


So really what happens when I render is translate out to the x,y position, then I rotate the coordinate system by the current rotation, then translate again by the pivot amount.

In ex1 and ex2 when either there is no rotation or there is no pivot offset, it's easy to find out if I clicked on the rectangle. The problem comes in when there is both a pivot offset and a rotation. That's where I'm struggling to figure out the math.

Any ideas?
First part, hope you're not really calling glPushMatrix without a glPopMatrix.
First and a half, the first call to glTranslatef has no z parameter

Second, if I understand it correctly, your 'point in rotated quad' part is ok, it works fine, and you're having problems with rendering. If it's that, change the translation order, first the pivot, then the rect position
First: Yup, I'm not looking for speed here so the push matrix stuff works.
First 1/2: Yea, sorry. typo...

Second: Nope, rendering is fine ( the last post was just going over the rendering to explain how everything was working ). The problem I'm having is determining if a mouse point is within the rectangle given the way I'm doing the rotation / pivot rendering ( as shown in the last post ). :)
Ah ha!

Ok, I figured it out. So, I had to change my detection code to adjust the "diff" value by adding in the pivot offset rotated by the current rotation. The detection code now looks like this:

VEC diff;VEC pivotOff;pivotOff.x = xPivot;pivotOff.y = yPivot;pivotOff.RotateAroundOrigin( curRotation );diff.x = xMouse - x;diff.y = yMouse - y;VEC boxAxisX, boxAxisY;boxAxisX.x = COS( curRotation );boxAxisX.y = SIN( curRotation );boxAxisY.x = -boxAxisX.y;boxAxisY.y = boxAxisX.x;float aax = VEC::Dot(&diff, &boxAxisX);float aay = VEC::Dot(&diff, &boxAxisY);if( abs( aax ) < rectHalfWidth && abs( aay ) < rectHalfHeight ){	return true;}return false;


Thanks!

This topic is closed to new replies.

Advertisement