Impact and Gravity Simulator, v 2.1

© COPYRIGHT International Business Machines Corp. 1996

The IBM Corporation contributes this program to the public to demonstrate the Java language and to help people learn to program in Java by browsing and modifying the source code. If you have any comments (or if you make improvements) please send a note to the author, John Henckel.

To run the program, press this button
This browser does not recognize the <applet> tag. To run this program, you need a browser that supports Java API 1.0. If you have access to JDK 1.0 you can also run Impact using either appletviewer index.html or java Impact.

Table of Contents

How To Use It

You can interact with the Impact universe using the control panel or by clicking and dragging your mouse on the animation window. When you hold down the mouse button in the animation window, the ball closest to your pointer is drawn to it. You can "throw" the ball by moving your mouse quickly and releasing the button.

Following is a description of each item on the control panel.

add ball
press this to show a dialog box for adding new balls which has these fields:
the mass of the new ball.
the radius of the new ball. If you specify a number less than 1, the radius is computed as the square root of the mass.
color of the new ball. Can be blue, red, orange, cyan, pink, ..., or any.
X Loc
x location, a positive number. Zero is the left edge of the window.
Y Loc
y location, a positive number. Zero is the bottom of the window.
X Vel
horizontal velocity. A 3 is moving pretty fast.
Y Vel
vertical velocity.
delete ball
press to remove the ball most recently clicked with the mouse. If no ball has been recently clicked, the newest ball is removed.
this controls the animation refresh rate. The lowest setting is one refresh per second. Each step doubles the refresh rate. The highest setting is 128 frames per second, which realistically means "as fast as you can." The setting one or two steps below top speed are better that top speed because they are more consistent.
stop the animation. Unfortunately you cannot drag balls when pause is on.
set vertical gravitation strength.
set mutual gravitation strength. This is the gravity that the balls exert on one another.
set viscosity. The lowest setting (leftmost) is no air (like on the moon.) The force of viscosity is proportional to the speed of the ball and surface area.
set restitution coefficient. This determines the efficiency of a bounce. At the maximum setting (rightmost) no energy is lost during impact of two balls or a ball and a wall. At the lowest setting, all impact energy is lost (converted to heat, for instance) hence balls don't bounce.
enable this to leave trails behind the balls. Actually this just disables the "erase" function, so performance is slightly better with trace on.
enable collisions between balls. If off, the balls pass right through each other.
If collision is enabled, then the "mush" option causes two balls to merge into one if collision occurs. The masses are added, and the radii are added geometrically. Momentum is conserved during a mush.
enable screen wrap. The balls do not hit the walls, they emerge on the other side of the screen. This produces a closed 2D surface such as the surface of a donut. The gravitational force between two balls is computed along the shortest distance in this wrapped surface.
enable screen flicker. When flicker is on, the entire screen is cleared after every animation frame (unless trace is on). When flicker is off, each ball is individually erased and redrawn. Flicker off produces smoother animation, but for some unknown reason (bug) it also occasionally leaves zombie balls on the screen.
press this to cause the most recently clicked ball to begin to orbit its nearest neighbor ball. This requires that you have at least two balls, and the m-gravity must be non-zero.
press this to set the total momentum of the balls to zero. For instance, if you have several balls that are all drifting to the left, pressing this will stop all of them without changing any of their velocities relative to each other.
press this to move the center of mass of all the balls to the center of the window. You may need to press this twice if wrap is on.
press this to momentarily clear the screen. You only need to use this if flicker is off or trace is on.

Some Fun Things to Try


When you first start the program you see a two balls orbiting each other similar to the Earth and the Sun. Can you make more planets orbit the Sun? You'll have best luck if you start small. First press center to give you more room, and enable wrap, so that balls won't bounce off the walls. Add a new ball with mass=1 and radius=0. Use the mouse to throw it around the sun in a large orbit. If that doesn't work, try using the orbit button. After you achieve orbit, use drift and center to adjust it. If you think that was easy, try to make a satellite around the earth. Hint: decrease m-gravity to reduce the tidal forces.


Disable wrap so balls can bounce against the walls. Turn off m-gravity (slide it left) and turn on v-gravity. Pick up a ball and let it bounce. Does it bounce back to the same height you dropped it from? Change restitution and try it again.

Now set restitution to 1.0 (slide it all the way to the right) and increase viscosity by one step. Drop some balls and notice the height they bounce to.

Terminal velocity

With v-gravity turned on, enable wrap. All the balls with begin to accelerate downwards. Without air friction, they will accelerate forever (until Java gets a floating point overflow exception). Increase and decrease the viscosity of the air and watch the effect.

Brownian Motion

One of the earliest observations supporting the atomic theory was the apparently random motion of small particles in liquid observed in a microscope. You can simulate this by creating one large ball (the particle) and many little balls (the liquid molecules).

Delete all the balls. Turn off v-gravity, m-gravity, viscosity, trace, trace, mush, and wrap. Turn on collide. Add one ball with mass=5000 location=(100,100). Add about one hundred little balls with mass=100. If things are moving slowly, use your mouse to stir things up and increase the "temperature".

Negative Mass

When you add a new ball, you can specify a negative mass. This may be nonsensical, but why not? The physical equations work with negative numbers, too. Is negative mass the same as anti-matter? No, anti-matter does not have negative gravity. Since gravity is proportional to the mass, negative mass balls actually repel other balls.

Try this. Turn on m-gravity and create a negative mass ball and a positive mass ball, the negative one is attracted to the positive one and chases after it. Since the positive one is repelled by the negative one, it runs away! If the positive mass ball is heavier, then using the orbit button you can actually get them to orbit each other.

The Impact program does not have any special code to handle negative masses. All the behavior you see is a result of the equations of Newtonian physics.

Implementation Notes

Overlapping and Off Screen Balls

When a ball overlaps another ball or crosses a wall, then Impact uses equations from physics to alter the velocity of the ball. However, what about the location of the ball? Several choices exist: (1) you can alter the location instantaneously to eliminate the overlap (or some fraction of it), (2) you can exert a new force on the ball which is proportional to the amount of overlap, duration of overlap, etc. (3) you can do nothing about it, and hope that the change in velocity will correct the situation soon. I have tried option 1, but it has a problem: When v-gravity is enabled then the location is usually altered in an "up" direction. This increases the potential energy of the ball, and over time this has drastic effects.

In this program I use a combination of 2 and 3. If a ball overlaps a wall, I ensure that the direction of the velocity is away from the wall. If not, reverse it. For each time step that the ball overlaps the wall, I add a tiny amount (1e-20) of velocity to ensure it will eventually get out. If you resize the window and make it smaller, some balls may not be visible, but they will eventually appear.

If a ball overlaps another ball (collision is on, mush is off) I compute the relative velocity normal to impact. If it is negative (retreating) then do nothing. If not, reverse the velocity and assign it to the balls in proportion to mass (this is Newton's law).

When overlap occurs and during the retreat (the balls are separating, or the ball is separating from the wall) I disable all forms of gravity. There is no physical justification for this, but it is the best way I can find to simulate hardness, i.e. two objects cannot occupy the same location at the same time.

A better solution may be to avert collisions altogether by anticipating them. Or how about this, when an overlap occurs, we "reverse" time to the actual moment of impact and calculate the trajectories from then to "now". An exercise left to the reader :-)


The calculation for viscosity is not entirely correct. According to Stokes' law the terminal velocity of a sphere is
           2*g*r*r*(d - d')
      V = ------------------

where	g = gravity
	r = radius
	d = density of body
	d' = density of liquid
	n = viscosity
At this velocity, the force of viscosity equals the force of gravity, m*g. If we assuming d'=0, then the acceleration caused by viscosity is
     a = ---------

About The Author

In case anyone is interested, here is some infomation about myself. I have a BS and an MS in Computer Science. Since 1988 I've worked for IBM in Rochester MN doing various object oriented things. Two programs I wrote for DOS can be found in the SimTel repository. The Algebra Editor is a tool for manipulating formulas and viewing 3D graphics using a simple mouse interface. Impact vers 1.2 handles any convex polygon shapes, but it does not have m-gravity. Both of these programs include instructions and complete Turbo C source code.

Trust in the Lord with all your heart
and lean not on your own understanding;
in all your ways acknowledge him,
and he will make your paths straight. Prov 2.5-6 NIV

Legal Information

The IBM Corporation contributes this program to the public to demonstrate the Java language and to help people learn to program in Java by browsing and modifying the source code. If you have any comments (or if you make improvements) please send a note to the author, John Henckel.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation.

This program has not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of this program. The Program contained herein is provided 'AS IS'. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY DISCLAIMED. IBM shall not be liable for any lost revenue, lost profits or other consequential damages caused by the Program even if advised of the possibility of such damages. Furthermore, IBM shall not be liable for any delays, losses or any other damages which may result from furnishing the Program, even if advised of the possibility of such damages.