将 OpenGL 4x4 矩阵转换为旋转角度

发布于 2024-11-26 17:01:09 字数 125 浏览 0 评论 0原文

我正在 OpenGL 中提取模型矩阵 glGetFloatv (GL_MODELVIEW_MATRIX, (float*)x)

并希望从生成的 4x4 矩阵中提取 x、y 和 z 轴旋转。我怎样才能做到这一点? 谢谢 !

I am extracting in OpenGL the Model Matrix with
glGetFloatv (GL_MODELVIEW_MATRIX, (float*)x)

And would like to extract from the resulting 4x4 matrix the x,y and z axis rotations. How Can I do that ?
Thanks !

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

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

发布评论

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

评论(3

生生不灭 2024-12-03 17:01:09

首先您应该知道,x、y、z 轴旋转(称为欧拉角)会遇到严重的数值问题。而且他们也不是明确的。因此,要么存储旋转角度和旋转轴,从而有效地变相形成四元数,要么坚持使用完整的旋转矩阵。

从旋转矩阵中找到四元数称为特征值问题。从技术上讲,您正在确定旋转矩阵的特征向量,它是轴,大小指定角度。

First you should know, that x,y,z axis rotations, called Euler Angles suffer from serious numerical problems. Also they're not unambigous. So either you store a rotation angle and the rotation axis, thus effectively forming a quaternion in disguise, or you stick with the full rotation matrix.

Find the quaternion from a rotation matrix is called an eigenvalue problem. Technically you're determining the eigenvector of the rotation matrix, which is the axis and the magnitude designates the angle.

2024-12-03 17:01:09

我正在编写一个类似 CAD 的应用程序,所以我理解你的问题,我们“业内人士”知道欧拉角对于线性变换有多么糟糕 - 但最终用户发现它们比矩阵或四元数直观得多。

对于我的应用程序,我解释了 Ken Shoemake 的精彩算法,它是极少数支持任意旋转顺序的算法之一。它来自 93 年,所以是纯 C 代码 - 不适合胆小的人!

http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/

I'm writing a CAD-like app, so I understand your problem, we 'in the business' know how awful Euler angles are for linear transformations - but the end-user finds them far more intuitive than matrices or quaternions.

For my app I interpreted Ken Shoemake's wonderful algorithm, it's one of the very few that support arbitrary rotation orders. It's from '93, so it's in pure C code - not for the faint hearted!

http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/

素食主义者 2024-12-03 17:01:09

像这样的东西应该会给你你想要的东西。

final double roll = Math.atan2(2 * (quat.getW() * quat.getX() + quat.getY() * quat.getZ()),
            1 - 2 * (quat.getX() * quat.getX() + quat.getY() * quat.getY()));
final double pitch = Math.asin(2 * (quat.getW() * quat.getY() - quat.getZ() * quat.getY()));
final double yaw = Math.atan2(2 * (quat.getW() * quat.getZ() + quat.getX() * quat.getY()), 1 - 2 * (quat.getY()
            * quat.getY() + quat.getZ() * quat.getZ()));

当我使用 SLERP 在从 2 个 4x4 矩阵导出的 2 个四元数(即 2 个 3D 点之间的相机移动)之间进行插值时,我使用它作为实用函数来打印相机角度。

Something like this should give you what you're after.

final double roll = Math.atan2(2 * (quat.getW() * quat.getX() + quat.getY() * quat.getZ()),
            1 - 2 * (quat.getX() * quat.getX() + quat.getY() * quat.getY()));
final double pitch = Math.asin(2 * (quat.getW() * quat.getY() - quat.getZ() * quat.getY()));
final double yaw = Math.atan2(2 * (quat.getW() * quat.getZ() + quat.getX() * quat.getY()), 1 - 2 * (quat.getY()
            * quat.getY() + quat.getZ() * quat.getZ()));

I use this as a utility function to print out camera angles when I'm using SLERP to interpolate between 2 quaternions that I've derived from 2 4x4 matrices (i.e. camera movement between 2 3D points).

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