jmasterx
jmasterx

Reputation: 54143

Interpolating an angle counter clockwise?

Right now 'm using linear bezier to interpolate angles:

    float CardAnimation::valueAt( float valueA, float valueB, float t ) const
    {
        return (1.0f - t) * valueA + t * valueB;
    }

....
if(m_startCard.m_angle != m_endCard.m_angle)
            {
                m_targetCard->m_angle = 
                    valueAt(m_startCard.m_angle, m_endCard.m_angle,m_interval);
            }

This works as expected. But here is my problem. If your start angle is 0.5f and you want to go to 6.0f (in radians) then it will go clockwise from 0.5f to 6.0f when really since 6.0f - 0.5f > 3.14f it would be much smarter to go counter clockwise from 0.5f to 6.0f (resulting in moving only 0.78 radians rather than 5.5). What should I do to interpolate counter clockwise if abs(endAngle - startAngle > PI) ?

Thanks

Upvotes: 0

Views: 579

Answers (2)

JohnPS
JohnPS

Reputation: 2626

If abs(endAngle - startAngle) > PI, then subtract 2*PI from endAngle. Then instead of going from 0.5 to 6.0, you go from 0.5 to -0.28.

Edit:

This actually assumes 0 <= startAngle < endAngle <= 2*Pi.

If 0 <= endAngle < startAngle <= 2*Pi and startAngle - endAngle > PI, then add 2*PI to endAngle.

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 477436

Maybe something like this:

  1. Normalize all angles to lie in [0, 2Pi) by adding or subtracting 2Pi repeatedly.

  2. Shift by min(a, b) so that your new endpoints are 0 and c.

  3. You either want your range to be c or by 2Pi - c, whichever is smaller, and you have to figure out the sign depending on what you did at (2). Then you want to interpolate between your original start point, and the startpoint plus the range.

Upvotes: 1

Related Questions