Задача с границами угла - PullRequest
1 голос
/ 17 июля 2011

Внимание: несмотря на то, что эта проблема возникла, когда я работал с Unity, она не имеет ничего специфического для Unity и больше относится к логике программирования, поэтому, пожалуйста, не уклоняйтесь.

Я используюЕдинство и вращение объекта по сценарию.Дело в том, что если я поверну его, скажем, на 180 градусов, объект не будет поворачиваться точно так сильно и будет стремиться остановиться в диапазоне между 179 и 181 градусом.Итак, чтобы проверить, завершено ли вращение, я проверяю, является ли угол поворота targetAngle +/- 1, который работает.

Я проверяю, используя

if (transform.eulerAngles.z > lowerLimit && transform.eulerAngles.z < upperLimit)

, где

lowerLimit = targetAngle-1;
upperLimit = targetAngle + 1;

Теперь проблема возникает, когда targetAngle равен 0. В этом случае мой скрипт проверяет, находится ли угол поворота между -1 и 1. Но, -1 действительно должен быть 359, поэтому он должен проверить, находится ли угол между 359и 1.

Как я могу это реализовать?Другими словами, я предполагаю, что спрашиваю, как реализовать систему счисления с циклическим изменением.

РЕДАКТИРОВАТЬ

Найден один обходной путь.Если targetAngle равен 0, я лечу это специально.Это работает, но не самый элегантный.

         if (targetAngle == 0.0)
        {
            if ((transform.eulerAngles.z > 359.0 && transform.eulerAngles.z <= 360.0) || (transform.eulerAngles.z >= 0.0 && transform.eulerAngles.z <= 1)) 
            {
                rotate = false;            
            }
        }
        else
        {
            if (transform.eulerAngles.z > targetAngle - 1 && transform.eulerAngles.z < targetAngle + 1)
            {
                rotate = false;            
            }
        }

Ответы [ 2 ]

3 голосов
/ 17 июля 2011

Вы могли бы сделать ...

lowerLimit = (targetAngle % 360) + 359; //360 - 1;
upperLimit = (targetAngle % 360) + 361; //360 + 1;

if (((transform.eulerAngles.z + 360) % 360) > lowerLimit
 && ((transform.eulerAngles.z + 360) % 360) < upperLimit)

Это сдвигает чек от нуля, и вам не придется иметь дело с положительным / отрицательным чеком.

EDIT

Оператор % на targetAngle ограничивает поворот до +/- 359 градусов, поэтому целевой угол 721 снизится до 1, а целевой угол -359 снизится до 1. я делаю хорошо для всех случаев, я думаю.

РЕДАКТИРОВАТЬ 2

Чтобы исправить последний случай, который вы упомянули в комментарии, я думаю, вам нужно применить ту же логику переноса к значениям transform.eulerAngles.z. Вероятно, лучше всего поместить эту упаковку в дополнительную функцию сейчас, поэтому попробуйте это:

int wrapNumber(int input) // replace int with whatever your type is
{
  // this will always return an angle between 0 and 360:
  // the inner % 360 restricts everything to +/- 360
  // +360 moves negative values to the positive range, and positive ones to > 360
  // the final % 360 caps everything to 0...360
  return ((input % 360) + 360) % 360;
}

lowerLimit = wrapNumber(targetAngle) + 359; //360 - 1;
upperLimit = wrapNumber(targetAngle) + 361; //360 + 1;

if (wrapNumber(transform.eulerAngles.z) + 360 > lowerLimit
 && wrapNumber(transform.eulerAngles.z) + 360 < upperLimit)

В зависимости от того, как часто вам нужно это использовать, проверка некоторых случаев может удалить ненужные накладные расходы. Например, окончательный % 360 в пределах wrapNumber необходим только в том случае, если входные данные были положительными. Если вы звоните по этому номеру десять раз в минуту, это, вероятно, не имеет значения. Если вы вызываете его сто раз в секунду, вы можете проверить, как он работает в этой ситуации.

1 голос
/ 18 ноября 2015

Это может быть старый поток, но, посмотрев на множество различных фрагментов, все пытавшихся разобраться с Wrapping, я обнаружил, что в Unity есть хорошая встроенная функция, которая просто заботится о бизнесе, по крайней мере, в моем случае конечный результат, который мне требовался, былтак что мне нужно было только изменить его на LerpAngle, и он дал солидный результат.

Mathf.LerpAngle - ваш друг ... решил все мои проблемы с сованием и т. д.

http://docs.unity3d.com/ScriptReference/Mathf.LerpAngle.html

...