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 шт):
Если 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;