Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

The following code will find the shortest rotation (in radians) (from pi to -pi) that I need to apply to from to leave me with to.

Scalar rotationBetween(Scalar from, Scalar to)
    Scalar fromMod = std::signbit(from) ? 
        pi * 2 + std::fmod(from, pi * 2) : std::fmod(from, pi * 2);
    Scalar toMod = std::signbit(to) ?
        pi * 2 + std::fmod(to, pi * 2) : std::fmod(to, pi * 2);

    Scalar rotation = toMod - fromMod;

    if(rotation > pi)
        return rotation - 2 * pi;
    else if(rotation < -pi)
        return 2 * pi + rotation;
        return rotation;

Scalar is a c++ float.

Can I simplify this? I feel like this is far too much logic to do something so simple.

share|improve this question
std::min(std::max(from, to) - std::min(from,to), std::min(from,to) + 2*pi - std::max(from,to));? – Chaosed0 Jun 25 '14 at 18:35
up vote 4 down vote accepted

To get a value inside [-pi,pi], you can add pi, do fmod, and subtract pi again. Here is one way that works. Unfortunately you still need to somehow test whether from - to is positive or negative before calling fmod:

Scalar rotationBetween(Scalar from, Scalar to)
    return (from > to) ? -pi + std::fmod(from - to + pi, pi * 2)
                       :  pi - std::fmod(to - from + pi, pi * 2);

If you are absolutely sure that from and to are in [-2pi,2pi], then this simpler version will work:

Scalar rotationBetween(Scalar from, Scalar to)
    std::fmod(from - to + 5 * pi, pi * 2) - pi;

Finally, if you just want short code and don’t care about performance, this can be interesting:

Scalar rotationBetween(Scalar from, Scalar to)
    return 2 * std::atan(std::tan((from - to) / 2);
share|improve this answer

I think the following should do the trick.

(Edit: as pointed out in the comments, this gives the unsigned rotation).

Scalar rotationBetween(Scalar from, Scalar to)
   //Calculates the two possibilities, and take the smallest
   Scalar difference = std::min(
      std::fmod(from - to, pi * 2),
      std::fmod(to - from, pi * 2)); 

   //takes the above that is in the range 0 to 2*pi 
   //and brings it in the range -pi to pi
   if (difference > pi) 
      difference -= 2 * pi;

   return difference;
share|improve this answer
This cannot be correct. It returns the same value for rotationBetween(a,b) and rotationBetween(b,a). – sam hocevar Jun 26 '14 at 6:53
@sam But the min angle between a an b is the same angle between b and a. Look at a clock. Is the big hand / little hand different from the little hand and the big??? – Simeon Pilgrim Jun 26 '14 at 7:19
They are the same in absolute value, but the sign matters, too. rotationBetween(0,1) should return 1 but it is expected that rotationBetween(1,0) returns -1. – sam hocevar Jun 26 '14 at 7:28
Oh yes, that makes it trickier. – Herman Tulleken Jun 26 '14 at 12:02

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.