Solar System Simulation Part 3 Asteroids Code

Posted on Posted in C Sharp, C#, Computer Graphics, Gravity, Math, Non-Tutorial Computer Science, Physics, programming, Science, Space

Solar System Simulation Series: Part 1 Part 2 Part 3

As of my last post, I had a couple more things on my checklist to do, and I’ve made the following changes to the current revision of  my program:

  • Make the Sun one of the foci of the elliptical orbits a lá Kepler’s Laws of Planetary Motion, instead of the center of the orbit. Can probably be done by shifting the orbit over by the difference between the planet’s perihelion (closest approach) and aphelion (furthest distance).
  • New Goal: Gravitational anomaly in the bottom left – asteroids tend to be attracted to an area of empty space in the bottom left – a planetary level mass apparently exists there. This needs to be fixed.
  • New Goal: Make orbit coloring a bit more palatable.

I’ll start with the second point – embarrassingly enough, turns out, I had the sun’s x and y coordinates reversed, so the asteroids attracted to the bottom left was actually the “sun”!

As for the first, I was using the planets’ perihelions, or closest approach to the sun, in previous builds of the program to approximate the semi-minor axis that I used to graph the planetary orbits. To make the simulation more accurate, I calculated the semi-minor axis using  [latex]b = a * \sqrt{1-e^2}[/latex], where b is the semi-minor axis, a is the semi-major axis, and e is the eccentricity. I also shifted over the orbit by half the difference between the perihelion and aphelion to make the sun a foci of every orbit.

Here’s an example of the edits I made to the code of the orbit (compare to the code I posted in Part 1):

if (planetmass == mercurymass)
     double semiminor = 57909050 * Math.Sqrt(1 - Math.Pow(0.20563, 2));
     double x = 640 + (semiminor * Math.Cos(iterations) / divider);
     double y = 360 + (69816900-46001200)/2/divider + (57909050 * Math.Sin(iterations) / divider);
     double[] pos = { y, x };
     return pos;

You can check out the effects of the above code in the screenshot below. Mercury’s orbit is the most pronounced change from previous versions of the program.


I’ve also overhauled the orbit coloring system. Instead of striping the orbits, which sometimes made the present position of each planet hard to see, instead, I’ve scaled the color change to the orbital velocity and circumference – every orbit around the sun has a distinct set of colors, which you can see above or in the video below at the bottom of the page.

Perhaps the coolest new feature I’ve added is the ability for the user to add asteroid by clicking. Firstly, to prevent conflict with the class GravAsteroid (since in C Sharp, you can’t access the same resource simultaneously on two or more fronts), I set a bool to check if it was in use. (Check out Part 2 for the code of GravAsteroid) While the program draws the asteroids from the list of Gravasteroids the boolean waitbetweenturns is false, anytime else, it is true.

Then, if the waitbetweenturns bool is true and the user hasn’t reached the maximum 343 asteroids, the program generates a random color and asteroid and adds them both to their respective lists. The -80 and -10 are there because there are 80 pixels between the top of the screen and the picturebox, and 10 pixels between the left edge of the screen and the picturebox.

        private void pictureBox1_Click(object sender, EventArgs e)
            System.Timers.Timer timer = new System.Timers.Timer(5000);
            timer.Elapsed += delegate { waitbetweenturns = true; };
            timer.AutoReset = false;
            SpinWait.SpinUntil(() => waitbetweenturns);
            if (trackBar1.Value < 343)
                Random randomGen = new Random(Guid.NewGuid().GetHashCode());
                KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
                KnownColor randomColorName = names[randomGen.Next(names.Length)];
                Color randomColor = Color.FromKnownColor(randomColorName);
                asteroids.Add(new Gravity.GravObject(this, MousePosition.Y - 80, MousePosition.X - 10));
                label4.Text = (Convert.ToInt32(label4.Text) + 1).ToString();
                MessageBox.Show("You've Reached the limit, can't add anymore asteroids.");

Here is a screenshot of the current build of the program, where both Saturn and Neptune have temporarily captured moons!


And a video of the orbital coloring and click to add asteroids in effect (up to many thousands of iterations). This time it’s on Youtube, as the file was too large to upload directly onto my site.

Please follow and like us:

Leave a Reply

Your email address will not be published.