【问题标题】:Length of vector using quaternions使用四元数的向量长度
【发布时间】:2017-01-03 17:14:00
【问题描述】:

是否可以通过将向量旋转到轴并沿轴旋转来计算向量的长度,然后使用该轴来测量向量的长度?如果是这样,它是否比通过毕达哥拉斯/平方根计算长度便宜? 我正在团结工作(C#)

例子:

Vector3 myVector(x, y, z);
Vector3 myVectorRealigned = Quaternion.FromToRotation(myVector, Vector3.up) * myVector;

float myVectorLength1 = sqrt(myVector.x^2 + myVector.y^2 + myVector.z^2);
float myVectorLength2 = myVectorRealigned.y;

当我尝试这个时,它似乎工作!然而,这些方法中哪一种最好用/最便宜?

【问题讨论】:

  • 如果您使用的是 Visual Studio,它有一个内置的分析器。它会让你衡量两者的表现。
  • 我建议@BrandonIbbotson 所说的,但我可以想象规范会更快,因为四元数计算也需要 sqrt 并且旋转涉及比规范更多的乘法。
  • 为了性能,有时最好不要平方和。比如当你想比较距离时。
  • 通过旋转计算向量长度是一个完全坏主意,因为您正在计算三个分量,其中两个将为零。不算,要获得轮换,您需要规范等等。

标签: c# optimization unity3d quaternions


【解决方案1】:

我不是数学家,如果我错了,请纠正我。

正如您所测试的,这两种方法都应该有效,但我猜四元数方法的成本更高。

范数方法需要 3 次乘法、2 次加法和 1 次平方。

相比之下,仅四元数方法 (Quaternion.FromToRotation) 的第一步需要比计算范数更昂贵。一种计算描述从一个向量到另一个向量的旋转的四元数的方法是这样的:

Quaternion q;
vector a = crossproduct(v1, v2)
q.xyz = a;
q.w = sqrt((v1.Length ^ 2) * (v2.Length ^ 2)) + dotproduct(v1, v2)

如您所见,仅此一项就比norm = sqrt(myVector.x^2 + myVector.y^2 + myVector.z^2) 更昂贵。

此外,您使用该四元数再次旋转矢量涉及点积、叉积以及多次乘法和加法。

例如:rotatedVec = 2 * dot(q.xyz, v) * q.xyz + (q.w^2 - dot(q.xyz, q.xyz)) * v + 2 * q.w * cross(q.xyz, v).

参考:from-to-quaternionrotate vector by quaternion

旁注:如果您关心性能并且不需要向量的确切长度(例如,用于确定最接近位置 x 的对象),您可以使用 Vector3.sqrMagnitude (平方范数)也是如此。

【讨论】:

    猜你喜欢
    • 2019-02-24
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 1970-01-01
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多