通过物理行为进行拖放
我想实现一个拖动功能,用户可以在工作区周围拖动对象。这当然是最简单的一点。困难之处在于尝试使其成为物理上正确的拖动,其中包含由于扭矩力矩而产生的旋转(想象一下仅使用一根手指在桌子上拖动一本书,当您拖动时它如何旋转?)。
有谁知道我在哪里可以找到有关如何编码的解释(仅限二维,仅限矩形,不需要摩擦)?
多谢, 大卫
编辑:
我写了一个小应用程序(具有明显错误的行为),我希望它能比言语更好地传达我正在寻找的内容。 C# (VS 2008) 源代码和编译的 exe 位于此处
编辑 2 :
调整示例项目以提供可接受的行为。新源代码(和已编译的 exe)可在此处。用 C# 2008 编写。我提供的代码没有任何版权,请随意使用/修改/任何。无需通知我或提及我。
I'd like to implement a dragging feature where users can drag objects around the workspace. That of course is the easy bit. The hard bit is to try and make it a physically correct drag which incorporates rotation due to torque moments (imagine dragging a book around on a table using only one finger, how does it rotate as you drag?).
Does anyone know where I can find explanations on how to code this (2D only, rectangles only, no friction required)?
Much obliged,
David
EDIT:
I wrote a small app (with clearly erroneous behaviour) that I hope will convey what I'm looking for much better than words could. C# (VS 2008) source and compiled exe here
EDIT 2:
Adjusted the example project to give acceptable behaviour. New source (and compiled exe) is available here. Written in C# 2008. I provide this code free of any copyright, feel free to use/modify/whatever. No need to inform me or mention me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
扭矩只是垂直于施加力点和物体质心之间的矢量投影的施加力。因此,如果垂直于直径拉动,扭矩等于施加的力。如果直接拉离质心,则扭矩为零。
您通常希望通过对将原始鼠标按下点连接到鼠标当前位置(在对象局部坐标中)的弹簧进行建模来实现此目的。使用弹簧和一些摩擦力可以使鼠标的运动变得更加平滑。
我听说过有关 Chipmunk 作为 2D 物理包的好消息:
http://code.google .com/p/chipmunk-physicals/
好吧,时间不早了,我需要睡觉了。但这里有一些出发点。您可以在一个坐标空间中进行所有计算,也可以为每个对象定义一个坐标空间。在大多数动画系统中,人们使用每个对象的坐标空间,并使用变换矩阵来转换,因为它使数学变得更容易。
计算的基本顺序是:
当鼠标按下时,你进行命中测试,
并存储坐标
事件(在对象坐标中
空格)。
当鼠标移动时,您会创建一个
表示距离的向量
移动。
弹簧施加的力为 k * M,其中 M 是步骤 1 中的初始鼠标按下点与当前鼠标位置之间的距离。 k 是弹簧的弹簧常数。
从最初的鼠标按下点开始,将该向量投影到两个方向向量上。一个方向朝向对象的中心,另一个方向与对象中心成 90 度。
投射到对象中心的力会将其移向鼠标光标,另一个力是绕轴的扭矩。物体的加速程度取决于其质量,而旋转加速度取决于角动量。
物体在其中移动的介质的摩擦力和粘度会产生阻力,这会随着时间的推移而减少物体的运动。
物体在其中移动的介质的摩擦力和粘度会产生阻力,
或者,也许你只是想假装它。在这种情况下,只需存储矩形的 (x,y) 位置及其当前旋转 phi。然后,执行以下操作:
Torque is just the applied force projected perpendicular to a vector between the point where the force is applied and the centroid of the object. So, if you pull perpendicular to the diameter, the torque is equal to the applied force. If you pull directly away from the centroid, the torque is zero.
You'd typically want to do this by modeling a spring connecting the original mouse-down point to the current position of the mouse (in object-local coordinates). Using a spring and some friction smooths out the motions of the mouse a bit.
I've heard good things about Chipmunk as a 2D physics package:
http://code.google.com/p/chipmunk-physics/
Okay, It's getting late, and I need to sleep. But here are some starting points. You can either do all the calculations in one coordinate space, or you can define a coordinate space per object. In most animation systems, people use coordinate spaces per object, and use transformation matrices to convert, because it makes the math easier.
The basic sequence of calculations is:
On mouse-down, you do your hit-test,
and store the coordinates of the
event (in the object coordinate
space).
When the mouse moves, you create a
vector representing the distance
moved.
The force exterted by the spring is k * M, where M is the amount of distance between that initial mouse-down point from step 1, and the current mouse position. k is the spring constant of the spring.
Project that vector onto two direction vectors, starting from the initial mouse-down point. One direction is towards the center of the object, the other is 90 degrees from that.
The force projected towards the center of the object will move it towards the mouse cursor, and the other force is the torque around the axis. How much the object accelerates is dependent on its mass, and the rotational acceleration is dependent on angular momentum.
The friction and viscosity of the medium the object is moving in causes drag, which simply reduces the motion of the object over time.
Or, maybe you just want to fake it. In that case, just store the (x,y) location of the rectangle, and its current rotation, phi. Then, do this:
这似乎是一个基本的物理问题。
您需要知道点击的位置,这将告诉您它们是在推还是拉,因此,尽管您在 2D 中执行此操作,但您的计算将需要在 3D 中进行,并且您对它们点击的位置的了解将在3D。
每个项目都具有属性,例如质量,也许还有空气阻力信息,因为空气将有助于提供运动。
您还需要根据用户移动鼠标的速度做出不同的反应。
因此,他们可能能够比可能的速度更快地移动 2 吨重物,而您只需要适应这一点,因为如果拖动的对象比鼠标指针慢,用户会不高兴。
This would seem to be a basic physics problem.
You would need to know where the click, and that will tell you if they are pushing or pulling, so, though you are doing this in 2D, your calculations will need to be in 3D, and your awareness of where they clicked will be in 3D.
Each item will have properties, such as mass, and perhaps information for air resistance, since the air will help to provide the motion.
You will also need to react differently based on how fast the user is moving the mouse.
So, they may be able to move the 2 ton weight faster than is possible, and you will just need to adapt to that, as the user will not be happy if the object being dragged is slower than the mouse pointer.
哪种语言?
这里有一堆 C 语言的 2d 变换
Which language?
Here's a bunch of 2d transforms in C