0
\$\begingroup\$

I am looking for an equation for predicting the future position of a moving arcade physics body in Phaser 3. The body has drag applied and isDamping set to true. Phaser applies the drag using the following run on each update (showing x axis only but same applies to y).

//  Damping based deceleration
dragX = Math.pow(dragX, delta);

velocityX *= dragX;

Given the above, how would I write a kinetic equation to predict the future position?

I am currently using the method below, where I am iterating over frames to calculate the position accumulatively. But this is inefficient and inelegant so would prefer a solution which estimates the position without any looping.

public futurePosition(timeInSeconds: number): Phaser.Math.Vector2 {
  const DELTA = 1 / 60; // Assume we are running at 60fps
  const DRAG = 0.3; // Drag value
  const position = this.position.clone(); // Current position of body
  const velocity = this.body.velocity.clone(); // Current velocity

  // Inefficiently looping through frames
  for (let i = 0; i < timeInSeconds / (DELTA * 1000); i++) {
    velocity.x *= Math.pow(DRAG, DELTA);
    velocity.y *= Math.pow(DRAG, DELTA);
    position.x += velocity.x * DELTA;
    position.y += velocity.y * DELTA;
  }

  return position;
}

Any help appreciated. Thanks.

\$\endgroup\$
4
  • \$\begingroup\$ I believe that it should be possible to solve this using integral calculus. Unfortunately that's not my strong suit. \$\endgroup\$
    – Philipp
    Commented Apr 8, 2021 at 13:13
  • \$\begingroup\$ Okay thanks Philipp. I will try and bend my mind round some calculus. \$\endgroup\$
    – Calabi
    Commented Apr 8, 2021 at 13:45
  • \$\begingroup\$ I've shared solutions for this here and here which might be useful to you. \$\endgroup\$
    – DMGregory
    Commented Apr 8, 2021 at 15:32
  • \$\begingroup\$ I'll have a read @DMGregory, thanks. \$\endgroup\$
    – Calabi
    Commented Apr 8, 2021 at 17:44

1 Answer 1

1
\$\begingroup\$

Solved with a geometric progression.

public futurePosition(timeInSeconds: number): Phaser.Math.Vector2 {
  const fps = 60;
  const drag = Math.pow(0.3, 1 / fps);
  const x = ((this.body.velocity.x / fps) * (1 - Math.pow(drag, timeInSeconds * fps))) / (1 - drag);
  const y = ((this.body.velocity.y / fps) * (1 - Math.pow(drag, timeInSeconds * fps))) / (1 - drag);

  return new Phaser.Math.Vector2(this.position.x + x,  this.position.y + y);
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .