JS Математика: повернуть объект на точку, кратчайшим способом

Всем привет! В общем делаю игру на канвасе, где нужно управлять 2д машиной, у меня возникла проблема с поворотом машины в нужную мне точку. mx, my - это точка в которую я хочу повернуть машину, this.Rotate - текущий поворот машины, вычисляю точку в которую я хочу повернуть машину так:

const targetRotate = Math.atan2(this.point.y - cy, this.point.x - cx); 

Но проблема в том, что машина может начать поворачиваться вокруг своей оси, когда можно было не поворачиваться лишний раз вокруг своей оси, а немного повернутся в другую сторону. Ну к примеру это возникает когда targetRotate допустим 0.50 радиан, а this.Rotate допустим 5 радиан.

class Player extends GameObject{
  constructor(){
    super(new Vector3(1122,280,10), new Size(62,33));
    this.setTexture(getTex('player'))
    this.OnUpdate = true;
    this.speed = 5;
  }

  Update(){
    const pos = this.pos;
    pos.x += Math.cos(this.Rotate)*this.speed;
    pos.y += Math.sin(this.Rotate)*this.speed;
    const size = this.size;

    if(AnyMouseDown){
      this.point = new Vector2(mx,my);
    }

    if(this.point != null){
      const cx = pos.x+size.w,cy = pos.y+size.h;
      const targetRotate = Math.atan2(this.point.y - cy, this.point.x - cx);

      const rotationSpeed = 0.1;

      console.log(this.Rotate + " " + targetRotate);

      if (this.Rotate < targetRotate - rotationSpeed) {
        this.Rotate += rotationSpeed;
      } else if (this.Rotate > targetRotate + rotationSpeed) {
        this.Rotate -= rotationSpeed;
      } else {
        this.Rotate = targetRotate;
        this.point = null;
      }
    }

    if(RectIntersectsLine(pos.x,pos.y,size.w,size.h,this.Rotate, Track.border1) || RectIntersectsLine(pos.x,pos.y,size.w,size.h,this.Rotate, Track.border2)){
      console.log("Машина врезалась в края трека");
    }

    ObjectCumShoot(this);
  }
}

Ответы (1 шт):

Автор решения: MBo

Если mx, my - точка, в которую нужно повернуть, posx, posy - текущее положение машины, dirx, diry - текущее направление машины, то вычисляете вектор направления на точку

px = mx - posx
py = my - posy 

и угол, на который нужно вращать машину (угол доворота, а не направление)

rotangle = atan2(px*diry-py*dirx, px*dirx+py*diry)

Если величина угла доворота по модулю оказывается больше Pi, то

if rotangle > Pi
   rotangle = rotangle - 2*Pi
else if rotangle <= -Pi
   rotangle = 2*Pi + rotangle

P.S. По возможности поменьше используйте углы. Вот это

pos.x += Math.cos(this.Rotate)*this.speed;

лучше считать с использованием единичного вектора направления (компоненты которого по сути косинус и синус угла направления, но считаются только один раз при изменении)

pos.x += dir.x*this.speed;
→ Ссылка