Reputation: 54143
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
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
Reputation: 477436
Maybe something like this:
Normalize all angles to lie in [0, 2Pi)
by adding or subtracting 2Pi
repeatedly.
Shift by min(a, b)
so that your new endpoints are 0
and c
.
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