glm::normalize函数是什么?

8

我正在尝试从C++源代码中用Java编写MD5加载器,但我无法弄清楚这行代码的作用:

animatedJoint.m_Orient = glm::normalize(animatedJoint.m_Orient);

animatedJoint.m_Orientvec4类型的,它的作用是什么?

4个回答

16

glm::normalize是做什么用的?

简短回答:它将一个向量规范化,即将长度设置为1。

细节

规范化的向量经常用来表示纯方向而不用考虑大小(设为1,因此它们也被称为单位向量),即向量的推动距离并不重要,而指向/推动的方向很重要。这样可以简化计算 - 无论是在纸上还是在机器上(例如点积成为余弦结果,省略除以长度等)

如果v = <v.x,v.y,v.z>是某个非单位向量,即长度/幅值不等于1的向量,则要获得normalized(v),我们必须将其每个分量除以它的长度。

vec3 normalize(const vec3 &v)
{
   float length_of_v = sqrt((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
   return vec3(v.x / length_of_v, v.y / length_of_v, v.z / length_of_v);
}
一个旧的术语用于表示单位向量是 方向余弦 。假设向量 v 分别与 X 轴成角度 α,与 Y 轴成角度 β,与 Z 轴成角度 γ,那么沿着 v 的方向余弦或单位向量由<cos α,cos β,cos γ> 给出。当我们不知道 v 的分量但知道它与基本轴的角度时,这是很有帮助的。 余弦函数和单位向量之间的关系将通过一个简单的二维示例变得清晰,该示例可以扩展到更高维度。假设对于一个向量,...
v = <3, 4> = 3i + 4j (3 units along X-axis and 4 units along Y-axis)

我们需要找到沿着v的单位向量u。

length of v = √(3² + 4²) = 5
u = <3/5, 4/5>
现在,X分量(沿基向量i)的3/5实际上就是沿X轴的长度(相邻边)除以向量长度(斜边),因为cos α = adj/hyp = 3/5,如果我们已知α,也会得出同样的结果。Y分量(沿基向量j)同理,它实际上就是cos β,其中β是相对于Y轴的角度,或者如果你想相对于X轴测量它,那么它将是90-β,这实际上就是α,这就是为什么我们有v = <cos α, sin α>,这是单位圆上一点的横坐标和纵坐标,从原点到圆上一点的向量长度为半径1。

1
严格来说,法向量确实有大小。然而,关键在于其大小恰好等于1(你知道的,除了浮点舍入误差),因此在许多地方不需要考虑长度。例如,要投影到普通向量上,需要除以长度;要投影到法向量上,则不需要,因为长度为1,任何数除以1都是它本身。 - anon
@NicHartley 你说得对,我应该表述得更明确一些。我想区分一下单位法线和普通法线;后者的方向比长度更有用,长度可能是1,也可能不是,但通常对于简单的公式和计算来说长度为1。现在已经澄清了 :) - legends2k
不错!我其实没想到会有回复,哈哈。最终来说这也不是非常重要——区别相当微小。然而,在少数情况下,如果不知道归一化向量只是具有1的大小的普通向量,那么它确实会让你很困扰,所以我觉得至少在注释中澄清一下。 - anon

7

对一个向量进行归一化,即按比例缩放其元素,使返回的向量长度为1。 许多与图形相关的函数要求传递的向量必须是已经归一化的。


6

该代码将animatedJoint.m_Orient向量进行规范化,通过获取该向量的法线并将其复制回向量本身。 glm::normalize() 方法不会修改您传递给它的对象。


4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接