Когда нормализовать вектор?

Я изучаю XNA и почти во всех обучающих наборах, найденных на http://creators.xna.com/en-US/. Я всегда вижу вызов Normalize() для вектора. Я понимаю, что нормализация в основном преобразует вектор в единицу длины, поэтому все это дает направление.

Теперь мой вопрос: когда нормализовать и что именно мне это помогает. Я занимаюсь 2D-программированием, поэтому, пожалуйста, объясните в 2D-концепциях, а не в 3D.

EDIT: вот код в наборе XNA, так почему называется Normalize?

if (currentKeyboardState.IsKeyDown(Keys.Left) ||
            currentGamePadState.DPad.Left == ButtonState.Pressed)
        {
            catMovement.X -= 1.0f;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Right) ||
            currentGamePadState.DPad.Right == ButtonState.Pressed)
        {
            catMovement.X += 1.0f;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Up) ||
            currentGamePadState.DPad.Up == ButtonState.Pressed)
        {
            catMovement.Y -= 1.0f;
        }
        if (currentKeyboardState.IsKeyDown(Keys.Down) ||
            currentGamePadState.DPad.Down == ButtonState.Pressed)
        {
            catMovement.Y += 1.0f;
        }


        float smoothStop = 1;


        if (catMovement != Vector2.Zero)
        {
            catMovement.Normalize();
        }

        catPosition += catMovement * 10* smoothStop;

}

Ответ 1

В вашем примере нажатия клавиш дают вам движение в X или Y, или и то, и другое. В случае как X, так и Y, как при одновременном нажатии вправо и влево, ваше движение диагонально. Но когда движение только в X или Y дает вам вектор длины 1, диагональный вектор длиннее одного. То есть около 1,4 (квадратный корень из 2).

Без нормализации вектора движения, диагональное движение будет быстрее, чем просто движение X или Y. При нормализации скорость одинакова во всех 8 направлениях, и я думаю, это то, что требует игра.

Ответ 2

Один общий вариант использования векторной нормализации, когда вам нужно что-то переместить на несколько единиц в направлении. Например, если у вас есть игра, в которой объект A перемещается к объекту B со скоростью 5 единиц в секунду, вы получите вектор от A до B (который равен B - A), вы нормализуете его так вы только сохраняете направление к объекту B с точки зрения, а затем умножаете его на 5 единиц в секунду. Результирующим вектором будет скорость A, и вы можете просто умножить его на прошедшее время, чтобы получить смещение, с помощью которого вы можете перемещать объект.

Ответ 3

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

Например, углы: угол theta между двумя единичными векторами u и v определяется формулой cos(theta) = u.v (где . является точечным произведением). Для неединичных векторов вам необходимо вычислить и разделить длины: cos(theta) = (u.v) / (|u| |v|).

Несколько более сложный пример: проекция одного вектора на другой. Если v - единичный вектор, то ортогональная проекция u на v задается выражением (u.v) v, а если v - неединичный вектор, то формула (u.v / v.v) v.

Другими словами: нормализовать, если вы знаете, что все, что вам нужно, - это направление, и если вы не уверены, что вектор уже является единичным вектором. Это помогает вам, потому что вы, вероятно, в конечном итоге разделите свои векторы направления по их длине все время, поэтому вы можете просто сделать это один раз, когда вы создадите вектор и перейдете к нему.

EDIT: Я предполагаю, что причина Normalize вызывается в вашем примере, так что направление скорости можно отличить от скорости. В последней строке кода 10 * smoothStop - скорость объекта, что удобно знать. Чтобы восстановить скорость со скоростью, вам нужно умножить на единичный вектор направления.

Ответ 4

Вы нормализуете любой вектор, разделив каждый компонент на величину вектора, который задается квадратным корнем из суммы квадратов компонентов. Затем каждый компонент имеет величину, которая изменяется между [-1, 1], а величина равна единице. Это определение единичного вектора.