6

我有一个经度和纬度,想把它转换成四元数,想知道我该怎么做?我想使用它,因为我有一个将地球投影到球体上的应用程序,我想从一个位置旋转到另一个位置。

最好的!

4

3 回答 3

5

有一种方法可以在不使用矩阵或向量的情况下解决这个问题,类似于这个 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 ) 的复合旋转。四元数乘法的公式有点长,但你可以在这里找到。结果:

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 个欧拉角基本相同。因此,要反转这种转换,您可以使用任何四元数到欧拉角的转换,前提是旋转顺序相同。

于 2017-11-14T05:01:37.600 回答
1

Latitude and longitude aren't enough to describe a quaternion. Latitude and longitude can describe a point on the surface of a 3d sphere. Let's say that's the point whose normal points directly out through the screen. You still have a degree of freedom left. The sphere can spin around the normal vector of the point specified by lat-lon. If you want a quaternion that represents the orientation of the sphere, you need to fully specify the rotation.

So let's say that you want to keep the north-pole of the sphere pointed upward. If the north pole is aligned with the object's +z axis and 'up' on the screen is aligned with the world's +y axis, and then you want to rotate the sphere so that point R on the surface of the sphere is pointed directly out at the screen (where R is found using lat-lon to euclidean as you mentioned in your comment), then you create the rotation matrix as follows.

You want object's R to align with the world's +z (assuming an OpenGL-like view-coordinate system) and you want object's +z to align with world's +y (as close as possible). We need the third axis; so we normalize R and then find: P = crossP([0 0 1]^T,R). We normalize P and then enforce orthogonality onto the second axis: Q = crossP(R,P). Finally, normalize Q. Now we have 3 orthogonal vectors P, Q, R that we want to align with the world's x,y,z respectively.

I'm assuming that P, Q, and R are column vectors; so to create a transformation matrix, we just stick 'em together: M = [P Q R]. Now M is the matrix that would transform a point in world coordinates into object coordinates. To go the opposite direction, we find the inverse of M. Fortunately, when the columns of a matrix are orthonormal, the inverse is the same as the transpose. So we get:

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

From that, if you need, you can find a quaternion using matrix to quaternion conversion. And then you can interpolate between quaternions using slerp or your method of choice.

于 2011-05-06T15:09:50.367 回答
1

也许你可以看看 boost C++ 库是如何实现它的。(或者甚至使用它)http://www.boost.org/doc/libs/1_46_0/libs/math/doc/quaternion/html/boost_quaternions/quaternions/create.html

经度和纬度与球坐标中的方位角 (theta - [0, 2*PI]) 和倾角 (rho? [0,PI]) 非常相似(表面的半径 r=1)。Boost 在我发布的链接中具有球面到四元数的功能。

于 2011-03-25T20:49:07.383 回答