Original Post
A couple weeks ago I implimented 5 different time-based animation patterns for an assignment. The patterns were: Linear - Move between 2 points over a period of time and back. Circle - Move in a circle over a period of time, at an initial position given by angle theta, supporting CW & CCW directions. Ellipse - Same as circle, but elliptical. Circular Arc - Move between 2 endpoints of a circular arc over a period of time and back again. Elliptical Arc - Same as Circular arc but elliptical. Coming up with the solutions wasn't hard at all, but I'm wondering if anyone has a cleaner solution than what I came up with. I'm not so much looking for optimizations, but rather different techniques(although optimizations which fundamentally change the algorithm or simplify it would be appreciated.) Since the assignment I've signifigantly optimized the algorithms below, but these show my approach more clearly so I'll them as is. Below are two examples, the other three are essentially combinations of these two. ticks is the ellapsed time since animation start in milliseconds. period is the length of the animation in milliseconds. initial is the angle representing the start position on a circle in radians. cw is +1 for clockwise, -1 for counter-clockwise. Linear: circular: Hope someone has some ideas! Thanks.
// Function returns time-based position along linear path via given parameters.
Point2 Suite::LinearAnim(const DWORD ticks, DWORD period, const Point2 p0, const Point2 p1)
{
int posX = 0;
int posY = 0;
int dx = p1.X - p0.X;
int dy = p1.Y - p0.Y;
// if (Pstart -> Pend) else (Pend -> Pstart)
if(ticks % (2 * period) < period) {
// There...
posX = p0.X + (int)(dx * ((ticks % period) * (1.0f / period)));
posY = p0.Y + (int)(dy * ((ticks % period) * (1.0f / period)));
}
else {
// and back again.
posX = p1.X - (int)(dx * ((ticks % (2 * period) - period) * (1.0f / period)));
posY = p1.Y - (int)(dy * ((ticks % (2 * period) - period) * (1.0f / period)));
}
return Point2(posX, posY);
}
// Function returns time-based position along circular path via given parameters.
Point2 Suite::CircleAnim(const DWORD ticks, const DWORD period, const Point2 origin, const int radius, const float initial, const int cw)
{
float arc = cw * 6.28318f; // arc in cw/ccw
float rop = (1.0f / period); // reciprical of perdiod
// constant motion on a circular path
int posX = origin.X + (int)(radius * cos(initial + arc * (ticks * rop)));
int posY = origin.Y + (int)(radius * sin(initial + arc * (ticks * rop)));
return Point2(posX, posY);
}