我正在学习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;
}
答案 0 :(得分:10)
在您的示例中,键盘按下可以让您在X或Y或两者中移动。在X和Y的情况下,当您同时向右和向下按压时,您的运动是对角线。但是,仅在X或Y中的移动给出了长度为1的向量,对角线向量长于1。也就是说,大约是1.4(2的平方根)。
如果不对运动矢量进行标准化,则对角线运动将比仅X或Y运动更快。通过标准化,所有8个方向的速度相同,我猜这是游戏所要求的。
答案 1 :(得分:3)
当您需要在某个方向上移动多个单位时,向量归一化的一个常见用例。例如,如果您有一个游戏,其中实体A以5个单位/秒的速度向实体B移动,您将获得从A到B的向量(即B - A
),您将标准化所以你只能从A的角度保持朝向实体B的方向,然后你将它乘以5个单位/秒。结果向量将是A的速度,然后您可以简单地将其乘以经过的时间来获得移动对象的位移。
答案 2 :(得分:2)
这取决于你使用矢量的是什么,但是如果你只使用矢量给出一个方向,那么如果你的矢量是单位长度的话,那么算法和公式会更简单。
例如,角度:两个单位向量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
。
换句话说:如果你知道所有你需要的是方向,并且如果你不确定向量是单位向量,那么标准化。它可以帮助你,因为你可能最终总是按照它们的长度划分你的方向向量,所以你也可以在创建向量时将它做一次并将它完成。
编辑:我认为在你的例子中调用Normalize的原因是为了可以将速度方向与速度区分开来。在代码的最后一行,10 * smoothStop
是对象的速度,这很方便。要从速度恢复速度,您需要乘以单位方向向量。
答案 3 :(得分:0)
通过将每个分量除以矢量的大小来归一化任何矢量,矢量的大小由分量的平方和的平方根给出。然后,每个分量的幅度在[-1,1]之间变化,并且幅度等于1。这是单位矢量的定义。