C++ 为什么我们需要单位向量(换句话说,为什么我们需要对向量进行归一化)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2304634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why do we need a Unit Vector (in other words, why do we need to normalize vectors)?
提问by numerical25
I am reading a book on game AI.
我正在阅读一本关于游戏 AI 的书。
One of the terms that is being used is to normalize a vector which is to turn a vector into a unit. To do so you must divide each dimension x
, y
and z
by its magnitude.
正在使用的术语之一是归一化向量,即将向量转换为一个单位。要做到这一点,您必须将每个维度x
,y
并z
通过它的大小。
We must turn vector into a unit before we do anything with it. Why?
在我们对它做任何事情之前,我们必须把它变成一个单位。为什么?
And could anyone give some scenarios where we must use a unit vector?
谁能给出一些我们必须使用单位向量的场景?
Thanks!
谢谢!
采纳答案by John D. Cook
You don't have to normalize vectors, but it makes a lot of equations a little simpler when you do. It could also make API's smaller: any form of standardization has the potential to reduce the number of functions necessary.
您不必对向量进行归一化,但这样做会使许多方程变得更简单。它还可以使 API 更小:任何形式的标准化都有可能减少必要的功能数量。
Here's a simple example. Suppose you want to find the angle between two vectors u and v. If they are unit vectors, the angle is just arccos(uv). If they're not unit vectors, the angle is arccos(uv/(|u| |v|)). In that case, you end up computing the norms of u and v anyway.
这是一个简单的例子。假设你想找到两个向量 u 和 v 之间的角度。如果它们是单位向量,角度就是 arccos(u v)。如果它们不是单位向量,则角度为 arccos(uv/(|u| |v|))。在这种情况下,您最终还是要计算 u 和 v 的范数。
回答by James
As John D. Cook says - mainly you're doing this because you care about the direction, not the vector itself. Depending on context, you more than likely don't want / need the magnitude information - just the direction itself. You normalize to strip away the magnitude so that it doesn't skew other calculations, which in turn simplifies many other things.
正如约翰·D·库克所说 - 主要是你这样做是因为你关心方向,而不是矢量本身。根据上下文,您很可能不需要/不需要幅度信息 - 只是方向本身。您进行标准化以去除幅度,这样它就不会歪曲其他计算,这反过来又简化了许多其他事情。
In terms of AI - imagine you take the vector V between P1(the AI bad guy) and P2 (your hero) as the direction for the bad guy to move. You want the bad guy to move at a speed N per beat - how do you calculate this? Well, we either normalize the vector each beat, multiply by N to figure out how far they moved, or we pre-normalize the direction in the first place, and just multiply the unit vector by N each time - otherwise the bad guy would move further if it were further away from the hero! If the hero doesn't change position, that's one less calculation to worry about.
在 AI 方面 - 假设您将 P1(AI 坏人)和 P2(您的英雄)之间的向量 V 作为坏人移动的方向。你想让坏人以每节拍 N 的速度移动 - 你如何计算这个?好吧,我们要么对每个节拍的向量进行归一化,乘以 N 以计算出它们移动了多远,要么我们首先对方向进行预归一化,然后每次将单位向量乘以 N - 否则坏人会移动离英雄越远越远!如果英雄不改变位置,那就少了一个需要担心的计算。
In that context, it's not a big deal - but what if you have a hundred bad guys? Or a thousand? What if your AI needs to deal with combinations of bad guys? Suddenly it's a hundred or thousand normalizations you're saving per beat. Since this is a handful of multiplies and a square root for each, eventually you reach the point where not normalizing the data ahead of time means you're going to kill your AI processing rate.
在这种情况下,这没什么大不了的——但如果你有一百个坏人呢?还是一千?如果你的 AI 需要处理坏人的组合怎么办?突然间,您每节拍节省了成百上千的标准化。由于这是少数乘法和每个乘法的平方根,最终你会达到不提前规范化数据意味着你将扼杀人工智能处理率的地步。
More broadly - math for this is really common - people are doing here what they do for things like 3D rendering - if you didn't unitize, for instance, the normals for your surfaces, you'd have potentially thousands of normalizations per rendering which are completely unnecessary. You have two options: one - make each function perform the calculation, or two - pre-normalize the data.
更广泛地说 - 这方面的数学真的很常见 - 人们在这里做他们为 3D 渲染做的事情 - 如果你没有统一,例如,你的表面的法线,你每次渲染可能会有数千个归一化完全没有必要。您有两种选择:一个 - 让每个函数执行计算,或者两个 - 预规范化数据。
From the framework designer's perspective: the latter is inherently faster - if we assume the former, even if your user thinks to normalize the data, they're going to have to go through the same normalization routine OR you're going to have provide two versions of each function, which is a headache. But at the point you're making people think about which version of the function to call, you may as well make them think enough to call the correct one, and only provide it in the first place, making them do the right thing for performance.
从框架设计者的角度来看:后者本质上更快 - 如果我们假设前者,即使您的用户想对数据进行规范化,他们也将不得不经历相同的规范化例程,或者您将不得不提供两个每个函数的版本,这是一个令人头疼的问题。但是当你让人们考虑调用哪个版本的函数时,你也可以让他们充分思考调用正确的函数,并且只在第一时间提供它,让他们为性能做正确的事情.
回答by smaclell
You are often normalizing a vector because you only care about the direction the vector points and not the magnitude.
您经常对向量进行归一化,因为您只关心向量指向的方向而不是大小。
A concrete scenario is Normal Mapping. By combining light striking the surface and vectors that are perpendicular to the surface you can give an illusion of depth. The vectors from the surface define the parallel direction and the magnitude to the vector would actual make calculations wrong.
一个具体的场景是法线贴图。通过结合照射表面的光和垂直于表面的矢量,您可以产生深度错觉。来自表面的向量定义了平行方向,向量的大小实际上会使计算出错。
回答by duffymo
We must we turn a vector into units before we do anything with it.
在我们对它做任何事情之前,我们必须把它变成单位。
This statement is incorrect. All vectors are not unit vectors.
这种说法是不正确的。所有向量都不是单位向量。
The vectors that form the basis for a coordinate space have two very nice properties that make them easy to work with:
构成坐标空间基础的向量有两个非常好的特性,使它们易于使用:
- They're orthogonal
- They're unit vectors - magnitude = 1
- 它们是正交的
- 它们是单位向量 - 幅度 = 1
This lets you write any vector in a 3D space as a linear combination of unit vectors:
这使您可以将 3D 空间中的任何向量写为单位向量的线性组合:
(source: equationsheet.com)
(来源:equationsheet.com)
I can choose to turn this vector into a unit vector if I need to by dividing each component by the magnitude
如果需要,我可以选择将此向量转换为单位向量,方法是将每个分量除以幅度
(source: equationsheet.com)
(来源:equationsheet.com)
If you don't know that coordinate spaces or basis vectors are, I'd recommend learning a little more about the mathematics of graphics before you go much further.
如果您不知道坐标空间或基向量是什么,我建议您在进一步了解图形数学之前多学习一点。
回答by Escualo
In addition to the answers already provided, I would mention two important aspects.
除了已经提供的答案之外,我还要提到两个重要方面。
Trigonometry is defined on a unit circle
三角函数定义在单位圆上
All trigonometric functions are defined over a unit circle. The number pi
itself is defined over a unit circle.
所有三角函数都定义在一个单位圆上。数字pi
本身是在单位圆上定义的。
When you normalize vectors, you can use all trigonometric functions directly, without any rounds of scaling. As mentioned earlier, the angle between two unit vectors is simply: acos(dot(u, v))
, without further scaling.
当您归一化向量时,您可以直接使用所有三角函数,无需任何轮次缩放。如前所述,两个单位向量之间的角度很简单:acos(dot(u, v))
,无需进一步缩放。
Unit vectors allow us to separate magnitude from direction
单位向量允许我们将大小与方向分开
A vector can be interpreted as a quantity carrying two types of information: magnitude and direction. Force, velocity, and acceleration are important examples.
向量可以解释为携带两种类型信息的量:大小和方向。力、速度和加速度是重要的例子。
If you wish to deal separatelywith the magnitude and direction, a representation of the form vector = magnitude * direction
, where magnitude
is a scalar and direction
a unit vector, is often very convenient: Changes in magnitude entail scalar manipulations, and changes in direction do not modify the magnitude. The direction
has to be a unit vector to ensure that the magnitude of vector
is exactly equal to magnitude
.
如果你想处理分别与大小和方向,形式的表示vector = magnitude * direction
,这里magnitude
是一个标量和direction
单位向量,往往是很方便的:变化幅度继承权标量操作,并且改变方向不改变大小。的direction
必须是一个单位矢量,以确保的大小vector
正好等于magnitude
。