Sign in to follow this  
Phoresis

Rotating a polygon around a point.

Recommended Posts

I'm trying to rotate a 2d polygon around a point by working out it's current angle in relation to the point and then adding one to that angle, and then setting the polygon's x and y position to correspond to the new angle. The trouble is the shape rotates around the point while getting closer and closer until it stops. I don't want it to get any closer.

//center co-ordinates of 2d polygon
int xpos = items[0]->getX();
int ypos = items[0]->getY();

//vector from point to center of polygon	
int d = sqrt((double)((x-xpos)*(x-xpos)) + ((y-ypos)*(y-ypos)));

//current angle between vector and horizontal
float theta = atan2((float)ypos - y, (float)x - xpos);
float angle = theta * (180 / 3.14159);

const float DEG2RAD = 3.14159/180;
		
angle = -angle -180;
//add one to angle
angle++;
float degInRad = angle*DEG2RAD;
//set x and y position
items[0]->setPosition((x + cos(degInRad)*d), (y + sin(degInRad)*d));

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just out of interest, if you set d at the start to be a constant distance, does it work?

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Just out of interest, if you set d at the start to be a constant distance, does it work?


hrmm yeah that worked. not sure why though.

Share this post


Link to post
Share on other sites
The biggest problem I see is that you're storing the distance in an integer, which automatically truncates the result of the square root. Combined with floating-point imprecision this could easily cause your values to degenerate. You want to do as much as your mathematics using floating-points as possible, and only convert to integers when it's absolutely necessary (i.e. transforming into screen-space). It's also possible that the floating-point imprecision alone could give you problems, in which case instead of calculating the distance each frame and trying to maintain it, you chose one beforehand (a constant as the AP suggested).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Yeah that was the point I was making Phoresis. Thanks for answering as I had to leave work and couldnt check back

Anonymous Poster ;)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by Zipster
The biggest problem I see is that you're storing the distance in an integer, which automatically truncates the result of the square root. Combined with floating-point imprecision this could easily cause your values to degenerate. You want to do as much as your mathematics using floating-points as possible, and only convert to integers when it's absolutely necessary (i.e. transforming into screen-space). It's also possible that the floating-point imprecision alone could give you problems, in which case instead of calculating the distance each frame and trying to maintain it, you chose one beforehand (a constant as the AP suggested).


Thanks for your help. I've discovered another problem that I can't explain also. When the radius is particularly short the item seems to stop rotating near the bottom of the circle.

Share this post


Link to post
Share on other sites
easier way to do it.:


int deg=0;
float distance=600;
const float piover180 = 0.0174532925f;

deg++;

if (deg > 360)
deg-=360;
if (deg < 0)
deg+=360;

polyx=sin(deg*PIover180)*distance;
polyy=cos(deg*PIover180)*distance;









easier to understand angle function

float GetAngl(float x1,float x2,float y1,float y2) //target, source, target, source
{
float Angle=0;
Angle=(atan2(x1-x2,y1-y2) * 57.29578049f) //(57....=180overpie)
if (Angle < 0)
Angle+=360.0f; //Fix Atan lameness (makes -180 and 180 into 0 - -360)
return Angle;
}






[Edited by - ViperG on March 8, 2007 1:44:10 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by ViperG
easier way to do it.:

*** Source Snippet Removed ***

easier to understand angle function
*** Source Snippet Removed ***


your angle function looks better, but I'm not sure about the first piece of code, as the distance needs to be in relation to the point i'm rotating about and it's also important that rotation starts from the current angle of the polygon with relation to the point, for various reasons.

Share this post


Link to post
Share on other sites

float GetDis(float x1,float y1,float x2,float y2)
{

Distance=(float)sqrt(((float)pow((x1-x2),2))+((float)pow((y1-y2),2)));
return (Distance);
}

Share this post


Link to post
Share on other sites
So basicly all you trying to do is do this:

get angle from a point to polygone
get the distance also
then update the x,y position based off the roation from the center point.

all you need to do is

GetDistance
GetAngle

thats all the info you need. then just do the math to update it

newpolyx=centerx+sin(angle*PIover180)*distance;
newpolyy=centery+cos(angle*PIover180)*distance;

then just add 1 to the angle, and redo ^^

or you could get distance and angle again, but that would be a waste of processing power. (if the distance never changes, why check it, and if you are only adding 1 to the angle, you always will know what the angle is from now on, no need to check it again)

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by ViperG
So basicly all you trying to do is do this:

get angle from a point to polygone
get the distance also
then update the x,y position based off the roation from the center point.

all you need to do is

GetDistance
GetAngle

thats all the info you need. then just do the math to update it

newpolyx=centerx+sin(angle*PIover180)*distance;
newpolyy=centery+cos(angle*PIover180)*distance;

then just add 1 to the angle, and redo ^^

or you could get distance and angle again, but that would be a waste of processing power. (if the distance never changes, why check it, and if you are only adding 1 to the angle, you always will know what the angle is from now on, no need to check it again)


Hrmm. Not sure if I did something wrong, but all that does now is wobble the shape back and forth in a blur.



//start function
if (items[0] != NULL)
{
//center co-ordinates of 2d polygon
int xpos = items[0]->getX();
int ypos = items[0]->getY();

//float d = getDistance(x, xpos, y, ypos);
float deg = getAngle(ypos,y,xpos,x);

const float PIover180 = 0.0174532925f;

deg++;

if (deg > 360)
deg-=360;
if (deg setPosition(polyx, polyy);
}
//end function

float Pool::getDistance(float x1,float y1,float x2,float y2)
{
float distance=(float)sqrt(((float)pow((x1-x2),2))+((float)pow((y1-y2),2)));
return (distance);
}


float Pool::getAngle(float x1,float x2,float y1,float y2) //target, source, target, source
{
float angle = 0.0;
angle=(atan2(x1-x2,y1-y2) * 57.29578049f);
if (angle

Share this post


Link to post
Share on other sites
damn wasn't logged in. sorry here is the code.



if (items[0] != NULL)
{
//center co-ordinates of 2d polygon
int xpos = items[0]->getX();
int ypos = items[0]->getY();

//float d = getDistance(x, xpos, y, ypos);
float deg = getAngle(ypos,y,xpos,x);

const float PIover180 = 0.0174532925f;

deg++;

if (deg > 360)
deg-=360;
if (deg < 0)
deg+=360;

float polyx = x + sin(deg*PIover180)*50;
float polyy = y + cos(deg*PIover180)*50;


items[0]->setPosition(polyx, polyy);
}

Share this post


Link to post
Share on other sites
most likely your computer is rendering it so fast your not seeing it.

change the degree/angle to a float, and increment it by something like 0.00001f instead of 1

I also edited my angle function so you might want to update yours.

Share this post


Link to post
Share on other sites
Quote:
Original post by ViperG
most likely your computer is rendering it so fast your not seeing it.

change the degree/angle to a float, and increment it by something like 0.00001f instead of 1

I also edited my angle function so you might want to update yours.


nope its not that. does the same after modifying it as you said. I was pretty damn close with the code I had, only for the fact that for some reason small distances broke it.

Ah well nevermind. Thanks for the help anyway.

Share this post


Link to post
Share on other sites
I've just had a thought. It could be something to do with the atan2 function requiring a vector (the distance from the point of rotation to the centre of polygon) of a minimum length for it to work?

Share this post


Link to post
Share on other sites
a quick way to test your code is to plug in numbers you know what the result will be.

so if you deg is 0 and distance is 50, that is straight up 50 units.

if you deg is 90, that is 50 units over on x.

if you deg is 180, that is 50 units down on -y

if you deg s 270, that is 50 units over on -x

so plug those in and make sure your polygon is in the right spot relative to your point.

Share this post


Link to post
Share on other sites
well those values produce the correct results with what I had. After some more testing though, I've got a better idea of what is happening. For certain radiuses the polygon stops rotating after it completes one revolution (360 degrees) but for radiuses greater than those, it keeps going. Now I just have to figure out why.

Share this post


Link to post
Share on other sites
using pushmatrix and popmatrix might help you out.

if your distance is staying the same but it keeps growing or shrinking when you rending it it's probably a translation problem so pushmatrix and popmatrix would solve that.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this