Bouncing ball hang up (The Nature of Code)

Example 2.3 The Nature of Code

The code: [https://editor.p5js.org/steinlav/sketches/Y8qlyS9I6]
In the method checkEdges(), line 84 this.pos.y = height; ()

Problem:

  • Why do the ball not loose bouncer over time when line 84 is active.

Additional problem:

  • This line is neccesary to prevent hang up and disappearance below the lower rim. Why?

The book: [https://natureofcode.com/]

The ball doesn’t loose any speed from moving it’s position because the velocity vector keeps track of the speed.

Line 84 is there to fix a potential bug where if the ball is moving fast enough it will go off the edge of the screen and then after the next update it is still off the edge of the screen the velocity will be reversed and it will start traveling down again. I managed to change the example to illustrate the potential bug by changing the ground and commenting out the reset on acceleration. Try running it with that line and without (now line 85).

Going back to velocity if you want a more realistic look where the ball loses speed try changing the change in direction to look something like:

if (this.pos.y > height) {
  this.pos.y = height;
  this.velocity.y *= -0.9;
  this.velocity.x *= 0.9;
}

This means the ball will slow down slightly every time it hits the ground. Hope that helps.

1 Like

yes, but
that could be avoided if you not work with
velocity *= -1;

instead with
dir = 1;

and later do
velosity * dir
( ok, sure for .x and .y separate )

Thanks.
But when line 84 is removed, the ball slows down without multiplying velocity with av number less than one.
Why?

I’m not seeing what you are describing.

I run the sketch, the ball slowly bounces lower over time.

I comment out 84, the ball slowly bounces lower over time.

What is the problem? figraham has explained the code in general. Are you asking why there isn’t perfect conservation of energy under the simulated gravity and wind? Consider possible sources of lost height over time – rounding off of impact points, float precision, lateral motion rather than vertical motion. If you remove some of them, what happens to the ball?

Thanks for answering.

On my computer the ball bounces lower only for the six or seven first bounces. After that the ball does not bounce lower than 28 pixels from the top (or at least as long as I have watched)

When line 84 is comment out, the ball bounces lower all the time. After only four bounces the ball is bouncing lower than 28 pixels from the top. When the ball comes low enough the problem with “hang up” occurs, witch is why line 84 is necessary, but before that: why this differece in bouncing?

(I have now fixed the size of the ball (no more random), fixed the vertical line at 28 pixels from the top and added a line through the center of the ball)

The code: https://editor.p5js.org/steinlav/sketches/Y8qlyS9I6

Think of line 84 as a rubber wall, adding energy to your ball.

Add this line above line 84:

print(this.pos.y, this.velocity.y);

Now watch what happens.

At a certain point, the y position of the ball is 407.76 – it has overshot the bottom of the frame by 7.76. The collision corrector fixes this by changing it to 400 – in essence, teleporting the ball up by 7.76. This exactly matches the height decay (the instant velocity) so the ball lost 0. The next bounce, the ball decays and falls to 407.46 again – and receives another boost, exactly matching its decay again, and so does the same bounce again.

With very slightly different settings, this behavior will find a different equilibrium. For example, try this:

this.pos.y = height -1;

See what happens? With just a bit more bounce energy from the offset, it finds a higher equilibrium point.

If you want to break equilibrium, there are many ways to do it. One is to soak a bit of velocity whenever your “overshoot” case is triggered, so that your ball slows a bit whenever it touches rubber.

if (this.pos.y > height) {
  print(this.pos.y, this.velocity.y);
  this.pos.y = height;
  this.velocity.y *= -.99;

Now the ball always loses energy on every bounce – and in this case, bounces down, although if it was moving very fast, it might still not be losing as much as it is gaining from being moved up by the bounce wall.

Or, you could just have the ball bounce from however deep it fell into the bottom surface. Rather than teleporting it out of the bottom material, you need to use an extra check to prevent in-wall bounce vibration.

if (this.pos.y > height && this.velocity.y > 0) {
  print(this.pos.y, this.velocity.y);
  // this.pos.y = height; // Comment out this
  this.velocity.y *= -1;

Now a ball will only start moving up if it is in a wall AND moving down, so it will only change direction once. However far it travels into the wall, that distance is lost – no teleporting – and so the bounce height always decays over time, regardless of speed.

Thank you very much. That was clarifying.

Including friction also solve the problem.
The Nature of Code. Example 2.4: Including friction, page 82.

Inside the for-loop in draw()

let c = 0.01; // friction coefficient
let friction = movers[i].velocity.copy(); // get the velocity vector
friction.mult(-1); // reverse the direction
friction.normalize(); // normalize (set magnitude to 1)
friction.mult(c); // multilply with friction coefficient

movers[i].applyForce(friction);
1 Like