1. 垂直拖动鼠标(几乎垂直即可,因为我使用简单的阈值来过滤沿水平轴的轻微偏差)以绕y轴旋转物体(此部分已完成)。 2. 水平拖动鼠标,就像上面描述的那样,以绕x轴旋转物体(此部分也已完成)。 3. 对于z轴旋转,我希望能够检测到圆形(或弧形)鼠标移动。我卡在这一步上,不知道如何实现。
对于前两个,我只是使用atan2()来确定运动的角度。但是如何检测圆形运动呢?
我认为它不是这样工作的...
你可以将鼠标滚轮旋转转换为z轴,或者使用四元数相机方向,它能够沿着几乎直观的每个轴旋转...
对于四元数相机来说情况恰恰相反:如果试图沿着一条直线旋转网格,则网格似乎会围绕其他奇怪的轴略微旋转--为了补偿这一点,人们本能地尝试遵循一些略微弯曲的轨迹。
这个算法需要用户在检测前画出一个四分之一圆,而且它不考虑大小、方向或者大部分不规则的运动。
如果你真的想继续使用这种方法,你可以得到一个更好的算法,但是你可能需要重新考虑你的控制方法。
这不完全是你想要的,但应该足够接近。
选择一个圆形区域,在此区域内,您的移动编号1和2按照描述工作(在图片中,这将是小于红色圆圈的某个区域)。然而,当用户点击圆形区域外部时,您会保存初始点击位置(显示为绿色)。这定义了一个相对于屏幕x轴具有一定角度的点(您可以使用一些三角函数轻松找到它),并且还定义了用户正在操作的圆的半径(以红色表示)。释放鼠标会添加第二个点(蓝色)。然后,您会找到此点相对于屏幕中心和x轴的角度(就像之前一样)。然后,您将该角度投影到由第一次点击确定的圆上。深红色弧线定义了模型旋转的量。
这应该足以让你开始了。
我认为这不是一个好的输入方法,因为您总是需要一些移动距离来区分直线和曲线,这意味着会有一些输入延迟。以下是一种替代方案:
只有当垂直鼠标经过屏幕中心线时,才被视为垂直。水平鼠标同理。其他情况被视为旋转,并计算其振幅,计算方法是相对于屏幕中心计算最后一个鼠标位置和当前位置之间的角度。
或者,如果您的应用程序支持,您可以使用所选网格的中心作为输入点。
你无法以接近于三维模型视图所需的精度检测出“沿弧线的圆形”鼠标移动。你需要的是像这样的东西:http://thetechartist.com/?p=80
你可以使用键盘快捷方式或屏幕轴指示器来指定一个轴(x、y或z)。这将比尝试检测“弧线”手势要精确得多。任何“弧线”的识别都必须涉及延迟,而在此期间累积足够的鼠标样本以决定是否开始了弧线手势。类似 Wii-mote 手势识别之类的操作并不容易。同样地,即使是您简单的“垂直”和“水平”鼠标移动检测也将需要相同的延迟。任何“简单的阈值以过滤轻微偏差”的处理都会让它感觉到很迟钝和奇怪。
在进行3D查看时,您需要 1:1 的鼠标响应性能,这意味着只需使用快捷键或 UI 等明确指定一个轴。例如,如果要绕 X 轴旋转,则将它限制为鼠标的 X 坐标; 如果是绕 Y 轴旋转,则限制为鼠标的 Y 坐标。对于 Z 轴,您可以类似地限制为鼠标的 X 或 Y 坐标,或者仅采用鼠标的总 2D 移动距离。这取决于您感觉最好的方式。
作为替代方案,您可以尝试编写支持 3D 鼠标(如 3dConnexion SpaceExplorer)的代码。