I am in the process of developing a very simple physics engine. The only non-static objects in it will be circles and the only collision detection I will be performing is between circles and line pieces.
For the purpose I am utilizing the principals described in Advanced Character Physics. That is, I do integration by using a simple Verlet integrator. I perform collision detection and response simply by calculating the distance between the circles and the line pieces and in case that the distance is less than the cirles radius I project the circle out of the line piece.
This works very well and the result is a practically perfect moving circle. The current state of the engine can be seen here: http://jsfiddle.net/8K4Wj/. This however, also shows the one major problem I am facing: The circle does not rotate at all.
As far as I can figure out there is three different collision cases that will have to be dealt with seperately:
When the circle is colliding with a line vertex and is not rolling along the line.
When the circle has just hit or rolled of a line. Then the exact point of impact will have to be calculated (how?) and the circle is rotated according to the distance between the impact position and the projected position.
When the circle is rolling along a line. Then is it simply rotated according to the distance traveled since last frame.
Here is the closest I have got to solving the problem: http://jsfiddle.net/vYjzt/. But as the demo shows it doesn't handle the edge cases probably.
I have searched for a solution online but I can not find any material that deals with the given problem specifically (as I said the physics engine is relatively simple and I do not want to bother with complex physic simulation concepts).
What looks wrong in your demo is that you're not considering angular moment and energy when determining the motion.
For the easy case, when the wheel is dropping to the floor in your demo, it stops spinning while in free fall. Angular momentum should keep it going.
A more complicated situation is when the wheel finally lands on the floor, it moves with the same horizontal velocity it had before hitting floor. This would be correct if it wasn't rolling but since it is rolling, some of the kinetic energy will have to go into the spinning motion, and this should slow it down. As a more clear example of this, consider the opposite case where the wheel is spinning quickly but has no linear momentum. When this wheel is set on the floor, it should take off and the spinning should slow. Also, for example, as the wheel rolls down a hill, it accelerates more slowly because the energy needs to go into both linear and circular motion.
It's not too hard to do, but to show a rolling object in a way that looks intuitively correct, I think you'll need to consider the kinetic energy and angular momentum associated with rolling. By "not too hard", I mean that all of your equations will essentially but twice as long, with one term for linear motion and another for angular. I won't recite all of the equations, it's basically just the chapter in rotational motion from any physics text.
(Nice demo, btw!)
Related
We're trying to get a realistic affect of a plane being rolled up into a coil in an animation like a carpet rolling up or toilet paper being rolled onto a cardboard tube.
To two ways that are usually suggested are:
Use a spiral and add a curve modifier to the plane - but this is not an accurate representation because the first roll is the widest diameter and then the coil 'tightens'. That would not be how paper really winds onto a cardboard tube ...
The Cylinder/Plane Trick - Move a cylinder while expanding a plane (so one edge is always under the cylinder and increase, decrease the size of the cylinder. This is a clever way to mimic a ribbon being wound / unwound but out plane is actually a complex model so we wouldn't be able to get away with it.
The current animation we are working on is all in Blender Render but if Blender Cycles was the only way to crack this I would go there! ;)
I'm wanting to create a physics engine within Java. However it's not the code I'm bothered about. It's simply the math of rigid body physics, specifically forces and how they affect the rotation of an object.
Let's say for example that I have a square with same length sides. The square will be accelerating towards ground level due to gravity (no air resistance). This would mean that there would be a vector force of (0,-9.8)m/s on every point in the square.
Now let's say that this square is rotated slightly. When this rotated square comes into contact with the ground (a flat surface) there will be an impulse velocity vector at the point of contact (most likely a corner of the square). However, what happens to the forces of the other corners on the square? From the original force of gravity, how are they affected?
I apologize if my question isn't detailed enough. I'd love to upload a diagram but I don't yet have the reputation.
rotation is form of kinetic energy
first the analogy to movement
alpha - angular position [rad]
omega - angular speed [rad/s]
epsilon - angular acceleration [rad/s^2]
alpha(t)/(dt^2)=omega(t)/dt=epsilon(t)
now the inertia
I - quadratic rotation mass inertia [kg.m^2]
m - mass [kg]
M - torque [N.m]
and some equations to be exploited
M=epsilon*I - torque needed to achieve acceleration or vice versa [N.m]
acc=epsilon*radius - perimeter acceleration [m/s^2]
vel=omega*radius - perimeter speed [m/s^2]
equation #1 can be used to directly compute the force. Equations #2,#3 can be used to calculate friction based forces like wheels grip/drag. Do not forget about the kinetic energy Ek=0.5*m*vel^2+0.5*I*omega^2 so you can exploit the law of preserving energy.
During continuous contact of object1 with object2 in rotation happens this
Perimeter speed/acceleration create interaction force, this is slowing down the rotation of object2 creating drag force on the object2 and reacting force on the object1.
if object1 is not fixed then this force also create torque and rotates the object1
If the rotation is forced to stop suddenly then all rotational part of kinetic energy is moved to the collision reaction Force impulse.
If object is in more complicated rotation motion then you should compute the actual rotation axis and alpha,omega,epsilon and use that because object can rotate with more rotations each with different center of rotation.
Also if object is rotating and another rotation is applied in different axis then this creates gyroscopic torque creating also rotation in the third axis perpendicular to both.
So when yo put all these together you have a idea of what structures you need. Sorry can not be more specific than this without further info about the structures and properties of your simulation ...
Applied forces do not play a role in the calculation of contact impulses because the impulses are said to occur on a time scale much smaller than the simulation time step. Basically the change is velocity during an impact because of gravity or other forces is negligible.
If I understand correctly, you worry about the different corners of the square - one with an impact, three without.
However, since you want to do rigid body dynamics, it is more helpful to think about the rigid body as having a center of mass (in this case, the square's center), a position, a rotation, and a geometry (in this case the square, but it could be anything).
The corners of the vertices are in constant position and rotation with regards to the center of mass - it's only the rigid body's position and rotation which change all four corners position in the world at once. An advantage of this view is that it is independent of the geometry - you could have 10 or 20 corners, and the approach would be the same.
With regard to computing the rotation:
Gravity is working as before. However, you now have another force (from the impulse over the time it acts) - and you have to add the effects of the two in order to get the complete outcome of the system.
The impulse will be due to one of the corners being in collision in the case you describe. It has to be computed at the contact point, with a contact normal - in this case the normal of the flat surface.
If the normal points in a different direction than the center of mass, this will lead to a rotation (as well as a position change).
The amount of the position change is due to how you model the contact computation and resolution, material properties, numerical stepper, impact velocity, time step, ...
As others mentioned, reading up on physics (rigid body dynamics) and physics simulations might be a good starting point to understand the concepts better.
I'm using Three.js and Physijs. I have a wall that should act as a boundary, but objects (especially boxes) often pass through it, if the force is sufficient. The collision is detected, as they do not do so cleanly, but they start spinning or bounce in some direction. Is there a way to increase the maximum force with which the wall can act on the colliding object?
All four of the wall's points are on the same plane, forming a rectangle. The mesh consists of two large triangular faces. I'm using a ConvexMesh.
Breaking the two triangles into many smaller ones does not alleviate the problem.
I can confirm the normals are fine, as the wall is shaded correctly.
How can I solve this without converting the wall into a BoxMesh?
I'll also appreciate an explanation of why this happens. I'm guessing that the engine limits the maximum force that collisions can apply.
I think it's Motion Clamping
https://github.com/chandlerprall/Physijs/wiki/Collisions
When an object has a high velocity, collisions can be missed if it
moves through and past other objects between simulation steps. To fix
this, enable CCD motion clamping. For a cube of size 1 try:
// Enable CCD if the object moves more than 1 meter in one simulation
frame mesh.setCcdMotionThreshold(1);
// Set the radius of the embedded sphere such that it is smaller than
the object mesh.setCcdSweptSphereRadius(0.2);
Hope this works ima try it now
I'm trying to figure out how to draw an stretchy/elastic line between two points in openGL/Cocos2d on iPhone. Something like this
Where the "band" get's thinner as the line gets longer. iOS uses the same technique I'm aiming for in the Mail.app, pull to refresh.
First of all, is there a name for this kind of thing?
My first thought was to plot a point on the radius of the starting and ending circles based on the angle between to the two, and draw a quadratic bezier curve using the distance/2 as a control point. But I'm not a maths whizz so I'm struggling to figure out how to place the control point which will adjust the thickness of the path.
But a bigger problem is that I need to fill the shape with a colour, and that doesn't seem to be possible with OpenGL bezier curves as far as I can tell since curves don't seem to form part of a shape that can be filled.
So I looked at using a spline created using a point array, but that opens up a whole new world of mathematical pain as I'd have to figure out where all the points along the edge of the path are.
So before I go down that rabbit hole, I'm wondering wether there's something simpler that I'm overlooking, or if anyone can point me towards the most effective technique.
I'm not sure about a "common" technique that people use, other than calculating it mathematically, but this project, SlimeyRefresh, is a good example of how to accomplish this.
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.
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:
Capture the mouse-down location in world coordinates
When the mouse moves, move the box according to the change in mouse position
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.
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.
Which language?
Here's a bunch of 2d transforms in C