何时归一化矢量?

我正在学习XNA和几乎所有在http://creators.xna.com/en-US/上找到的教育工具包。 我总是在向量上看到对Normalize()的调用。 我理解,normalize基本上将向量转换为单位长度,所以它给出的只是方向。

现在我的问题是何时进行标准化以及它对我有什么帮助。我正在进行2D编程,因此请在2D概念而不是3D中进行解释。

编辑:这是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; 

}

在您的示例中,键盘按下可以让您在X或Y或两者中移动。 在X和Y的情况下,当您同时向右和向下按压时,您的运动是对角的。 但是,仅在X或Y中的运动为您提供长度为1的向量时,对角线矢量长于1。 也就是说,大约是1.4(2的平方根)。

如果不对运动矢量进行归一化,则对角线运动将比仅X或Y运动更快。 通过标准化,所有8个方向的速度都相同,我猜这是游戏所要求的。

当您需要在一个方向上移动多个单位时,向量归一化的一个常见用例。 例如,如果你有一个游戏,其中实体A以5个单位/秒的速度向实体B移动,你将获得从A到B的向量(即B - A ),你将它标准化为你只能从A的角度保持朝向实体B的方向,然后你将它乘以5个单位/秒。 生成的矢量将是A的速度,然后您可以简单地将其乘以经过的时间,以获得移动对象的位移。

这取决于你使用矢量的是什么,但是如果你只使用矢量给出一个方向,那么如果你的矢量是单位长度的话,许多算法和公式就更简单了。

例如,角度:两个单位矢量uv之间的角度theta由公式cos(theta) = uv (其中.是点积)给出。 对于非单位向量,您必须计算并除去长度: cos(theta) = (uv) / (|u| |v|)

一个稍微复杂的例子:将一个向量投影到另一个向量上。 如果v是单位向量,那么uv的正交投影由(uv) v ,而如果v是非单位向量,则公式是(uv / vv) v

换句话说:如果你知道所有你需要的是方向,并且如果你不确定向量是单位向量,那么标准化。 它可以帮助你,因为你可能最终会按照它们的长度来划分你的方向向量,所以你可能只需要在创建向量并将其完成时执行一次。

编辑:我认为在你的例子中调用Normalize的原因是为了可以将速度方向与速度区分开来。 在代码的最后一行, 10 * smoothStop是对象的速度,这很方便。 要从速度恢复速度,您需要乘以单位方向向量。

通过将每个分量除以矢量的大小来归一化任何矢量,矢量的大小由分量的平方和的平方根给出。 然后,每个分量的幅度在[-1,1]之间变化,并且幅度等于1。 这是单位矢量的定义。