# Rotating an object smoothly

I'm trying to rotate a ship in an asteroid game. What I'm doing is creating a float angle variable and at each time I press left or right buttons, I increase and decrease it, and in the drawing function, I rotate the ship by that amount.

The behaviour that I get is not really correct, because what I want is at each press, the ship should move smoothly and not by small increments. This is what I'm doing:

 static float ang = 20.0f;

if(event.getCode() == KeyEvent::KEY_RIGHT)
{
ship.m_Angle+=ang*getElapsedSeconds();
}
else if(event.getCode() == KeyEvent::KEY_LEFT)
{
ship.m_Angle-=ang*getElapsedSeconds();
}

gl::pushMatrices();
gl::translate(Vec2f(m_Pos.x,m_Pos.y));

gl::rotate(Vec3f(0,0,m_Angle));
gl::scale(0.3,0.3,0.3);
gl::color(ci::Color(1,1,1));

gl::drawLine(Vec2f(-52,-23),Vec2f(69,0));
gl::drawLine(Vec2f(-43,-20),Vec2f(-43,20));
gl::drawLine(Vec2f(69,0),Vec2f(-52,23));
gl::popMatrices();


EDIT: I would also like to limit the angle, it goes forever and the variable will overflow.

• I'm not sure that I fully understand your question, since it looks like David's understanding is different than mine... By "move smoothly", do you mean that you want your ship to keep rotating as long as the key is pressed? – Laurent Couvidou Aug 5 '12 at 2:52
• @lorancou The ship angle variable goes overflow, and also when you press the key, the ship rotates in small increments, I would like on press the button, the ship rotates not by small increments. – Ahmed Saleh Aug 5 '12 at 12:21

static float ang = 20.0f;

if(  event.getCode() == KeyEvent::KEY_RIGHT)
{
ship.m_Angle+=ang*getElapsedSeconds();
}
else if( event.getCode() == KeyEvent::KEY_LEFT)
{
ship.m_Angle-=ang*getElapsedSeconds();


Should be:

static float ang = 20.0f;

if(  event.getCode() == KeyEvent::KEY_RIGHT)
{
ship.m_Angle = fmod(ship.m_Angle + ang, 360);
}
else if( event.getCode() == KeyEvent::KEY_LEFT)
{
ship.m_Angle = fmod(ship.m_Angle - ang, 360);
}


I've removed getElapsedSeconds(); as it would jump first frame as soon as a key would be pressed.

Note I've added the closing bracket on the second example, see last line, which looks like it is in the wrong place in your example and the fmod will ensure that it doesn't overflow.

• it is ok now, but is it correct to use glrotate with angle like that or it should be converted to radian. – Ahmed Saleh Aug 5 '12 at 13:22
• Something like glRotatef(ship.m_angle, 0.0f, 0.0f, 1.0f); is required. First parameter is an angle so no radian to convert. – John Aug 5 '12 at 19:28

Have 2 angles and a rotation speed value.

1 angle is a 'target' angle and another is the 'current' angle.

The 'current' angle is the displayed one that can take any visible rotation. The target angle is the one you change that can only take the angles you want to be selectable.

Every frame update make the 'current' angle increase or decrease in the direction of the 'target' angle by the desired rotation speed * elapsed time. When the buttons are pressed increase/decrease the target angle based on the direction in increments based on the number of rotation degree you want.

Just make sure that you don't overshoot the target angle otherwise you will jump back and forth around it.

• would you please show me a pseudo code ? – Ahmed Saleh Aug 5 '12 at 10:53