Почему мы используем теорему Пифагора в игровой физике?


38

Недавно я узнал, что мы часто используем теорему Пифагора в наших физических расчетах, и я боюсь, что на самом деле не понимаю.

Вот пример из книги, чтобы убедиться, что объект движется не быстрее, чем MAXIMUM_VELOCITYпостоянная в горизонтальной плоскости:

MAXIMUM_VELOCITY = <any number>;
SQUARED_MAXIMUM_VELOCITY = MAXIMUM_VELOCITY * MAXIMUM_VELOCITY; 

function animate(){
    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);

    if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){

        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;

        x_velocity = x_velocity / scalar;
        z_velocity = x_velocity / scalar;
    }
}

Давайте попробуем это с некоторыми числами:

Объект пытается переместить 5 единиц в x и 5 единиц в z. Он должен иметь возможность перемещать только 5 единиц по горизонтали!

MAXIMUM_VELOCITY = 5;
SQUARED_MAXIMUM_VELOCITY = 5 * 5;
SQUARED_MAXIMUM_VELOCITY = 25;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var squared_horizontal_velocity = (x_velocity * x_velocity) + (z_velocity * z_velocity);
    var squared_horizontal_velocity = 5 * 5 + 5 * 5;
    var squared_horizontal_velocity = 25 + 25;
    var squared_horizontal_velocity = 50;

//  if( squared_horizontal_velocity <= SQUARED_MAXIMUM_VELOCITY ){
    if( 50 <= 25 ){
        scalar = squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY;
        scalar = 50 / 25;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

Теперь это работает хорошо, но мы можем сделать то же самое без Пифагора:

MAXIMUM_VELOCITY = 5;

function animate(){
    var x_velocity = 5;
    var z_velocity = 5;

    var horizontal_velocity = x_velocity + z_velocity;
    var horizontal_velocity = 5 + 5;
    var horizontal_velocity = 10;

//  if( horizontal_velocity >= MAXIMUM_VELOCITY ){
    if( 10 >= 5 ){
        scalar = horizontal_velocity / MAXIMUM_VELOCITY;
        scalar = 10 / 5;
        scalar = 2.0;

        x_velocity = x_velocity / scalar;
        x_velocity = 5 / 2.0;
        x_velocity = 2.5;

        z_velocity = z_velocity / scalar;
        z_velocity = 5 / 2.0;
        z_velocity = 2.5;

        // new_horizontal_velocity = x_velocity + z_velocity
        // new_horizontal_velocity = 2.5 + 2.5
        // new_horizontal_velocity = 5
    }
}

Преимущества делать это без Пифагора:

  1. Меньше строк
  2. В этих строках легче читать, что происходит
  3. ... и вычисление занимает меньше времени, так как меньше умножений

Мне кажется, что компьютеры и люди получают лучшую сделку без теоремы Пифагора! Однако я уверен, что ошибаюсь, поскольку видел теорему Пифагора в ряде авторитетных мест, поэтому я хотел бы, чтобы кто-то объяснил мне преимущество использования теоремы Пифагора для новичка по математике .

Это как-то связано с единичными векторами? Для меня единичный вектор - это когда мы нормализуем вектор и превращаем его в дробь. Мы делаем это путем деления вектора на большую константу. Я не уверен, что это за константа. Общий размер графика? В любом случае, потому что это дробь, я так понимаю, единичный вектор - это, в основном, график, который может поместиться в трехмерной сетке с осью X, бегущей от -1 до 1, осью Z, бегущей с -1 до 1, и Y ось работает от -1 до 1. Это буквально все, что я знаю о единичных векторах ... не так много: P И я не вижу их полезности.

Кроме того, мы на самом деле не создаем единичный вектор в приведенных выше примерах. Должен ли я определить скаляр следующим образом:

// a mathematical work-around of my own invention. There may be a cleverer way to do this! I've also made up my own terms such as 'divisive_scalar' so don't bother googling
var divisive_scalar = (squared_horizontal_velocity / SQUARED_MAXIMUM_VELOCITY);
var divisive_scalar = ( 50 / 25 );
var divisive_scalar = 2;

var multiplicative_scalar = (divisive_scalar / (2*divisive_scalar));
var multiplicative_scalar = (2 / (2*2));
var multiplicative_scalar = (2 / 4);
var multiplicative_scalar = 0.5;

x_velocity = x_velocity * multiplicative_scalar
x_velocity = 5 * 0.5
x_velocity = 2.5

Опять же, я не понимаю, почему это лучше, но это больше "unit-vector-y", потому что multiplicative_scalar - это unit_vector? Как вы можете видеть, я использую такие слова, как «unit-vector-y», так что я на самом деле не математик! Также помните, что единичные векторы могут не иметь ничего общего с теоремой Пифагора, поэтому игнорируйте все это, если я лаю не на том дереве.

Я очень визуальный человек (3D модельер и концепт-художник по профессии!), И я нахожу диаграммы и графики действительно, очень полезными, так что, насколько это возможно, пожалуйста!


2
На самом деле, ни один из написанных алгоритмов не ограничивает скорость. Вектор (2.5, 2.5)имеет величину приблизительно 3,54, а не 5.
Христос

1
sqrt(2.5*2.5 + 2.5*2.5)
bcrist

1
Мы этого не делаем, философ умер 2500 лет назад, и теорема, носящая его имя, была понята другими цивилизациями за тысячелетия до его рождения. Это немного похоже на то, что мы говорим, что мы используем Эйнштейна на подводных лодках Neuclear, это забавная мысль (каждая субмарина имеет Эйнштейна в команде), но мы применяем часть опубликованной им теории. В случае Эйнштейна он известен многими теориями в физике, поэтому вы можете назвать теорию, из которой получается эквивалентность массы-энергии, используя только часть его имени (например, «относительность» вместо «специальной теории относительности»), не путая ее для человек.
Андон М. Коулман

3
Проблема с вашей позицией заключается в том, что «мы можем сделать то же самое без Пифагора». Но расстояние до Манхэттена не совпадает с расстоянием по Евклиду, поэтому вы сравниваете яблоки и апельсины. Если вы хотите евклидово расстояние от пары X / Y, вы должны сделать математику.
Джерри Б.

3
связанные: «Почему мы используем математику в физике» и «Почему мы используем математику в играх?»
vaxquis

Ответы:


104

Ваш код без Pythagoras не вычисляет длину, как мы обычно думаем об этом.

Обычно в трехмерных играх мы моделируем мир как евклидово пространство и используем евклидову метрику расстояния ( также известную как теорема Пифагора ), чтобы вычислить общую длину вектора v с компонентами vx и vy. А именно:

EuclideanLength(v) = sqrt(v.x * v.x + v.y * v.y)

(Обратите внимание, что этот квадратный корень отсутствует в приведенном выше примере кода, поэтому оба подхода дают один и тот же ответ. Подробнее об этом в ближайшее время ...)

Код, который вы описали, использует метрику расстояния Манхэттен :

ManhattanLength(v) = abs(v.x) + abs(v.y)

(Хотя вы не включили абсолютные значения, что может привести к неожиданному поведению отрицательных чисел)

Легко видеть, что эти две функции расстояния совпадают, когда vx или vy равны нулю, и мы движемся только вдоль одной оси. Как они сравниваются, хотя, когда мы движемся по диагонали?

Скажем, vx = vy = 1. Как долго длится этот вектор (эквивалентно, какова скорость, которую он описывает)?

Euclidean                              Manhattan

sqrt(v.x*v.x + v.y * v.y)              abs(v.x) + abs(v.y)
sqrt(1 * 1 + 1 * 1)                    abs(1) + abs(1)
sqrt(2)                                1 + 1
1.414...                               2

Вы можете видеть, что эти метрики на самом деле не согласуются для диагональных линий.

Давайте на графике нанесем набор точек, которые каждая метрика говорит на расстоянии 1 от начала координат:

Метрики расстояния

Наша знакомая евклидова метрика - красный круг. Это множество всех точек x, y, таких что x ^ 2 + y ^ 2 = 1. Вы можете видеть, что оно вращательно-симметрично, и поэтому нам это нравится: оно аккуратно представляет идею, что расстояние не меняется с направление.

Манхэттенская метрика - это голубой бриллиант. Не очень подходит для нашего интуитивного представления о расстоянии - но это не делает его плохим. Во многих играх на основе тайлов, где вы двигаетесь дискретными шагами в четырех основных направлениях, метрика Манхэттена дает правильное расстояние между точками (с точки зрения «сколько ходов потребуется, чтобы добраться туда?»)

Наконец, я бросил методу Чебышева для удовольствия - это зеленый квадрат:

ChebyshevLength(v) = max(abs(v.x), abs(v.y))

Это также хорошо для игр на основе тайлов, где вы можете перемещаться по диагонали. Король в шахматах движется по методу Чебышева.

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


11

Без Пифагора вы привязаны к фиксированной скорости на каждой оси. У вас есть x-speed, y-speed и (в трехмерном мире) z-speed, которые не зависят друг от друга. Любое движение будет выровнено по этой перпендикулярной оси.

Однако с Пифагором у вас есть скорость, которая может быть постоянной под любым углом. Это позволяет вам заставить сетку исчезать и иметь объекты, движущиеся с постоянной скоростью в любом возможном направлении.

Область, в которой объект перемещается за одну секунду, выглядит без Пифагора (например, метрика Чебышева):

введите описание изображения здесь

И это с Пифагором:

введите описание изображения здесь

Последнее обычно кажется гораздо более естественным во многих случаях.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.