在OpenGL中跟踪圆形鼠标移动

3
我正在使用C++实现一个简单的网格查看器,具有平移、旋转和缩放等基本功能。目前我卡在了使用鼠标实现物体绕z轴旋转这一步上。我想实现以下内容:
1. 垂直拖动鼠标(几乎垂直即可,因为我使用简单的阈值来过滤沿水平轴的轻微偏差)以绕y轴旋转物体(此部分已完成)。 2. 水平拖动鼠标,就像上面描述的那样,以绕x轴旋转物体(此部分也已完成)。 3. 对于z轴旋转,我希望能够检测到圆形(或弧形)鼠标移动。我卡在这一步上,不知道如何实现。
对于前两个,我只是使用atan2()来确定运动的角度。但是如何检测圆形运动呢?

2
当“几乎垂直”和“轻微圆形”基本相同时,你如何区分它们?如果移动长度约为3-4像素,则无法区分它们。 - Lyth
同意。这就是我困惑的部分。但我在一个示例网格查看器中看到了这种实现方式,这就是为什么我想尝试实现它的原因。 - user1737647
1
这是一款公开可用的软件吗?如果是,也许在YouTube上有相关视频。 - Aki Suihkonen
6个回答

0

我认为它不是这样工作的...

你可以将鼠标滚轮旋转转换为z轴,或者使用四元数相机方向,它能够沿着几乎直观的每个轴旋转...

对于四元数相机来说情况恰恰相反:如果试图沿着一条直线旋转网格,则网格似乎会围绕其他奇怪的轴略微旋转--为了补偿这一点,人们本能地尝试遵循一些略微弯曲的轨迹。


可以的。但我之所以这样做,是因为我在一个示例网格查看器中看到了这种实现方式(我没有源代码),我真的想找出它是如何完成的。感谢您的评论! - user1737647

0
也许你应该定义一个屏幕区域(例如在窗口边界),当被点击时,将启动圆弧运动 - 或使用其他修改器,如按钮或任何其他东西。
然后,在鼠标点击时,您捕获2D屏幕空间中的坐标和旋转中心(网格轴)。这会给您一个向量(网格中心,按下的位置)。
在每次鼠标移动时,您都会计算一个新向量(网格中心,鼠标位置),两个向量之间的角度就是旋转角度。

0
唯一的解决方法是在用户开始移动和物体旋转之间设置延迟:
当用户点击并开始移动鼠标时,您需要确定它是否会成为直线运动还是圆形运动。在做出判断之前,这将需要收集一定量的数据。
最极端的情况是要求用户先完成一个完整的圆圈,然后旋转开始(实际上你可以做得比这更好)。你能够缩短这个时间段的大小取决于a)你规定用户的行动必须多么精确,以及b)你对模式识别算法的掌握程度。
为了让你开始,这里是一个极其糟糕的算法概述:
在用户点击时存储x和y坐标。 每1/10秒存储新坐标并进行模式处理。
在process_for_pattern中,您正在寻找:
x坐标和y坐标定期同时增加、同时减少或一个增加一个减少的周期。随着时间的推移,如果这种模式发生变化,使得x或y开始反向而另一个继续保持原样,那么在那一刻,你可以相当肯定地认为你已经得到了一个圆。

这个算法需要用户在检测前画出一个四分之一圆,而且它不考虑大小、方向或者大部分不规则的运动。

如果你真的想继续使用这种方法,你可以得到一个更好的算法,但是你可能需要重新考虑你的控制方法。


谢谢你的回答。感激不尽!我会尝试着实现这个。 - user1737647

0

这不完全是你想要的,但应该足够接近。

选择一个圆形区域,在此区域内,您的移动编号1和2按照描述工作(在图片中,这将是小于红色圆圈的某个区域)。然而,当用户点击圆形区域外部时,您会保存初始点击位置(显示为绿色)。这定义了一个相对于屏幕x轴具有一定角度的点(您可以使用一些三角函数轻松找到它),并且还定义了用户正在操作的圆的半径(以红色表示)。释放鼠标会添加第二个点(蓝色)。然后,您会找到此点相对于屏幕中心和x轴的角度(就像之前一样)。然后,您将该角度投影到由第一次点击确定的圆上。深红色弧线定义了模型旋转的量。

enter image description here

这应该足以让你开始了。


0

我认为这不是一个好的输入方法,因为您总是需要一些移动距离来区分直线和曲线,这意味着会有一些输入延迟。以下是一种替代方案:

只有当垂直鼠标经过屏幕中心线时,才被视为垂直。水平鼠标同理。其他情况被视为旋转,并计算其振幅,计算方法是相对于屏幕中心计算最后一个鼠标位置和当前位置之间的角度。

或者,如果您的应用程序支持,您可以使用所选网格的中心作为输入点。


0

你无法以接近于三维模型视图所需的精度检测出“沿弧线的圆形”鼠标移动。你需要的是像这样的东西: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)的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接