I've created a simple 2d physics engine in Java that uses circular projectiles and straight walls. Currently, with each frame, every projectile's position is advanced by velocity * (1/fps)
. Velocity is updated afterwards, once per frame. Collision detection defines a line in point-slope form using the previous and current position, checks if that line intersects with a wall, and if that intersection lies in between the previous position and current position, a collision is registered and the projectile's current position and velocity is updated accordingly. At the moment, there is no rotation, which is intended.
Now, this all works except in inelastic collisions. Currently, an inelastic collision multiplies the component of the projectile's velocity that is perpendicular to the surface it collided with by some coefficient that is less than 1.
Say there is a projectile bouncing up and down on a horizontal surface. What should happen is that the y component of the projectile's velocity decreases with every bounce, causing the maximum height of the projectile to decrease with every bounce, eventually reaching a point where it becomes negligible. Instead, what happens is that the ball's maximum height decreases to a certain point, then starts to increase for a few bounces, starts decreasing again, entering a constant cycle. The result is that the ball never really stops, but appears to "jitter".
This happens because the projectile moves in straight line segments every frame and because velocity is not continuously changing. If there are more frames during which the ball is dropping down than there are frames during which the ball rises up, the ball is accelerated for those extra frames and it ends up going higher than it should have. What is happening is that the ball reaches a point where one bounce sends it higher up than it should have for the above reason. When the maximum height drops back down again due to the inelastic collision, it does the same thing again.
I've tried eliminating this by making the ball move by (v*t + 0.5*a*t^2)
, where v
is velocity, a
is acceleration due to gravity, and t
is 1/fps
. This works, except for the fact that it causes the collision detection using straight lines to fail when the bounces get small enough. I've also tried doing collision detection with parametrically-defined parabolas, but it becomes unbelievably annoying and inefficient when it comes to detecting collisions between projectiles. If you're curious, I can explain my attempted solution more in-depth.
Any other simple solutions you'd like to suggest?
Thanks in advance, especially if you actually read through those five paragraphs.
What I would suggest is to have a block of code that will bounce only if the bounce height is at or above a certain constant that you've defined as the height. You would need some sort of loop structure (or "helper" method as I did below) to calculate the projected bounce height after every bounce of the ball. Then you might be able to do something like this: (assuming that you've entered the "now it's time to bounce method")
The only problem with this way is that if you do not terminate at some point, the program will be checking if it can bounce infinitely (if the ball is "rolling" on the baseline). This might cause some memory issues as it is to a certain extent an infinite loop.
Just for clarification:
calculateNewBounceHeight()
andbounce()
are methds that I assume you will be able to create. Does this help at all? Let me know if I missed something or interpreted the question wrong (I might not have read the whole thing).