经度/纬度转四元数

6
我有一组经纬度,想把它转换成四元数,请问我该如何操作?我想这么做是因为我有一个应用程序可以在球体上投影地球,并且我想从一个位置旋转到另一个位置。祝好!
3个回答

6

有一种方法可以在不使用矩阵或向量的情况下完成此操作,类似于this numpy implementation。我们可以将经度/纬度视为两个四元数旋转组合在一起。

让我们使用一个Z-up右手坐标系。我们称经度为φ,纬度为θ,并将由这两个值表示的点称为(φ, θ)。为了可视化,红轴对应X,绿色对应Y,蓝色对应Z。

我们想要找到表示从红色的(0, 0)旋转到绿色的(a, b)的四元数:

Sphere with origin and destination points

我们可以将这个旋转表示为先经度旋转,然后是纬度旋转的组合,如下所示:

First rotation Second rotation

首先,我们沿着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) 的复合旋转。四元数乘法公式有点冗长,但您可以在此处找到它。结果如下:
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个欧拉角进行操作基本相同。因此,要撤销此转换,可以使用任何四元数到欧拉角的转换,前提是旋转顺序相同。


我对“The second rotation is represented by a rotation of b degrees along the transformed/local (0, 1, 0) axis”感到困惑,如果它是本地变换的轴,为什么本地的 (0,1,0) 轴会与世界坐标系相同? - ZackOfAllTrades
@ZackOfAllTrades 你是怎么看出本地坐标 (0, 1, 0) 和世界坐标相同的?这不应该是这样的。如果有需要澄清的地方,请告诉我。 - meepzh

1

仅有经度和纬度无法描述四元数。经度和纬度可以描述三维球面上的一个点。假设这是一个法向量直接指向屏幕的点。你还有一个自由度。球体可以围绕由lat-lon指定的点的法向量旋转。如果你想要一个表示球体方向的四元数,你需要完全指定旋转。

所以假设你想要保持球体的北极朝上。如果北极与物体的+z轴对齐,并且屏幕上的“上”与世界的+y轴对齐,然后你想要旋转球体,使得球面上的点R直接指向屏幕(其中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,QR是列向量;因此,要创建一个变换矩阵,我们只需将它们粘在一起:M = [P Q R]。现在M是将世界坐标中的点转换为对象坐标的矩阵。要走相反的方向,我们找到M的逆。幸运的是,当矩阵的列正交时,逆矩阵与转置矩阵相同。所以我们得到:

             [ P^T ]
M^-1 = M^T = [ Q^T ]
             [ R^T ]

从那里开始,如果需要的话,您可以使用矩阵转四元数找到一个四元数。然后,您可以使用slerp或您选择的方法在四元数之间进行插值。


1

嗨,jon_darkstar,所以经度是phi,纬度是theta,但rho会是什么? - rick
那是 φ 吗?我忘记了 =P 早就没用过球坐标系了。我真的无法想象第三个角度会有什么作用。rho 可以只是表示大小,但为什么会有两个 phis 呢?我只能指向那个方向,祝你好运。 - jon_darkstar
我正在使用这个代码将经纬度转换为笛卡尔坐标系: ' float phi = ofDegToRad(ll.lat + 90); float theta = ofDegToRad(ll.lon - 90); x = sin(phi) * cos(theta); y = sin(phi) * sin(theta); z = cos(phi);' 现在我需要一种方法将其转换为旋转而不是坐标。旋转可以是轴/角度或四元数。 - rick
我可能漏掉了什么,但笛卡尔坐标系不会让你离你所需的更远吗?纬度和经度是角度。 - jon_darkstar

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