我有一个经度和纬度,并希望将其转换为四元数,并想知道我该怎么做?我想用这个,因为我有一个应用程序,它将地球投射到球体上,我想从一个位置旋转到另一个位置。
最佳!
答案 0 :(得分:2)
有一种方法可以在不使用矩阵或向量的情况下实现这一点,类似于this numpy implementation。我们可以将经度/纬度视为两个四元数旋转组合在一起。
让我们使用Z-up右手坐标系。我们将经度φ和纬度θ称为,并将由两者表示的点称为(φ,θ)。对于可视化,红色轴对应于X,绿色对应Y,蓝色对应Z.
我们希望找到表示旋转的四元数,从(0,0),红色,到( a , b ),绿色:
我们可以将此旋转表示为纵向旋转的第一个组合,然后是纬度旋转的组合,如下所示:
首先,我们沿着Z轴旋转 a ,这会转换X轴和Y轴。然后,我们沿着新的局部Y轴旋转 b 。因此,我们知道这种旋转的两组轴/角度信息。
幸运的是,从轴/角度到四元数的转换是已知的。给定角度α和轴向量ω,得到的四元数为:
(cos(α/2), ω.x*sin(α/2), ω.y*sin(α/2), ω.z*sin(α/2))
所以第一次旋转由沿着世界(0,0,1)轴的 a 度的旋转表示,给我们:
q1 = (cos(a/2), 0, 0, sin(a/2))
第二次旋转由沿着变换/局部(0,1,0)轴的 b 度的旋转表示,给我们:
q2 = (cos(b/2), 0, sin(b/2), 0)
我们可以将这两个四元数相乘,得到一个单个四元数,表示从(0,0)到( a , b)的复合旋转 强>)。四元数乘法的公式有点冗长,但您可以找到它here。结果:
q2*q1 = (cos(a/2)cos(b/2), -sin(a/2)sin(b/2), cos(a/2)sin(b/2), sin(a/2)cos(b/2))
这并不意味着很多,但我们可以确认这个公式与之前提到的numpy实现相同。
JCooper提到了一个很好的观点,即在这种情况下,沿X轴仍然存在一个自由度。如果θ保持在±90度范围内,我们可以想象Z轴总是指向上方。这具有约束X轴旋转的效果,并且希望是你想要的。
希望这有帮助!
编辑:请注意,这与使用2个欧拉角度基本相同。因此,要反转此转换,您可以使用任何四元数进行欧拉角度转换,前提是旋转顺序相同。
答案 1 :(得分:1)
也许你可以看一下boost C ++库如何实现它。 (或者甚至可能使用它)http://www.boost.org/doc/libs/1_46_0/libs/math/doc/quaternion/html/boost_quaternions/quaternions/create.html
经度和纬度非常类似于球面坐标中的方位角(θ - [0,2 * PI])和倾角(rho?[0,PI])角度(当然,曲面的半径r = 1)。 Boost在我发布的链接中有一个球形到四元数的函数。
答案 2 :(得分:1)
纬度和经度不足以描述四元数。纬度和经度可以描述3d球体表面上的点。让我们说这是正常点直接通过屏幕的点。你还有一定程度的自由。球体可以围绕lat-lon指定的点的法向量旋转。如果需要表示球体方向的四元数,则需要完全指定旋转。
所以,让我们说你想保持球体的北极指向上方。如果北极与对象的 + z 轴对齐,屏幕上的“向上”与世界的 + y 轴对齐,然后您想要旋转球体所以球体表面上的 R 点直接指向屏幕(如你在评论中提到的那样,使用lat-lon到euclidean找到 R ),然后按如下方式创建旋转矩阵。
您希望对象的 R 与世界的 + z (假设类似OpenGL的视图坐标系统)对齐,并且您希望对象的 + z 与世界的 + y (尽可能接近)保持一致。我们需要第三轴;所以我们将 R 标准化,然后找到: P = crossP([0 0 1] ^ T,R)。我们将 P 标准化,然后在第二轴上强制正交: Q = crossP(R,P)。最后,规范化 Q 。现在我们有3个正交向量 P,Q,R ,我们希望分别与世界的 x,y,z 对齐。
我假设 P,Q,和 R 是列向量;所以为了创建转换矩阵,我们只需将它们粘在一起: M = [P Q R] 。现在 M 是将世界坐标中的点转换为对象坐标的矩阵。为了反方向,我们找到 M 的倒数。幸运的是,当矩阵的列是正交的时,反转与转置相同。所以我们得到:
[ P^T ]
M^-1 = M^T = [ Q^T ]
[ R^T ]
由此,如果需要,您可以使用matrix to quaternion conversion找到四元数。然后,您可以使用slerp或您选择的方法在四元数之间进行插值。