Given the pace and the angle of an object, how to calculate it's coordinates after 1 movement?

40 Views Asked by At

I am learning to program a video game, which is a quite fun exercise, but clearly shows where I lack in the field of maths. So, I hope for some help, here.

I have a coordinate system, which starts in the top left with 0/0. Now I put an object on its origin and move it to the right. This would constitute a movement of 0 degrees. Down would mean 90 degrees, to the left 108 and top 270. (Sub-question: is this a good definition or does it go against everything that is holy?) Every step, I'd move 10 units in the given direction.

I hope, nobody minds the code, here.

// player.ts

moveTowards(target: Point) {
    const angle = this.position.angleTowards(target);
    console.log(angle);
    this.paceX = this._pace * Math.sin(this.degrees_to_radians(180 - angle));
    this.paceY = this._pace * Math.sin(this.degrees_to_radians(angle));
  }

  private degrees_to_radians(degrees: number) {
    var pi = Math.PI;
    return degrees * (pi / 180);
  }


update() {
    this.x += this.paceX;
    this.y += this.paceY;
}

However, my tests fail:

  @test moves_horizontally() {
    const player = new Player({ x: 0, y: 0, userId: 'abc' });
    player.moveTowards(new Point(100, 0));
    player.update();
    expect(player.position.x).to.eq(player.pace);
    expect(player.position.y).to.eq(0);
  }

      AssertionError: expected 1.2246467991473533e-15 to equal 10
      + expected - actual

      -1.2246467991473533e-15
      +10

  @test moves_vertically() {
    const player = new Player({ x: 0, y: 0, userId: 'abc' });
    player.moveTowards(new Point(0, 100));
    player.update();
    expect(player.position.x).to.eq(0);
    expect(player.position.y).to.eq(player.pace);
  }

      AssertionError: expected 10 to equal 0
      + expected - actual

      -10
      +0

I assumed, wrongly as it shows, because the pace is my hypotenuse and my angle is given, c×sin(angle) should give me y. In the same reasoning, 180-angle should give me the missing angle and allow me to do the same maths.

I am a bit overwhelmed by the array of things I could be doing wrongly, here. So I'd appreciate some help.

For completeness my Point implementation:

class Point {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
  angleTowards(point: Point) {
    var delta = point.subtract(this);
    return Math.atan2(delta.y, delta.x) * 180 / Math.PI;
  }
  subtract(point: Point) {
    return new Point(this.x - point.x, this.y - point.y);
  }
  static get origin() {
    return new Point(0, 0);
  }
}