经度/纬度到四元数

发布于 2024-10-27 03:30:52 字数 96 浏览 0 评论 0原文

我有经度和纬度,想将其转换为四元数,想知道如何做到这一点?我想使用这个,因为我有一个应用程序,它将地球投影在一个球体上,我想从一个位置旋转到另一个位置。

最好的!

I've got a longitude and latitude and want to convert this to a quaternion and wondering how I can do this? I want to use this, because I've got an app which projects the earth on a sphere and I want to rotate from one location to another one.

Best!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

惯饮孤独 2024-11-03 03:30:52

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

让我们使用 Z 向上右手坐标系。我们将经度称为 φ,将纬度称为 θ,将两者表示的点称为 (φ, θ)。为了可视化,红色轴对应于 X,绿色轴对应于 Y,蓝色轴对应于 Z。

我们想要找到代表从 (0, 0) 旋转的四元数,红色为 (ab),绿色:

具有起点和终点的球体

我们可以将此旋转表示为纵向旋转的组合,然后是纬度旋转,如下所示:

第一次旋转
第二次轮换

首先,我们沿 Z 轴旋转a,从而变换 X 轴和 Y 轴。然后,我们沿着新的局部 Y 轴旋转 b。因此,我们知道该旋转的两组轴/角度信息。

幸运的是,从轴/角度到四元数的转换是已知的。给定角度 α 和轴向量 ω,得到的四元数为:

(cos(α/2), ω.x*sin(α/2), ω.y*sin(α/2), ω.z*sin(α/2))

因此,第一次旋转表示为沿世界旋转 a 度 (0, 0, 1 ) 轴,给我们:

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

There's a way to go about this without using matrices or vectors, similar to this numpy implementation. We can think of longitude/latitude as two quaternion rotations composed together.

Let's work with a Z-up right-handed coordinate system. Let's call longitude φ and latitude θ, and the point represented by the two as (φ, θ). For visualization, the red axis corresponds to X, green to Y, and blue to Z.

We want to find the quaternion representing the rotation from (0, 0), in red, to (a, b), in green:

Sphere with origin and destination points

We can represent this rotation as a combination first of the longitudinal rotation, then of the latitudinal rotation, like so:

First rotation
Second rotation

First, we rotated by a along the Z axis, which transforms the X and Y axes. Then, we rotated by b along the new local Y axis. Thus, we know two sets of axis/angle information for this rotation.

Luckily, the conversion from axis/angle to quaternions is already known. Given an angle α and an axis vector ω, the resulting quaternion is:

(cos(α/2), ω.x*sin(α/2), ω.y*sin(α/2), ω.z*sin(α/2))

So the first rotation is represented by a rotation of a degrees along the world (0, 0, 1) axis, giving us:

q1 = (cos(a/2), 0, 0, sin(a/2))

The second rotation is represented by a rotation of b degrees along the transformed/local (0, 1, 0) axis, giving us:

q2 = (cos(b/2), 0, sin(b/2), 0)

We can multiply these two quaternions to give us a single quaternion representing this compound rotation from (0, 0) to (a, b). The formula for quaternion multiplication is a bit lengthy, but you can find it here. The result:

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))

Not that it means much, but we can confirm that this formula is the same as the numpy implementation mentioned before.

JCooper mentioned a great point that one degree of freedom is still left, along the X axis in this case. If θ stays within ±90 degrees, we can imagine that the Z axis always pointing upwards. This has the effect of constraining the X axis rotation and is hopefully what you want.

Hope this helps!


edit: Notice that this is essentially the same thing as working with 2 Euler angles. So to reverse this conversion, you can use any quaternion to Euler angle conversion, provided that the rotation order is the same.

黒涩兲箜 2024-11-03 03:30:52

纬度和经度不足以描述四元数。纬度和经度可以描述 3d 球体表面上的点。假设该点的法线直接穿过屏幕。你仍然有一定程度的自由。球体可以绕经纬度指定点的法线向量旋转。如果您想要一个代表球体方向的四元数,则需要完全指定旋转。

假设您希望保持球体的北极朝上。如果北极与物体的 +z 轴对齐,并且屏幕上的“向上”与世界的 +y 轴对齐,然后您想要旋转球体这样球体表面上的点 R 直接指向屏幕(正如您在评论中提到的,使用经纬度到欧几里德找到 R ),然后按如下方式创建旋转矩阵。

您希望对象的 R 与世界的 +z 对齐(假设类似 OpenGL 的视图坐标系),并且希望对象的 +z 与世界的 +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 = [PQR]。现在M是将世界坐标中的点转换为对象坐标的矩阵。为了走向相反的方向,我们找到M的倒数。幸运的是,当矩阵的列正交时,逆矩阵与转置相同。所以我们得到:

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

由此,如果需要,您可以使用 矩阵到四元数的转换。然后您可以使用 slerp 或您选择的方法在四元数之间进行插值。

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.

梦幻的心爱 2024-11-03 03:30:52

也许你可以看看 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 有一个用于球形到四元数的函数。

Maybe you could look into how the boost C++ library implements it. (or perhaps even using it) http://www.boost.org/doc/libs/1_46_0/libs/math/doc/quaternion/html/boost_quaternions/quaternions/create.html

Longitude and lattitude are pretty much analogous to the azimuth (theta - [0, 2*PI]) and inclination (rho? [0,PI]) angles in spherical coordinates (radius r=1 of course for surface). Boost has a function for spherical to quaternion in the link i posted.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文