Как компенсировать «скачок угла» от 0 до 360 и наоборот?

1

Я использую вращающуюся пушку на танке. Пушка NPC следует за танком игрока (автоматически вращается).

Я рассчитываю:

  • Угол векторного резервуара → враг (радианы)
  • Угол пушки (радианы)
  • Разница между обоими (я пытался с Math.min и Math.abs после googling)

Проблема в том, что прыжок с 0 градусов до 360 или от 360 до 0 делает пушку "свободным" в танке игрока, и пушка вращается один раз вокруг.

Сейчас это делается так:

  Vector2 Tank2Enemy = tank.getPosition().sub(closestEnemyTank.getPosition());
  float angleTank2Enemy = Tank2Enemy.angleRad();   // this is the angle of the vector tank -> enemy in radians   
  float angleCannon = tank.cannon.getOwnAngle();   // this is the cannon-angle in radians   
  float diffAngle = Math.min(Math.abs(angleCannon - angleTank2Enemy), MathUtils.PI - Math.abs(angleCannon - angleTank2Enemy));

  if (diffAngle > 0.01f || diffAngle < -0.01f) {   // dead zone

     if (diffAngle > 0.01f) {

        direction = -1;   // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
     }
     else if (diffAngle < 0.01f) {
        direction = 1;   // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
     }
  }

  return direction;
  • 0
    я только что сделал видео: youtu.be/HGRlQhULu2U
Теги:
rotation
angle

2 ответа

1

Хорошая практика заключается в том, чтобы угол всегда был положительным, например, чтобы не путаться с разными знаками в углах. Вы могли заметить, что угол 270 будет работать так же, как -90 градусов. Ваша проблема может быть решена путем простой проверки:

while(angle >= 2*Math.PI) //angle in radians
    angle -= 2*Math.PI;
while(angle < 0)
    angle += 2*Math.PI;

Обновление: я думаю, проблема кроется в том, как вы вычисляете diffAngle. Не могли бы вы попробовать следующее?

float diffAngle = angleCannon - angleTank2Enemy; // or angleTank2Enemy - angleCannon, depending on the direction of angles in your game
double sign  = Math.signum(diffAngle);
float diffAngle = sign >= 0 ? Math.min(diffAngle, 2*MathUtils.PI - diffAngle) : Math.max(diffAngle, -(2*MathUtils.PI - diffAngle));
  • 0
    Спасибо! я уже сделал это мой код выглядит так, теперь это упрощено: diffAngle = (angleTank2Enemy - angleCannon); if (Math.abs (diffAngle)> 0,05f) {// мертвая зона if (diffAngle> 0,05f) направление = -1; иначе if (diffAngle <-0.05f) direction = 1; } обратное направление; все мои углы колеблются от 0 до 2 * пи
  • 0
    Спасибо! я уже сделал это все мои углы колеблются от 0 до 2 * пи. Моя проблема: если у меня есть diffAngle = (angleTank2Enemy - angleCannon); затем я получаю "скачки" от 0 до 2 * PI => внезапно diff = -6 ... или внезапно diff = +6 ... и это заставляет объект вращаться один раз вокруг .... надеюсь, вы понимаете, что я значит....
Показать ещё 3 комментария
0

Хорошо, я решил это так:

    if (angleTank2Enemy > angleCannon) {

        diffAngle = angleTank2Enemy - angleCannon;
        if (diffAngle > MathUtils.PI) {
            rotDirRight = true;
        }
        else rotDirRight = false;
    }
    else {
        diffAngle = angleCannon - angleTank2Enemy;
        if (diffAngle > MathUtils.PI) {
            rotDirRight = false;
        }
        else rotDirRight = true;
    }

    if ((diffAngle) > 0.05f) {  // dead zone

        if (rotDirRight)    direction = 1;  // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
        else                direction = -1; // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
    }

    return direction;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню