views:

799

answers:

4

I have balls bouncing around and each time they collide their speed vector is reduced by the Coefficient of Restitution.

Right now my balls CoR for my balls is .80 . So after many bounces my balls have "stopped" rolling because their speed has becoming some ridiculously small number.

In what stage is it appropriate to check if a speed value is small enough to simply call it zero (so I don't have the crazy jittering of the balls reacting to their micro-velocities). I've read on some forums before that people will sometimes use an epsilon constant, some small number and check against that.

Should I define an epsilon constant and do something like:

if Math.abs(velocity.x) < epsilon then velocity.x = 0

Each time I update the balls velocity and position? Is this what is generally done? Would it be reasonable to place that in my Vector classes setters for x and y? Or should I do it outside of my vector class when I'm calculating the velocities.

Also, what would be a reasonable epsilon value if I was using floats for my speed vector?

A: 

IMO your epsilon approach is fine. I would just experiment to see what looks or feels natural to the animation in the game.

grepsedawk
+1  A: 

A reasonable value for epsilon is going to depend on the constraints of your system. If you are representing the ball graphically, then your epsilon might correspond to, say, a velocity of .1 pixels a second (ensuring that your notion of stopping matches the user's experience of the screen objects stopping). If you're doing a physics simulation, you'll want to tune it to the accuracy to which you're trying to measure your system.

As for how often you check - that depends as well. If you're simulating something in real time, the extra check might be costly, and you'll want to check every 10 updates or once per second or something. Or performance might not be an issue, and you can check with every update.

bradheintz
+1  A: 

Instead of an epsilon for an IsStillMoving function, maybe you could use an UpdatePosition function, scheduled on an object-by-object basis based on its velocity.

I'd do something like this (in my own make-it-up-as-you-go pseudocode):

void UpdatePosition(Ball b) {

   TimeStamp now = Clock.GetTime();
   float secondsSinceLastUpdate = now.TimeSince(b.LastUpdate).InSeconds;

   Point3D oldPosition = b.Position;
   Point3D newPosition = CalculatePosition(b.Position, b.Velocity, interval);
   b.MoveTo(newPosition);

   float epsilonOfAccuracy = 0.5; // Accurate to one half-pixel
   float pixelDistance = Camera.PixelDistance(oldPosition, newPosition);
   float fps = System.CurrentFramesPerSecond;
   float secondsToMoveOnePixel = (pixelDistance * secondsSinceLastUpdate) / fps;
   float nextUpdateInterval = secondsToMoveOnePixel / epsilonOfAccuracy;

   b.SetNextUpdateAt(now + nextUpdateInterval);
}

Balls moving very quickly would get updated on every frame. Balls moving more slowly might update every five or ten frames. And balls that have stopped (or nearly stopped) would update only very very rarely.

benjismith
A: 

Epsilon by nature is the smallest possible increment. Unfortunately, computers have different "minimal" increments of their own depending on the floating point representation. I would be very careful (and might even go higher than what I would calculate just for safety) playing around with that, especially if I want a code to be portable.

You may want to write a function that figures out the minimal increment on your floats rather than use a magic value.

Uri