Для игры, которую я делаю, я хочу 3 корабля, которые будут гонять по карте, набирая очки. Он отлично работает, за исключением одной точки на карте, где корабли решают повернуть почти на 360 градусов против часовой стрелки, хотя достаточно только 10 градусов по часовой стрелке.
Код для расчета поворота:
vec2 distance = *desiredPosition - position;
float rot = atan2(distance.y, distance.x);
rot = rot * 180.f / PI + 90.f;
if (rot < angle)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (rot > angle)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
Как я могу убедиться, что он не будет вращаться в неправильном направлении?
Благодаря Ричарду Байрону (принятый ответ ниже) проблема исправлена. Взятие точечного произведения лучше, чем использование степеней.
Финальный код:
vec2 distance = desiredPosition - position;
normal = vec2(sin((angle - 90) * PI / 180.0), cos((angle - 90) * PI / 180.0) * -1);
float dir = normal.x * distance.x + normal.y * distance.y;
//turn
if (dir > 0)
{
angle -= dAngle;
boat->RotateImage(-dAngle);
}
if (dir < 0)
{
angle += dAngle;
boat->RotateImage(dAngle);
}
velocity += vec2(acceleration * cos((angle - 90) * PI / 180.0), acceleration * sin((angle - 90) * PI / 180.0));
Есть несколько проблем с вашим обновленным кодом. Во-первых, должно быть rot2 = 360 — rot1; (rot1 + 360 точно такой же угол, что и rot1).
Вторая проблема заключается в том, что вы не учитываете, что 1 и 359 градусов — это почти один и тот же угол. Так что если abs (rot1 — angle)> 180, то вам действительно нужно использовать 360 — abs (rot1 — angle) в этом случае. Ваши последующие сравнения с гнилью и углом являются проблемой по той же причине, и вам нужно обрабатывать угол, увеличивающийся выше 360 и уменьшающийся ниже 0.
Я мог бы написать код для этого, но на самом деле есть гораздо более простой и быстрый способ сделать это. Если вы берете точечное произведение вектора (требуемая позиция — положение) и вектора под прямым углом к текущему курсу корабля, то вы можете поворачиваться на основе знака этого результата. Если неясно, как это сделать, дайте мне знать, и я могу рассказать об этом в комментариях.
Угол поворота лодки должен быть не более 180 градусов по часовой стрелке или против часовой стрелки. Если он поворачивается более чем на 180 градусов в одном направлении, было бы лучше повернуть в другую сторону.
Более общим решением было бы вычисление вектора расстояния относительно системы отсчета лодки.