5

I would like to know if it's possible to select coordinates from a path to draw a bitmap over time, for example, I have an image of a sun, and I would like to move it, over time, along an arc path.

Is there some way to define a path like this and then move along it, so that I don't have to calculate it mathematically?

Thanks.

WendiKidd
  • 4,333
  • 4
  • 33
  • 50
Hamid
  • 4,410
  • 10
  • 43
  • 72
  • This question is 5 years old now and I still see answers coming in. – Hamid May 15 '15 at 10:17
  • This question is 5 years old now and I still see answers coming in. I'm older, and, well, older now and personally, I would do this right now using a sinusoid. (Math.sin()). Between 0 and Pi rads would give you 180 degrees, or you can multiply or divide the X and Y values to give wider/tighter arcs, but that's all basic mathematics of sine waves. Increment/loop the values in a timer or in your draw loop. (Use float values against time in millis to get smooth movements, by moving a fraction of a pixel each frame) – Hamid May 15 '15 at 10:25

3 Answers3

12

Yes, it's possible to move image along path. I will provide simple solution to show the principle. The following code will move and rotate your image. If you don't need rotation remove the TANGENT_MATRIX_FLAG flag.

import android.graphics.*;
//somewhere global
int iCurStep = 0;// current step

//don't forget to initialize
Path pathMoveAlong = new Path();
private static Bitmap bmImage = null;

@Override
protected void onDraw(Canvas canvas) {
    Matrix mxTransform = new Matrix();
    PathMeasure pm = new PathMeasure(pathMoveAlong, false);
    float fSegmentLen = pm.getLength() / 20;//20 animation steps

    if (iCurStep <= 20) {
        pm.getMatrix(fSegmentLen * iCurStep, mxTransform,
            PathMeasure.POSITION_MATRIX_FLAG + PathMeasure.TANGENT_MATRIX_FLAG);
        canvas.drawBitmap(bmImage, mxTransform, null);
        iCurStep++;
        invalidate();
    } else {
        iCurStep = 0;
    };
};
Eduard
  • 1,464
  • 15
  • 19
  • Hi Eduard, could you provide some more code (Activity, layout, etc...)? This is not enough for me to understand how it works. Many thanks in advance! – thomaus Mar 14 '13 at 17:40
  • 1
    Also would you mind sending some code using a real image and a real path? – thomaus Mar 14 '13 at 18:45
  • Ok, I got it using http://stackoverflow.com/questions/6154370/android-move-object-along-a-path – thomaus Mar 15 '13 at 09:22
6

Here are the animators I use:

Purpose: Move View "view" along Path "path"

v21+:

ValueAnimator pathAnimator = ObjectAnimator.ofFloat(view, "x", "y", path)

v11+:

ValueAnimator pathAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);

pathAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
float[] point = new float[2];

@Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float val = animation.getAnimatedFraction();
        PathMeasure pathMeasure = new PathMeasure(path, true);
        pathMeasure.getPosTan(pathMeasure.getLength() * val, point, null);
        view.setX(point[0]);
        view.setY(point[1]);
    }
});

Similar requirement to: https://stackoverflow.com/a/30254715/4344057

Community
  • 1
  • 1
Dileep P G
  • 571
  • 5
  • 13
3

I'm thinking of one solution:

         _
       /   \

If your arc has this kind of shape (meaning less than half a circle and positioned horizontaly) then you could iterate the x value and for that x get the y that's on the path. Then move your bitmap to that position.

Iulius Curt
  • 4,984
  • 4
  • 31
  • 55
  • This is how I ended up implementing it. Wat I was hoping for was a path feature like iOS has but it seems it's not available. – Hamid Feb 11 '11 at 08:37
  • Now that I'm thinking and I searched a little about this, I'm cuious: how did you get the point at a specific x value that's on the path? – Iulius Curt Feb 11 '11 at 10:46
  • I ended up just moving in several straight lines that make up a curve or other pattern. So, 3 straight lines in the case of you ASCII art above. – Hamid Jun 28 '12 at 14:15