0

I have an image (let's say it's a simple rectangle) positioned on the left of my screen, which I can move up and down. When moving it upwards, I use some simple trigonometry to rotate it so that the rectangle "points" towards the upper right corner of the screen. When moving downwards, it points towards the lower left corner of the screen.

Given that my application uses the following coordinate system: Coordinate system

I use the following code to achieve the rotation:

// moving upwards
rotation = -atan2(position.y , res.x - position.x));

// moving downwards
rotation = atan2(res.y - position.y , res.x - position.x));

where res is the reference point and position is the position (upper left corner) of our rectangle image. (For information on atan2(): atan2() on cplusplus.com).

This works just fine: it rotates more when farther away from the reference point (res). However, let's say the image is all the way at the bottom of the screen. If we move it upwards, it will very suddenly rotate. I would like to 'inbetween' this rotation, so that it is smoothened out.

What I mean by suddenly rotating is this: Let's say the rectangle is not moving in frame n: therefore its rotation is 0 degrees. I then press the up arrow, which makes it calculate the angle. In frame n+1, the angle is 30 degrees (for example). This is ofcourse not very smooth.

Is my question clear? How do I go about this?

RaptorDotCpp
  • 1,375
  • 12
  • 25

1 Answers1

1

You can incrementally change the angle on each frame. For a very "smooth" rotation effect, you can use

target_angle = ... 
current_angle += (target_angle - current_angle) * smoothing_factor

where smoothing_factor gives the rate at which current_angle should converge to target_angle. For example, a value of 1 would be instantaneous, a value of 0.1 would probably give a smooth effect.

By doing this you may encounter the wraparound issue whereby something like going from 10 degrees to 350 degrees would go the wrong way. In such a case, use

target_angle = ... 
current_angle += diff(target_angle, current_angle) * smoothing_factor

where

diff(a, b) {
    return atan2(sin(a - b), cos(a - b))
}

This nice angle difference formula is taken from another question.

Community
  • 1
  • 1
Zong
  • 5,701
  • 5
  • 27
  • 46
  • It should be noted that delta time should be included to make the rotation speed time independent – Sebastian Hoffmann Jun 26 '13 at 20:51
  • @Paranaix Yes, and we would then use the parametric form for this equation, which should be exponential decay. Depends on how important the animation is and whether this extra bit of effort is worth it. – Zong Jun 26 '13 at 21:07