拖放与物理行为

Posted

技术标签:

【中文标题】拖放与物理行为【英文标题】:Drag+Drop with physical behaviour 【发布时间】:2010-12-04 12:04:42 【问题描述】:

我想实现一个拖动功能,用户可以在工作区中拖动对象。这当然是容易的一点。困难在于尝试使其成为物理上正确的拖动,其中包含由于扭矩力矩而产生的旋转(想象一下,只用一根手指在桌子上拖动一本书,拖动时它是如何旋转的?)。

有谁知道我在哪里可以找到关于如何编码的解释(仅限 2D、仅限矩形、无需摩擦)?

非常感谢, 大卫


编辑:

我写了一个小应用程序(有明显错误的行为),我希望它能比文字更好地传达我正在寻找的东西。 C# (VS 2008) source and compiled exe here


编辑 2:

调整了示例项目以提供可接受的行为。新的源代码(和编译的 exe)可用here。用 C# 2008 编写。我提供此代码没有任何版权,请随意使用/修改/任何内容。无需通知我或提及我。

【问题讨论】:

【参考方案1】:

扭矩只是垂直于施加力的点和对象质心之间的矢量投射的施加力。因此,如果垂直于直径拉动,则扭矩等于施加的力。如果直接拉离质心,则扭矩为零。

您通常希望通过对将原始鼠标按下点连接到鼠标当前位置(在对象局部坐标中)的弹簧进行建模来做到这一点。使用弹簧和一些摩擦可以稍微平滑鼠标的运动。


我听说过将 Chipmunk 作为 2D 物理包的好处:

http://code.google.com/p/chipmunk-physics/


好了,时间不早了,我要睡觉了。但这里有一些起点。您可以在一个坐标空间中进行所有计算,也可以为每个对象定义一个坐标空间。在大多数动画系统中,人们使用每个对象的坐标空间,并使用transformation matrices 进行转换,因为它使数学更容易。

计算的基本顺序是:

    在鼠标按下时,您会进行命中测试, 并存储坐标 事件(在对象坐标 空间)。

    当鼠标移动时,您会创建一个 表示距离的向量 搬家了。

    弹簧施加的力为 k * M,其中 M 是从步骤 1 开始的初始鼠标按下点与当前鼠标位置之间的距离。 k是弹簧的弹簧常数。

    将该向量投影到两个方向向量上,从最初的鼠标按下点开始。一个方向是朝向对象的中心,另一个方向是与之成 90 度。

    向对象中心投射的力会将其移向鼠标光标,另一个力是围绕轴的扭矩。物体加速多少取决于它的质量,而旋转加速度取决于角动量。

    物体在其中移动的介质的摩擦力和粘度会导致阻力,这会随着时间的推移简单地减少物体的运动。


或者,也许您只是想伪造它。在这种情况下,只需存储矩形的 (x,y) 位置及其当前旋转 phi。然后,这样做:

    在世界坐标中捕获鼠标按下的位置 当鼠标移动时,根据鼠标位置的变化移动方框 计算鼠标和对象中心之间的角度(atan2 在这里很有用),以及对象中心和初始鼠标按下点之间的角度。将两个角度之间的差异添加到矩形的旋转中。

【讨论】:

谢谢马克,拖动角度一定是方程式的一部分,只是还没能想出一个很好的方法来合并它。 (我编辑了原始帖子并添加了一个示例应用程序的下载链接)。你有如何构建(和解决)这样一个弹簧系统的例子吗? 我担心你会问一个例子 :-) 我有一段时间没有这样做了,但我会通过上面的一些方程式...... 嘿,没有好事会受到惩罚。我一直在浏览Chipmunk,它确实令人印象深刻。但我犹豫是否将整个项目添加到我的应用程序中只是为了允许旋转框。我很确定一定有一种用相对简单的算法来模拟物理盒子变换的好方法。再次感谢您的努力。 @Mark,准时度过了我的一天(我也是就寝时间)。我在原始帖子中发布的示例应用程序完全符合您描述的技巧(我认为),但效果不是很好。明天我将尝试向量分解方法并在此处发布更新。 @Mark,我尝试了向量分解,但感觉不正确。最后,我使用了你提到的技巧,但添加了一个基于质心和抓握点之间距离的平方的角度阻尼因子。原始帖子中提供了新的源代码(和编译的 exe)。再次感谢伙计。【参考方案2】:

这似乎是一个基本的物理问题。

您需要知道点击的位置,这将告诉您他们是在推动还是在拉动,因此,尽管您在 2D 中执行此操作,但您的计算需要在 3D 中进行,并且您知道他们点击的位置将是 3D。

每个项目都有属性,例如质量,也许还有空气阻力信息,因为空气将有助于提供运动。

您还需要根据用户移动鼠标的速度做出不同的反应。

因此,他们可能能够以比可能更快的速度移动 2 吨重的重量,您只需要适应这一点,因为如果被拖动的对象比鼠标指针慢,用户将不会高兴。

【讨论】:

嗨詹姆斯,这远远超出了我正在寻找的范围。不需要与地平面结合摩擦,不需要处理不同质量的物体,不需要与其他物体碰撞,当然也不需要考虑气流。我什至不确定放开鼠标后我是否希望物体继续移动。 @David Rutten - 如果你不考虑空气摩擦和速度,你将如何计算会发生什么?如果我点击物体的某个部分并拉动它,什么力会导致它旋转? @James,物体倾向于围绕质心旋转。如果我在这个点之外的任何地方拉动物体,它就会平移和旋转。如果运动足够慢,则可以忽略物体动量。【参考方案3】:

哪种语言?

Here's a bunch of 2d transforms in C

【讨论】:

我可以阅读很多语言,但这最终会以 C# 或 VB.NET 结束。该链接的来源确实谈到了变换,但没有谈到如何从拖动向量计算这些变换。

以上是关于拖放与物理行为的主要内容,如果未能解决你的问题,请参考以下文章

拖放与视觉指示

nstableview 拖放与自定义单元格视图

IOS拖放与缩放

如何使用 jQuery 拖放与段落元素

如何让 jQueryUI 拖放与触摸设备一起使用

AngularJS - 将拖放与流程图相结合