Использование нормализованных векторов для хранения направления

Я делаю простую игру на С#/XNA. Мои актеры сохраняют направление, в котором они намереваются двигаться, как Vector2. В каждом цикле обновления я нормализую заголовок (поскольку способ его установки может привести к разной длине) и добавляю heading*Speed к позиции для перемещения актера.

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

  1. Есть ли NormalizedVector2 в XNA?
  2. Как создать приложение, совместимое с Vector2 XNA (т. е. его можно добавить к нему и т. д.)? Расширить Vector2 и переопределить свойство Length?
  3. Существуют ли более серьезные концептуальные проблемы с тем, как я пытаюсь достичь того, чего я пытаюсь достичь?

person Superbest    schedule 13.10.2012    source источник
comment
Хотя можно подумать, что направление само по себе не имеет величины, вектор скорости имеет. Вектор скорости содержит как скорость, так и направление, и эти данные удобно представлять в виде единой векторной структуры. Очень простой способ совместить курс и скорость — начать с курса с единицей длины, как вы это делаете. Использование этого вектора скорости, который фактически содержит два бита данных, — элегантная вещь.   -  person Steve H    schedule 13.10.2012


Ответы (3)


  1. Нет. Единственный 2D-вектор — это Vector2 в XNA.
  2. Вы не можете. Поскольку Vector2 является struct, вы не можете создать его подкласс. Однако вы можете создать свой собственный тип и предоставить метод для его преобразования в Vector2 (путем создания нового Vector2).

На самом деле, я подозреваю ваш текущий подход (используя Vector2 и просто вызывая Нормализовать, вероятно, лучший подход. Если вас действительно беспокоит большое количество вызовов, используйте перегрузка, которая использует ref и out для параметров, так как это немного более эффективно.

person Reed Copsey    schedule 13.10.2012
comment
Это такая крошечная функция, что, если вы не пишете движок частиц или физический движок и не выполняете тщательное профилирование (они, типа, очень крошечные!), на самом деле не имеет значения, какой из них вы выберете. Но, что бы это ни стоило, я решил проверить ваш ответ. И вы совершенно правы, обе другие перегрузки примерно на 25% медленнее (x86 .NET 4.0). - person Andrew Russell; 13.10.2012
comment
На самом деле я (несколько) беру свои слова назад. Если вы нормализуете вектор на месте, то Normalize(), который работает с this, имеет ту же скорость, что и static, который принимает ссылки. Профилировать этих лохов сложно ;) - person Andrew Russell; 13.10.2012

  1. Не то чтобы я в курсе
  2. Как уже говорилось, Vector не может быть подклассом, но вы можете создать класс Direction, который обрабатывает вычисления и может быть преобразован в Vector2 или просто иметь свойство Vector.
  3. Я бы просто использовал унитарный вектор и повернул его с помощью матрицы. С точки зрения производительности, он позволяет избежать разделения, которое обычно является медленной операцией. Даже с точки зрения логики направление чаще выражается как 30° влево, а не как x + y.
person Samy Arous    schedule 13.10.2012
comment
Нормализация вектора — это 2 умножения, сложение, квадратный корень и деление. Но поворот вектора с матрицей — это множество сложений и умножений, а также пара триггерных операций. Бьюсь об заклад, вращение матрицы намного медленнее. Вы могли бы сделать это без матрицы - я уверен, что это все равно не выигрыш в производительности. Выражение направлений в виде нормализованных векторов на самом деле чрезвычайно распространено. - person Andrew Russell; 13.10.2012

Я что-то упускаю? Нормализованный вектор — это просто вектор, в котором x + y равен 1 и указывает направление. У него нет длины, как у любого вектора.

Вы можете хранить нормализованный вектор только в векторе того же типа. И, конечно, вам нужно обновить его, когда вам нужно изменить направление чего-либо.

Это довольно простая концепция, описанная здесь: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.normalize.aspx

person Madmenyo    schedule 13.10.2012
comment
Vector2 хранит величину и направление. Величина не имеет значения для моих целей, и я не хочу ее хранить. Как вы можете понять из моего вопроса, я знаю, как нормализовать вектор. - person Superbest; 13.10.2012