Go to top

# Fun With Gravity

, 28 Jul 2008
 Rate this:
A gravity simulation particle system.

## Introduction

This article is a fine example of what happens when programmers get bored. There's nothing exciting in the code, maybe a gentle introduction to GDI+. It was just a fun project to mess with, and it's addictive to play with. So I thought I might share it.

I was thinking about the fact that every particle in the universe is constantly gravitationally affected by every particle in the universe, and wanted to see what it would look like modeled in software. It's been a number of years since I cracked a Physics book, so I can't guaranty my accuracy with this project... But it sure is pretty.

## The Code

### Calculating Acceleration Due to Gravity

The method I chose for calculating the gravitational effect of each particle `pn` on particle `p` is this: I create a vector that extends from one particle to the other by subtracting `p`s location vector from `pn`s location.

`Vector unit = p2.Location - p.Location;`

Then, calculate the magnitude of the resulting vector:

```float magnitude = (float)Math.Sqrt(
(unit.X * unit.X)
+ (unit.Y * unit.Y)
+ (unit.Z * unit.Z)
);```

Then, you have what you need to calculate the acceleration.

```float factor = (
GravitationalConstant * (
(p.Mass * p2.Mass) / (magnitude * magnitude * magnitude)
)
) / p.Mass;```

The resulting vector is what's needed to alter your particle's velocity due to the gravity of particle `pn`. I originally started with the actual gravitational constant `G = 6.672e-11`, but scaled it larger for simulation's sake, allowing smaller masses to be used.

The full calculation loop looks like this. Notice that for each particle, you calculate the gravitational effect on it by every other particle.

```foreach (Particle p in particles) {
...
if (particles.Count > 1) {
Vector a = new Vector();
foreach (Particle p2 in particles) {
if (object.ReferenceEquals(p, p2)) { continue; }
Vector unit = p2.Location - p.Location;
float magnitude = (float)Math.Sqrt(
(unit.X * unit.X)
+ (unit.Y * unit.Y)
+ (unit.Z * unit.Z));
float factor = (GravitationalConstant * (
(p.Mass * p2.Mass) / (magnitude * magnitude * magnitude)
)) / p.Mass;
unit *= factor;
a += unit;
}
p.Velocity += a;
}
...
}```

### Conservation of Momentum with Inelastic Collisions

My collision detection is primitive. I'm only looking to see if a particle's bounding rectangle intersects with another. The Z axes was an afterthought, and in case the X and Y are intersecting, I look to see if the Z locations are with 5 of each other. I got lazy, what can I say. I wasn't that interested in the Z axes, but wanted to include it in the calculations.

In any event, when two particles collide, I combine their colors and masses. I increase their size slightly. And combine their momentum to find the resulting particle's velocity.

```private Particle Merge(Particle i, Particle j, Graphics g) {
...
Vector v = ((i.Velocity * i.Mass) + (j.Velocity * j.Mass));
v /= i.Mass + j.Mass;
...
}```

## The Demo Application

### Controls

There are menu options to Start, Stop, and Pause the simulation. Pause has a keyboard shortcut of F5, and Start has Ctrl+E (Execute from SQL Query Analyzer . You must start the simulation before you can add particles, and you can restart at any time to reset everything. Clicking anywhere in the picture box will create a particle at that location. The text boxes to the left under the check boxes determines the properties that the new particle will have. You can set the X, Y, and Z components of its initial velocity, its mass, and its size in pixels.

### Buttons

The three buttons under the text boxes, labeled "B", "M" & "S", set the properties to predefined values for convenience. "B" creates a massive particle, "M" creates a medium, and "S" creates a small. The "Background" button allows you to change the picture box's background color.

### Check Boxes

• Trace: Toggles tracing. Tracing now shows a trail for each particle.
• Collisions: Toggles collision detection.
• Show Vel: Shows the velocity vector in red.
• Vel Box: Shows the velocity vector's bounding box.
• Show Acc: Shows the acceleration vector in the particle's color.
• Acc Box: Shows the acceleration vector's bounding box.

The visual representation of the velocity and acceleration vectors is scaled up quite a bit so that they are visible at the scales I was working with. With more massive examples, the acceleration vector line can be pretty long. I may look at changing it to scale variably based on masses, but probably not.

 Velocity Vector Velocity Box Acceleration Vector Acceleration Box Velocity & Acceleration

### Particle ListView

Finally, the list view at the bottom of the window shows some attributes of the particles. The list view now shows all particles but only when paused. While paused, if you select particles in the list view and hit `DELETE`, it will remove the selected particles.

## Conclusion

I don't think there's much to learn from this project, other than some simple GDI+ usage, and I suppose if you're not familiar with operator overloads, you could find some interesting things in the `Vector` class. It was just a fun project to play with, and it looks pretty cool. If I get bored enough some day, I may see about turning it into a screensaver.

## History

#### 07/24/2008

Based on the suggestions by protix & Zimriel I've updated calculations to more accurately represent orbits. I fixed the non-tracing flickering by drawing to an image and replacing the picturebox's image (poor man's double buffer). And tracing has been redone as well. Originally, I wanted to clear the image with a white color with a low alpha so that previous draws would fade. However, drawing an alpha color to the entire image takes far too long. In the end, I wound up having each particle keep track of a number of previous position, which get redrawn with decreasing alpha values. There may be a better solution, but this works for now.

## Share

Software Developer (Senior) BoneSoft Software
United States
I've been in software development for more than a decade now. Originally with ASP 2.0 and VB6. I worked in Japan for a year doing Java. And have been with C# ever since.

In 2005 I founded BoneSoft Software where I sell a small number of developer tools.
Group type: Organisation (No members)

## You may also be interested in...

### Why “Good Enough” Isn’t Good Enough Anymore for Software Configuration Management

 First Prev Next
 My vote of 5 Philip P Liebscher 26-May-11 18:58
 My vote of 5 alain_dionne 29-Mar-11 5:30
 Thumbs up! Bigdeak 10-Jun-10 5:15
 [Message Removed] immetoz 6-Oct-08 7:49
 Good Article, But ... Member 4770365 28-Jul-08 23:36
 Re: Good Article, But ... canozurdo 29-Jul-08 2:23
 Re: Good Article, But ... ``` Xmen ``` 22-Jan-09 16:25
 Fun Timmy Kokke 28-Jul-08 20:14
 good david bagaturia 20-Jul-08 20:06
 Nice project fgjsdhgsdhg3432423423234 22-Aug-07 9:04
 Re: Nice project BoneSoft 22-Aug-07 12:10
 Orbits protix 26-Jul-07 1:32
 Re: Orbits BoneSoft 26-Jul-07 4:09
 Re: Orbits protix 26-Jul-07 21:45
 The mag^3 comes just from the vector form of the gravitational law which one has to use when dealing with arbitrary configurarions (you use it). In vector form the gravitation force is (see http://en.wikipedia.org/wiki/Newton%27s_law_of_universal_gravitation[^] for instance)   F12 = -G m1 m2 * (r2 - r2) / |r2 - r2| ^ 3   (where the vectors are bold and magnitude = |r2 - r2|). If you want just the strength of the force (without direction) then the vector difference in the nominator becomes a magnitude too and cancels one magnitude power in the denominator - this is why the vectorless form has magnitude ^ 2.   Also velocity is just v = r / t in vector form (which is in no contradiction with your formula for the rotation case where T is the period of one rotation).   Orbits are *never* exact circles, in two body case they are ellipses. When more bodies are involved orbits are complicated and usually even completelly irregular. For 2 bodies you get a nearly perfect circle orbit in case one mass is much bigger M >> m (as like M mass of Sun and m mass of Earth) and the velocity of the small body is   v = sqrt( G m / r )   (get it by equaling the gravitational and the zentrifugal force). Actually it is all probably not that easy, I just keep forgetting that most of the people in the world are not physicists Anyway very interesting stuff to fiddle around.   A very cool java applet seriously simulating curious body configurations is here http://www.princeton.edu/~rvdb/JAVA/astro/galaxy/Galaxy.html[^]   Greetings,   Plamen.
 Re: Orbits protix 26-Jul-07 21:48
 Re: Orbits Zimriel 14-Nov-07 19:21
 Great Work!! Neo_Shehpar 24-Jul-07 11:35
 Re: Great Work!! BoneSoft 24-Jul-07 16:34
 Physics from a physicist Kory.Postma 24-Jul-07 1:20
 Re: Physics from a physicist BoneSoft 24-Jul-07 2:18
 Re: Physics from a physicist BoneSoft 24-Jul-07 6:02
 Suggestion Josh Smith 23-Jul-07 8:12
 Re: Suggestion BoneSoft 23-Jul-07 16:50
 Cool! Jay Gatsby 22-Jul-07 21:42
 Gravity Screen Saver Obiwan Jacobi 22-Jul-07 19:59
 Re: Gravity Screen Saver BoneSoft 23-Jul-07 3:53
 Re: Gravity Screen Saver Chris Losinger 3-Dec-07 10:31
 Dang! Now I just have to know... charlieg 22-Jul-07 13:04
 Re: Dang! Now I just have to know... BoneSoft 22-Jul-07 17:25
 Extra Mass? Berg49508 22-Jul-07 1:19
 Re: Extra Mass? Obble 25-Jul-07 10:16
 Cool article Joergen Sigvardsson 22-Jul-07 0:07
 Awesome! Stephan Poirier 21-Jul-07 20:11
 Last Visit: 31-Dec-99 18:00     Last Update: 18-Sep-14 11:00 Refresh 1

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 28 Jul 2008