Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation Along a path with Auto Rotation based on the path in android

I have been trying to animate an image of a fly which moves in a path like the following image(which i have added for a clear idea) in android version 2.2

Well,this can be done in a very simple manner in the iphone as they have a property forsetting this auto rotation after the path is drawn using

animation.rotationMode = kCAAnimationRotateAuto;

which i believe would rotate the object based on the path`

Fly path

I am able to animate ma fly through this path using the nineoldandroid library using the methods

 path.moveTo(float x, float y);
 path.lineTo(float x, float y);
 path.curveTo(float c0X, float c0Y, float c1X, float c1Y, float x, float y);

Such that the curves are drawn through cubic B�zier curve.

Now what i have been trying is to implement something that would allow my fly to rotate itself along the path and i just cant seem to reach anywhere.

Please Help Me out with some ideas!!! :( :(

like image 998
John Avatar asked Sep 13 '12 12:09

John


Video Answer


1 Answers

You have to download the demo and the lib of nineoldandroids and these 4 java files if you want to use my solution

That was easy, I modified the evaluator in the demo of nineoldandroids.

It's too much to post here:

Just to get the idea:

I extend the PathPoint with the field angle. Then write all calculated Points in a stack (a simple float[][])

After the first calculation the angle can be calculated by the atan and the last 2 points in the stack.

If you don't want to use a stack you can modify the timeparam and look forward to where the next point will be drawn and calculate the angle out of these.

Just think about: Do you first watch where you are walking to and then walk or do you just walk and then chose the angle for the destination. It's not neccessary since we have display densities that high and calculating the angle for each pixel.

Here's the PathEvaluator

public class PathEvaluatorAngle implements TypeEvaluator<PathPointAngle> {

private static final int POINT_COUNT = 5000;
private float[][] stack = new float[POINT_COUNT][2];
private int stackC = 0;

@Override
public PathPointAngle evaluate(float t, PathPointAngle startValue, PathPointAngle endValue) {
    float x, y;
    if (endValue.mOperation == PathPointAngle.CURVE) {
        float oneMinusT = 1 - t;
        x = oneMinusT * oneMinusT * oneMinusT * startValue.mX +
                3 * oneMinusT * oneMinusT * t * endValue.mControl0X +
                3 * oneMinusT * t * t * endValue.mControl1X +
                t * t * t * endValue.mX;
        y = oneMinusT * oneMinusT * oneMinusT * startValue.mY +
                3 * oneMinusT * oneMinusT * t * endValue.mControl0Y +
                3 * oneMinusT * t * t * endValue.mControl1Y +
                t * t * t * endValue.mY;
    } else if (endValue.mOperation == PathPointAngle.LINE) {
        x = startValue.mX + t * (endValue.mX - startValue.mX);
        y = startValue.mY + t * (endValue.mY - startValue.mY);
    } else {
        x = endValue.mX;
        y = endValue.mY;
    }

    stack[stackC][0] = x;
    stack[stackC][1] = y;

    double angle;

    if (stackC == 0){
        angle = 0;
    } else if (stackC >= POINT_COUNT){
        throw new IllegalStateException("set the stack POINT_COUNT higher!");
    } else {
        angle = Math.atan(
                (stack[stackC][1] - stack[stackC-1][1]) /
                (stack[stackC][0] - stack[stackC-1][0])     
                ) * 180d/Math.PI;
    }
    stackC++;
    return PathPointAngle.moveTo(x, y, angle);
}

}

like image 54
redestructa Avatar answered Nov 15 '22 15:11

redestructa