# Manual Rotation of vertices about center of shape

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

## Recommended Posts

Reposting, cos I've tried loads of stuff and really can't figure this out. It's driving me nuts. I want to manually rotate each vertex of a 2d rectangle around the center of the shape, without using glRotatef. I can rotate a point around another point fine, but whatever I try I can't seem to rotate the four corners of the shape around a center point. My vertices are declared as follows:
	vertices[0][0] = x - (width / 2);
vertices[0][1] = y + (height / 2);

vertices[1][0] = x + (width / 2);
vertices[1][1] = y + (height / 2);

vertices[2][0] = x + (width / 2);
vertices[2][1] = y - (height / 2);

vertices[3][0] = x - (width / 2);
vertices[3][1] = y - (height / 2);

I used this code to rotate a point around another point:
void orbit()
{
const float DEG2RAD = (float) 3.14159/180;
angle = angle + (1.0f);
for(int i = 0; i < 4; i++)
{
}
}


##### Share on other sites
Phoresis,

Do you mean that you want to rotate the object about its centre?. If so then,

(1) Translate your object back into LOCAL co-ordinate space.

Your object is at (x, y) then,

vertices[0][0] -= x;
vertices[0][1] -= y;

vertices[1][0] -= x;
vertices[1][1] -= y;

vertices[2][0] -= x;
vertices[2][1] -= y;

vertices[3][0] -= x;
vertices[3][1] -= y;

(2) Perform your rotation in LOCAL space

float fx = vertices[0][0];
float fy = vertices[0][1];

vertices[0][0] = fx * cosf(angle) - fy * sinf(angle);
vertices[0][1] = fx * sinf(angle) + fy * cosf(angle);

fx = vertices[1][0];
fy = vertices[1][1];

vertices[1][0] = fx * cosf(angle) - fy * sinf(angle);
vertices[1][1] = fx * sinf(angle) + fy * cosf(angle);

// similar for the remaining vertices
NOTE: (angle) must is in rads too ;)

(3) Translate object back into WORLD space

vertices[0][0] += x;
vertices[0][1] += y;

vertices[1][0] += x;
vertices[1][1] += y;

vertices[2][0] += x;
vertices[2][1] += y;

vertices[3][0] += x;
vertices[3][1] += y;

This also applies to 3D objects too, but you will have to factor in the z-ordinate.

Hope this works

MAMEman.

##### Share on other sites
just to clarify, do i translate to local co-ordinate space after I have declared the following:

vertices[0][0] = x - (width / 2);

vertices[0][1] = y + (height / 2);

vertices[1][0] = x + (width / 2);

vertices[1][1] = y + (height / 2);
etc

or instead of? Just want to make sure I get exactly what you mean.

##### Share on other sites
Yes, I'm assuming that your (x, y) co-ordinates define the centre position of your object in WORLD space. Hence vertices[0][0] -> vertices[3][1] should already be in WORLD space. :)

##### Share on other sites
Cool. Thanks this seems to work, but it also seems to get faster and faster and faster.

void orbit(){	const float DEG2RAD = (float) 3.14159/180;	angle = angle + (0.01f);	if (angle > 360) angle -= 360;	if (angle < 0) angle += 360;	float degInRad = angle*DEG2RAD;	for (int i = 0; i < 4; i++)	{		vertices[0] -= x;		vertices[1] -= y;	}	for (int i = 0; i < 4; i++)	{				float fx = vertices[0];		float fy = vertices[1];				vertices[0] = fx * cosf(degInRad) - fy * sinf(degInRad);		vertices[1] = fx * sinf(degInRad) + fy * cosf(degInRad);	}	for (int i = 0; i < 4; i++)	{		vertices[0] += x;		vertices[1] += y;	}}

I call this method every time the sqaure is drawn. Yeah I know I don't need to keep repeating the for loop, just wanted to split up the logic for now.

##### Share on other sites
Looking at your code it appears that your angle gets bigger and bigger. Therefore your rotation will get bigger and bigger. Just make your angle variable constant, for example 0.5f. This should take care of that. But this may run faster/slower on another system because you are not using timer based rotation methods ;). However for your needs the initial suggestion should work fine.

Regards,

MAMEman.

##### Share on other sites
Ah right I'm starting to understand now. What if I wanted it rather than rotate to just set it at the angle?

##### Share on other sites
Did the initial suggestion work? (setting a constant). I'm not sure what you meant in the last post please carify.

##### Share on other sites
setting a constant works in that the shape keeps rotating without getting faster or slower, which is good. However what I wanted to achieve initially was a method that just sets the shape to a specified angle, rather than rotating it constantly. So if I gave an angle of 45 degrees then the method would set the angle of the shape to 45 degrees and it would stay at 45 degrees until the method was called again with a different angle. Hope this clarifies it.

##### Share on other sites
OK. How about when you initialize the object that you want set an initial angle for, you do something like this:

void InitializeVertices(float angle, const float px, const float py)
{

// initialize LOCAL co-ordinates of the object

vertices[0][0] = -(float)(width / 2);
vertices[0][1] = (float)(height / 2);

vertices[1][0] = (float)(width / 2);
vertices[1][1] = (float)(height / 2);

vertices[2][0] = (float)(width / 2);
vertices[2][1] = -(float)(height / 2);

vertices[3][0] = -(float)(width / 2);
vertices[3][1] = -(float)(height / 2);

// perform the initial rotation (as per (2) in my initial post)
// not forgetting to convert (angle) to rads (if not already done so)

// put object into WORLD space (as per (3) in my initial post)
// use parameters px and py to do the translation

}

Now when you want to apply a rotation to the object (for example as the result of a key push) then,

void RotateVertices(float angle)
{
// put your rotation code in here

// note: that when you apply your rotation then angle will be FROM your current angle.
// for example if you initially rotate your object say 90deg and then apply a 45deg rotation your object will have rotated 135deg total from the +ve x-axis.
}

##### Share on other sites
I think you misunderstood me, either that or I'm just being dumb (most likely), all I want to do is scrap the rotation and just have the set angle, but the code I've got at the moment doesn't just set an angle, it constantly rotates the square .

I know these two lines need altering:

but again I'm stuck with the math.

So, to re-iterate, the shape starts of with no rotation. I then call my rotate method and the shape is redisplayed, rotated to whatever angle I wanted. This would be the same as calling glRotatef on the shape once.

##### Share on other sites
Yep I guessed right. I think I am being dumb. Basically all I need to do is account for the fact that the angle is added onto the current angle of the shape.

##### Share on other sites
The problem with my solution is that the vertex data is constantly being updated (correct?). So what you will need to do is store the initial WORLD co-ordinates of your object and work with those. Looking at you code you may want to do it this way.

void orbit(float angle)
{
const float DEG2RAD = (float) 3.14159/180;

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

for (int i = 0; i < 4; i++)
{
vertices[0] = initial_vertex[0];
vertices[1] = initial_vertex[1];

vertices[0] -= x; // move into local space
vertices[1] -= y;
}

for (int i = 0; i < 4; i++)
{

float fx = vertices[0];
float fy = vertices[1];

vertices[0] = fx * cosf(degInRad) - fy * sinf(degInRad); // rotate point
}

for (int i = 0; i < 4; i++)
{
vertices[0] += x; // move back to world space
vertices[1] += y;
}
}

BEWARE: If you perform a translation operation then you will need to update initial_vertex as well as vertices. Hope this solves it.