Search code examples
processinggame-physicsphysicsprocessing.js

Processing.js: Stop acceleration using ease out


I'm looking at an example from Nature of Code.

The particular example has a ball accelerate towards the cursor. However, it does not stop when it reaches it, actually it has maximum momentum, and starts to decelerate once it passes it, accelerate towards the cursor, and overshoot it again.

My question is, how to have the ball accelerate, then start decelerating BEFORE it touches the cursor using a transition such as ease out, so it stops before it touches the cursor?

The ProcessingJS code:

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

// A Mover object
Mover mover;

void setup() {
  size(640,360);
  mover = new Mover(); 
}

void draw() {
  background(255);

  // Update the position
  mover.update();
  // Display the Mover
  mover.display(); 
}

// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com

class Mover {

  // The Mover tracks position, velocity, and acceleration 
  PVector position;
  PVector velocity;
  PVector acceleration;
  // The Mover's maximum speed
  float topspeed;

  Mover() {
    // Start in the center
    position = new PVector(width/2,height/2);
    velocity = new PVector(0,0);
    topspeed = 5;
  }

  void update() {

    // Compute a vector that points from position to mouse
    PVector mouse = new PVector(mouseX,mouseY);
    PVector acceleration = PVector.sub(mouse,position);
    // Set magnitude of acceleration
    acceleration.setMag(0.2);

    // Velocity changes according to acceleration
    velocity.add(acceleration);
    // Limit the velocity by topspeed
    velocity.limit(topspeed);
    // position changes by velocity
    position.add(velocity);
  }

  void display() {
    stroke(0);
    strokeWeight(2);
    fill(127);
    ellipse(position.x,position.y,48,48);
  }

}

Solution

  • The Nature of Code is an awesome book and I'm often coming back to read it, especially when it comes to autonomous agents.

    About your specific question, Shiffman deals with this exact problem just a little bit further in the same chapter. Take a look at example 6.2 on this page and you'll get the approximative comportment you just described. It's a little bit too long to post the whole thing, but here's an excerpt just in case the site goes down in the future and someone reads this question:

    void arrive(PVector target) {
        PVector desired = PVector.sub(target,location);
    
        // The distance is the magnitude of
        // the vector pointing from
        // location to target.
        float d = desired.mag();
        desired.normalize();
        // If we are closer than 100 pixels...
        if (d < 100) {
          //[full] ...set the magnitude
          // according to how close we are.
          float m = map(d,0,100,0,maxspeed);
          desired.mult(m);
          //[end]
        } else {
          // Otherwise, proceed at maximum speed.
          desired.mult(maxspeed);
        }
    
        // The usual steering = desired - velocity
        PVector steer = PVector.sub(desired,velocity);
        steer.limit(maxforce);
        applyForce(steer);
      }
    

    I can take no credit for the code, as it's Shiffman's writing. I'm just the messenger. Have fun and thanks for the glory points!