PDA

View Full Version : rotating object



pbivens
07-07-2013, 09:49 PM
I am trying to rotate a space ship like in asteroids here is the code I am working on.


void DrawShip(GLfloat position_X,GLfloat position_Y, GLfloat position_Z, GLfloat rotation,GLfloat color)
{
glPushMatrix();
glTranslatef(position_X, position_Y, position_Z);
glRotatef(rotation,0.0f,0.0f,1.0f);
glColor3f(color,0.0f,0.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f,-0.25f,0.0f);
glVertex3f(-0.25f,-0.5f,0.0f);
glVertex3f(-0.5f,-0.5f,0.0f);
glVertex3f(-0.0f,0.5f,0.0f);
glVertex3f(0.5f,-0.5f,0.0f);
glVertex3f(0.25f,-0.5f,0.0f);
glVertex3f(0.0f,-0.25f,0.0f);
glEnd();
glPopMatrix();
}

I am able to get the ship to move up and down but I want it to follow its nose after rotation.

tonyo_au
07-07-2013, 10:59 PM
You should rotate before you translate.

marcClintDion
07-07-2013, 11:31 PM
Phil, I recognize that ship...funny. I have the current and full code listing that you posted on gameDev, I'll be taking a look at it right away. I'm pretty sure what I've already posted will do the trick but it still has to be put into the appropriate place. There is now a third page on that thread. I've made a slight change in how color is being handled.


You should rotate before you translate.

Doing that will offset the ship from it's pivot point, when you rotate it, the ship will orbit as if it's on a swing arm.

GClements
07-08-2013, 12:06 AM
I am able to get the ship to move up and down but I want it to follow its nose after rotation.
If you want to move the ship (or fire bullets) in the direction it's facing, you need your own polar-to-cartesian conversion:


x = magnitude * cos(angle)
y = magnitude * sin(angle)

This assumes that angle is counter-clockwise with zero at the positive X axis. Bear in mind that the trigonometry functions in the standard C library use radians while glRotate() uses degrees.

While it's possible to abuse OpenGL functions to do this for you (using glRotate() and glGet(GL_MODELVIEW_MATRIX)), doing it yourself is trivial and far more efficient (glGet() is expensive).

FWIW, the inverse conversion is:


magnitude = sqrt(x*x+y*y)
angle = atan2(y, x)

Conversion between polar and cartesian coordinates is probably the only trigonometry you'll ever need for graphics; everything else is normally done using vectors.

pbivens
07-08-2013, 03:40 PM
cool thanks marc again.

pbivens
07-14-2013, 03:56 PM
well I have tried several things but I am still stuck. Here is the code I am working on.


void DrawShip(GLfloat position_X,GLfloat position_Y, GLfloat position_Z, GLfloat rotation,GLfloat color)
{
glPushMatrix();
glRotatef(rotation,0.0f,0.0f,1.0f);
glTranslatef(position_X, position_Y, position_Z);
glColor3f(color,0.0f,0.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f*cos(angle)+0.25f*sin(angle),0.0f*s in(angle)-0.25f*cos(angle),0.0f);
glVertex3f(-0.25f*cos(angle)+0.5f*sin(angle),-0.25f*sin(angle)-0.5f*cos(angle),0.0f);
glVertex3f(-0.5f*cos(angle)+0.5f*sin(angle),-0.5f*sin(angle)-0.5f*cos(angle),0.0f);
glVertex3f(0.0f*cos(angle)-0.5f*sin(angle),0.0f*sin(angle)+0.5f*cos(angle),0. 0f);
glVertex3f(0.5f*cos(angle)+0.5f*sin(angle),0.5f*si n(angle)-0.5f*cos(angle),0.0f);
glVertex3f(0.25f*cos(angle)+0.5f*sin(angle),0.25f* sin(angle)-0.5f*cos(angle),0.0f);
glVertex3f(0.0f*cos(angle)+0.25f*sin(angle),0.0f*s in(angle)-0.25f*cos(angle),0.0f);
glEnd();
glPopMatrix();
}

GClements
07-15-2013, 05:57 AM
well I have tried several things but I am still stuck. Here is the code I am working on.
There was nothing wrong with your original code. You just need to set position_X and position_Y correctly.

For an asteroids clone, the update function should look something like:


double angle = (90 - rotation) * M_PI / 180;
speed_X += acceleration * cos(angle);
speed_Y += acceleration * sin(angle);
position_X += speed_X;
position_Y += speed_Y;

pbivens
07-16-2013, 09:59 PM
If you want to move the ship (or fire bullets) in the direction it's facing, you need your own polar-to-cartesian conversion:


x = magnitude * cos(angle)
y = magnitude * sin(angle)

This assumes that angle is counter-clockwise with zero at the positive X axis. Bear in mind that the trigonometry functions in the standard C library use radians while glRotate() uses degrees.

While it's possible to abuse OpenGL functions to do this for you (using glRotate() and glGet(GL_MODELVIEW_MATRIX)), doing it yourself is trivial and far more efficient (glGet() is expensive).

FWIW, the inverse conversion is:


magnitude = sqrt(x*x+y*y)
angle = atan2(y, x)

Conversion between polar and cartesian coordinates is probably the only trigonometry you'll ever need for graphics; everything else is normally done using vectors.

here is my new code


void update(int value)
{
double magnitude = sqrt(ship_01_POSITION_X * ship_01_POSITION_X + ship_01_POSITION_Y * ship_01_POSITION_Y);
double angle = atan2(ship_01_POSITION_Y,ship_01_POSITION_X);
ship_01_POSITION_X = magnitude * cos(angle);
ship_01_POSITION_Y = magnitude * sin(angle);
glutPostRedisplay();
glutTimerFunc(25,update,0);
}

it moves up and down but does not rotate.

GClements
07-17-2013, 04:00 AM
double angle = atan2(ship_01_POSITION_Y,ship_01_POSITION_X);


This is wrong. The angle should be the direction the ship is facing.

pbivens
07-17-2013, 04:58 PM
so how do I adjust the angle variable.

GClements
07-18-2013, 07:38 AM
so how do I adjust the angle variable.
Have keys for "rotate right" and "rotate left". Pressing one causes the angle to increase at a fixed rate, pressing the other causes it to decrease at a fixed rate.

pbivens
07-18-2013, 07:25 PM
here is the code I am using


void ship_left_two()
{
angle+=2.5f;
}

void ship_right_two()
{
angle-=2.5f;
}

here is the drawing code


void DrawShip(GLfloat position_X,GLfloat position_Y, GLfloat position_Z, GLfloat rotation,GLfloat color)
{
glPushMatrix();
double magnitude = sqrt(position_X * position_X + position_Y * position_Y);
double angle = atan2(position_Y,position_X);
position_X = magnitude * cos(angle);
position_Y = magnitude * sin(angle);
// double acceleration = sqrt(position_X * position_X + position_Y * position_Y);
// double angle = atan2(position_Y,position_X);
// position_X = acceleration * cos(angle);
// position_Y = acceleration * sin(angle);
// position_X = speed_X;
// position_Y = speed_Y;
// glRotatef(rotation,0.0f,0.0f,1.0f);
glTranslatef(position_X, position_Y, position_Z);
glColor3f(color,0.0f,0.0f);
glBegin(GL_LINE_LOOP);
glVertex3f(0.0f,-0.25f,0.0f);
glVertex3f(-0.25f,-0.5f,0.0f);
glVertex3f(-0.5f,-0.5f,0.0f);
glVertex3f(0.0f,0.5f,0.0f);
glVertex3f(0.5f,-0.5f,0.0f);
glVertex3f(0.25f,-0.5f,0.0f);
glVertex3f(0.0f,-0.25f,0.0f);
glEnd();
glPopMatrix();
}

I am still a little confused

GClements
07-19-2013, 04:03 AM
here is the drawing code


double magnitude = sqrt(position_X * position_X + position_Y * position_Y);
double angle = atan2(position_Y,position_X);
position_X = magnitude * cos(angle);
position_Y = magnitude * sin(angle);


This doesn't belong here. The drawing code in your first post was fine.

The issue is how you obtain the position which you pass to the drawing function.

pbivens
07-19-2013, 01:35 PM
now I am totally confused, please help