我正在尝试从C++源代码中用Java编写MD5加载器,但我无法弄清楚这行代码的作用:
animatedJoint.m_Orient = glm::normalize(animatedJoint.m_Orient);
animatedJoint.m_Orient
是vec4
类型的,它的作用是什么?
我正在尝试从C++源代码中用Java编写MD5加载器,但我无法弄清楚这行代码的作用:
animatedJoint.m_Orient = glm::normalize(animatedJoint.m_Orient);
animatedJoint.m_Orient
是vec4
类型的,它的作用是什么?
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。 许多与图形相关的函数要求传递的向量必须是已经归一化的。
该代码将animatedJoint.m_Orient
向量进行规范化,通过获取该向量的法线并将其复制回向量本身。 glm::normalize()
方法不会修改您传递给它的对象。