我有一个3d对象,我希望能够在3d中旋转。最简单的方法是将X和Y鼠标运动直接转换为围绕Y和X轴的旋转,但如果沿这两个轴都有一些旋转,则模型的旋转方式将变得非常不直观(即,如果围绕一个轴将对象翻转180度,则沿另一个轴的运动将反转)。
我可以简单地执行上面的方法,但不是存储绕两个轴旋转的量,而是存储完整的旋转矩阵,并在每次鼠标拖动时沿着相同的轴进一步旋转它,但我担心这很快就会出现精度问题。
发布于 2008-09-20 06:48:12
创建累加器矩阵,并使用标识对其进行初始化。
每一帧,在绘制对象之前将其应用于模型视图/世界矩阵状态。
在鼠标移动时,使用一些sensitivity_constant * delta_x构建一个绕X轴的旋转矩阵。为另一个组件构建另一个绕Y轴的旋转矩阵。将一个相乘,然后将另一个相乘到累加器上。
当您移动鼠标时,累加器将发生变化。绘制时,它将按照您的预期调整对象的方向。
此外,谈论四元数的人是对的;这只适用于小的增量变化。如果您在对角线上快速拖动它,它将不会像您预期的那样旋转。
发布于 2008-09-20 07:26:41
围绕垂直于当前拖动方向的轴旋转对象可能是最直观的方式,可以随着每次鼠标移动而递增旋转,也可以相对于拖动开始位置旋转。这两个选项给出的用户交互略有不同,各有优缺点。
有一种relatively straightforward方法可以将表示被旋转的轴的角度和3d矢量转换为旋转矩阵。
您是对的,通过增量旋转更新原始旋转矩阵将导致矩阵不再是纯旋转矩阵。这是因为3x3旋转矩阵具有的数据量是表示旋转所需数据量的三倍。
表示旋转的一种更紧凑的方法是使用Euler Angles,它具有最小的3值向量。可以将当前旋转作为Euler角度向量,将其转换为矩阵,应用旋转(增量或其他方式),然后将矩阵转换回Euler角度向量。最后一步将自然地消除矩阵中的任何非旋转分量,以便您再次为下一个状态得到一个纯旋转矩阵。
Euler角度在概念上很好,但是来回转换需要大量的工作。
更实际的选择是Quaternions (also),它是四个元素向量。这四个元素指定旋转和均匀缩放,如果您进入并将向量归一化为单位长度,您将获得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在旋转状态下显示模型时,将四元数转换为旋转矩阵非常简单(仅使用乘法和加法)。
发布于 2008-09-20 08:37:18
在我的计算机图形学课程中,我们得到了下面的代码,这些代码让我们不必重复发明轮子。
trackball.h
trackball.c
https://stackoverflow.com/questions/107413
复制相似问题