views:

332

answers:

3

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.

+1  A: 

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.

James Black
Hi James, this is going far beyond the scope of what I'm looking for. There's no need to incorporate friction with the groundplane, no need to handle objects with different masses, no need for collisions with other objects, and certainly no need to take air-flow into account. I'm not even sure I want objects to keep on moving after I let go of the mouse.
David Rutten
@ David Rutten - if you don't take into account air friction and velocity, how will you calculate what should happen? If I click on a certain part of the object and pull, what forces will cause it to being to rotate?
James Black
@James, the object has a tendency to rotate around the center of mass. If I pull on the object anywhere besides this point, it will both translate and rotate. If the motion is slow enough than the object momentum can be ignored.
David Rutten
A: 

Which language?

Here's a bunch of 2d transforms in C

DVK
I can read a lot of languages, but this will eventually end up in C# or VB.NET. The source at that link indeed talks about transforms, but not about how to calculate those transforms from dragging vectors.
David Rutten
+1  A: 

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:

  1. On mouse-down, you do your hit-test, and store the coordinates of the event (in the object coordinate space).

  2. When the mouse moves, you create a vector representing the distance moved.

  3. 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.

  4. 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.

  5. 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.

  6. 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:

  1. Capture the mouse-down location in world coordinates
  2. When the mouse moves, move the box according to the change in mouse position
  3. Calculate the angle between the mouse and the center of the object (atan2 is useful here), and between the center of the object and the initial mouse-down point. Add the difference between the two angles to the rotation of the rectangle.
Mark Bessey
Thanks Mark, the dragging angle must somehow be part of the equation, just haven't been able to come up with a good way to incorporate it. (I edited the original post and added a download link to an example app).Do you have an example of how to construct (and solve) such a spring system?
David Rutten
I was afraid you'd ask for an example :-) I haven't had to do this for a while, but I'll through some equations in up above...
Mark Bessey
Heh, no good deed goes unpunished. I've been browsing Chipmunk, it is indeed pretty impressive. But I hesitate to add a whole project to my app just to allow for rotating boxes. I'm pretty sure there must be a good way to mimic physical box transformations with a relatively simple algorithm. Thanks again for the effort.
David Rutten
@Mark, made my day just in time (bedtime for me too). The example app I posted in the original post does exactly the trick you described (I think) and it doesn't work very well. I'll try the vector-decomposition approach tomorrow and post an update here.
David Rutten
@Mark, I tried the vector decomposition, but I couldn't get it to feel right. In the end, I used the trick you mentioned but added an angle damping factor based on the square of the distance between the centroid and the grip point. New source (and compiled exe) is available in the original post. Thanks again man.
David Rutten