physics: determine velocities of 2 spheres after collision
I'm using Physics for Games Programmers to develop a simple physics-based game.
I need to compute the resulting velocities for two spheres after an elastic collision. The book example for this in Chapter 6 assumes that the 2nd sphere is stationary, and so some of the equations are simplified to 0. I need the math to work whe开发者_如何学编程n both bodies are in motion.
I've tried to convert the book's example to code, and puzzle out what should happen for the second sphere's line of action and normal- V2p and V2n. My code sort of works, but occasionally the velocities suddenly speed up and bounce out of control. Clearly there's something wrong with my math.
Here's what I'm using. The code is in Java, "s1" and "s2" are the spheres.
double e = 1d;
// distance of sphere centers
double dX = s2.getCenterX() - s1.getCenterX();
double dY = s2.getCenterY() - s1.getCenterY();
double tangent = dY / dX;
double angle = Math.atan(tangent);
// v1 line of action
double v1p = s1.getVelocityX() * Math.cos(angle) + s1.getVelocityY() * Math.sin(angle);
// v1 normal
double v1n = -s1.getVelocityX() * Math.sin(angle) + s1.getVelocityY() * Math.cos(angle);
// v2 line of action
double v2p = s2.getVelocityX() * Math.cos(angle) + s2.getVelocityY() * Math.sin(angle);
// v2 normal
double v2n = -s2.getVelocityX() * Math.sin(angle) + s2.getVelocityY() * Math.cos(angle);
double v1massScale = (s1.getMass() - (e * s2.getMass())) / (s1.getMass() + s2.getMass());
double v2massScale = ((1 + e) * s1.getMass()) / (s1.getMass() + s2.getMass());
// compute post-collision velocities
double v1pPrime = v1massScale * v1p + v2massScale * v2p;
double v2pPrime = v2massScale * v1p + v1massScale * v2p;
// rotate back to normal
double v1xPrime = v1pPrime * Math.cos(angle) - v1n * Math.sin(angle);
double v1yPrime = v1pPrime * Math.sin(angle) + v1n * Math.cos(angle);
double v2xPrime = v2pPrime * Math.cos(angle) - v2n * Math.sin(angle);
double v2yPrime = v2pPrime * Math.sin(angle) + v2n * Math.cos(angle);
It might be the Math.atan(y/x)
. You need to handle some special cases, and you usually want to use Math.atan2(y,x)
instead.
See the Math.atan() and Math.atan2() docs.
It's a surprisingly difficult problem if you don't know much about physics or math.
You need to know about Newton's laws of motion. These are couple differential equations, so you'll need to know how to solve those.
The problem is easier if you assume certain things to be unimportant for the behavior you're interested in: rigid versus deformable spheres, friction, and other factors.
The answer depends a lot on what you'd like to do.
A quick glance at the code you posted suggests that the best you can hope for is that you have a correct but less than optimal implementation. It's likely that you fail to understand the physics and mathematics sufficiently well to solve it on your own.
I'd Google for a physics engine in the language of your choice and use an idealization that someone else has already coded.
精彩评论