3d 将鼠标拖动运动转换为对象三维旋转的最佳方法

3d 将鼠标拖动运动转换为对象三维旋转的最佳方法,3d,3d,我有一个3d对象,我希望能够在3d中旋转。最简单的方法是直接将X和Y鼠标运动转换为绕Y和X轴旋转,但如果沿两个轴都有一些旋转,则模型旋转的方式会变得非常违反直觉(即,如果将对象围绕一个轴翻转180度,则沿另一个轴的运动会反转) 我可以简单地使用上面的方法,但是我可以存储完整的旋转矩阵,而不是存储绕两个轴旋转的量,然后在每次鼠标拖动时沿相同的轴进一步旋转,但我担心这会很快产生精度问题。创建一个累加器矩阵并用标识初始化它 在绘制对象之前,将每个帧应用于模型视图/世界矩阵状态 鼠标移动时,围绕X轴构造

我有一个3d对象,我希望能够在3d中旋转。最简单的方法是直接将X和Y鼠标运动转换为绕Y和X轴旋转,但如果沿两个轴都有一些旋转,则模型旋转的方式会变得非常违反直觉(即,如果将对象围绕一个轴翻转180度,则沿另一个轴的运动会反转)


我可以简单地使用上面的方法,但是我可以存储完整的旋转矩阵,而不是存储绕两个轴旋转的量,然后在每次鼠标拖动时沿相同的轴进一步旋转,但我担心这会很快产生精度问题。

创建一个累加器矩阵并用标识初始化它

在绘制对象之前,将每个帧应用于模型视图/世界矩阵状态

鼠标移动时,围绕X轴构造一个旋转矩阵,具有一定的灵敏度常数*δX。为其他组件构建另一个绕Y轴的旋转矩阵。在累加器上乘以一个,然后再乘以另一个

移动鼠标时,累加器将发生变化。绘制时,它将按预期定向对象


而且,谈论四元数的人是对的;这仅适用于小的增量更改。如果在对角线上快速拖动,它将不会按照预期的方式旋转。

可以通过重新规范化旋转矩阵来处理精度损失,使3行中的每一行再次垂直。或者,您可以根据有关对象的现有信息重新生成要修改的旋转矩阵,这样就不需要重新规范化

或者,您可以使用,这是处理旋转的Euler角度的替代方法


在我早期的日子里,我从中了解了很多这方面的知识,它在中处理了这个问题(尽管是在另一个应用程序中)。

最直观的方法可能是围绕垂直于当前拖动方向的轴旋转对象,可以是随着每次鼠标移动而递增,也可以是相对于拖动开始位置。这两个选项提供的用户交互略有不同,各有优缺点

有一种方法可以将表示旋转轴的角度和3d矢量转换为旋转矩阵

您是对的,通过增量旋转更新原始旋转矩阵将导致矩阵不再是纯旋转矩阵。这是因为3x3旋转矩阵的数据量是表示旋转所需数据量的三倍

表示旋转的一种更简洁的方法是使用,具有最小的3值向量。可以将当前旋转作为Euler角度向量,将其转换为矩阵,应用旋转(增量或其他),然后将矩阵转换回Euler角度向量。最后一步将自然地消除矩阵中的任何非旋转分量,这样,下一个状态的纯旋转矩阵将再次结束

欧拉角在概念上很好,但是来回转换需要做很多工作

更实际的选择是(),它是四个元素向量。这四个元素指定旋转和均匀缩放,如果您将向量规格化为单位长度,您将得到1.0的缩放因子。事实证明,角度轴值也可以通过以下方式轻松转换为四元数值:

q.x = sin(0.5*angle) * axis.x;
q.y = sin(0.5*angle) * axis.y;
q.z = sin(0.5*angle) * axis.z;
q.w = cos(0.5*angle);
然后,可以获取当前旋转四元数和增量旋转四元数的四元数乘积(仅使用简单的乘法和加法),以获得表示执行两个旋转的新四元数。此时,您可以规范化长度以确保纯旋转,但也可以继续迭代组合旋转


当您希望使用传统图形API显示处于旋转状态的模型时,将四元数转换为旋转矩阵非常简单(仅使用乘法和加法)。

在我的计算机图形课程中,我们获得了以下代码,这使我们不必重新发明轮子


我高估了浮点不精确的影响。简单地累积旋转就可以了。我会研究四元数,但因为我只绕两个轴旋转,所以一切看起来都很好。