3

我正在用 C++ 开发一个简单的网格查看器实现,它具有平移、旋转、缩放等基本功能。我坚持使用鼠标实现对象沿 z 轴的旋转。我要实现的是以下内容:

  1. 垂直单击并拖动鼠标(几乎垂直即可,因为我使用简单的阈值来过滤沿水平轴的轻微偏差)以沿 y 轴旋转对象(此部分已完成)。
  2. 如上所述,单击并水平拖动鼠标以沿 x 轴旋转对象(这部分也已完成)。
  3. 对于 z 轴旋转,我想检测圆形(或沿弧形)鼠标移动。我被这部分困住了,不知道如何实现。

对于以上两个,我只是使用 atan2() 来确定运动的角度。但是如何检测圆周运动?

4

6 回答 6

0

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

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

在此处输入图像描述

这应该足以让你开始。

于 2012-10-25T13:52:55.563 回答
0

The only way to deal with this is to have a delay between the user starting to make the motion and the object rotating:

When user clicks and begins to move the mouse you need to determine if its going to become a straight line movement, or a circular one. This will require a certain amount of data to be collected before that judgement can be made.

The most extreme case would be requiring the user to make one complete circle first, then the rotation begins (in reality you could do much better than this). Just how small you are able to cut this period down to will depend on a) how precise you dictate your users actions must be, and b) how good you are with pattern recognition algorithms.

To get you started heres an outline of an extremely poor algorithm:

On user click store the x and y coordinates. Every 1/10 of a second store the new coordinates and process_for_pattern.

in process_for_pattern you're looking for:

A period where the x coordinates and the y coordinates regularly both increase, both decrease, or one increases and one decreases. Over time if this pattern changes such that either the x or the y begins to reverse whilst the other continues as it was, then at that moment you can be fairly sure you've got a circle.

This algorithm would require the user to draw a quarter circle before it was detected, and it does not account for size, direction, or largely irregular movements.

If you really want to continue with this method you can get a much better algorithm, but you might want to reconsider your control method.

于 2012-10-25T13:29:38.077 回答
0

我不认为它像那样工作......

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

对于四分位数相机,情况正好相反:如果尝试沿直线旋转网格,则网格似乎会围绕其他一些奇怪的轴轻微旋转——为了弥补这一点,人们会直觉地尝试遵循一些略微弯曲的轨迹。

于 2012-10-25T13:11:25.573 回答
0

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

只有直线穿过屏幕中心的垂直鼠标才被认为是垂直的。水平也一样。在其他情况下,它被认为是一个旋转,为了计算它的幅度,计算最后一个鼠标位置和当前位置之间相对于屏幕中心的角度。

或者,如果您的应用程序是这样工作的,您可以使用所选网格的中心。

于 2012-10-25T14:02:20.103 回答
0

您无法检测到接近 3D 模型查看所需精度的“圆形,沿弧线”鼠标移动。你想要的是这样的: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 )的支持。

于 2012-10-25T14:21:35.870 回答
0

也许,您应该定义一个屏幕区域(例如,在窗口边界处),当单击该区域时,将启动弧形移动 - 或使用其他修饰符、按钮或其他任何东西。

然后单击鼠标,您可以在 2D 屏幕空间中捕获坐标和旋转中心(网格轴)。这会给你一个矢量(网格中心,按钮向下位置)

在每次鼠标移动时,您都会计算一个新向量(网格中心,鼠标位置),两个向量之间的角度就是旋转角度。

于 2012-10-25T13:16:31.130 回答