Search code examples
androidanimationcoordinate-transformation

Animating a list of points to move away from a given touch location


The animation I am working on achieving is shown below in Figure 1.

1)I have a list containing points on a 2D plane(left) that I am working on animating.

2)A touch is made at location x, and an invisible circle is drawn (middle). I want all of the points contained in that circle to move away from the center (x).

3) A final result example (right)

I am planning on applying this in a way that I can supply any list of points, touch location, numFrames, and force applied on each point per frame. An array of length numFrames is returned, each array item being an already animated list.

Since I plan on implementing this on screen touch, it is possible for another touch to happen while the first touch animation is already in progress. How can I handle these collisions?

Figure 1: 2D Point Animation


Solution

  • here's my 2 cents, you need a list of points, these points should have a position, a velocity and a method to update the position. something like this

    public class Point {
        public float x, y;
        public boolean isMoving;
        private float dx,dy;
    
        public Point(float x, float y){
            this.x = x;
            this.y = y;
        }
    
        public boolean move(float maxWidth, float maxHeight){
            if(!isMoving) return false;
    
            // update the position 
            x += dx;
            y += dy;
    
            dx /= FRICTION;
            dy /= FRICTION;
    
            // bounce...?
            if(x < 0 || x > maxWidth){
                dx *= -1;
            }
            if(y < 0 || y > maxHeight){
                dy *= -1;
            }
    
            if(Math.abs(dx) < MOVEMENT_THRESHOLD && Math.abs(dy) < MOVEMENT_THRESHOLD){
                isMoving = false;
            }
    
            return isMoving;
        }
    }
    

    on every touch event you apply a force to every point within the radius and set their velocity

    for(Point point : mPoints){
        float distance = point.distance(x,y);
    
        if(distance > mTouchRange) continue;
    
        float force = (float) Math.pow(1 - (distance / mTouchRange), 2) * mForceFactor;
        float angle = point.angle(x,y);
    
        point.dx -= Math.cos(angle) * force;
        point.dy -= Math.sin(angle) * force;
        point.isMoving = true;
    }
    

    then you need an animation that call move on every frame and eventully stops when there are no moving points

    you can find the full example here