top of page

The project for this module was a visualisation to display the solar system (including the planets, the moon, the Sun and the asteroid belt), using C++ and OpenGL. The application can be downloaded here and the source code can be viewed here.

Solar System Visualisation

The visualisation renders the objects within a background to make it look like they are floating within space. The Sun lies in the centre of the visualisation with all of the planets (including Pluto) orbiting around it. The relative scales of the planets are represented, with Jupiter dwarfing the smaller planets such as Mercury and Mars. The different speeds of the planet orbits and axis rotations are also represented along with their axis inclines. The asteroid belt lies between Mars and Jupiter, with asteroids peppered in orbit along the distance between them. As earth orbits the Sun between Venus and Mars, the moon orbits the earth and is tidally locked, with the same side always facing inward towards the earth. The rings on both Saturn and Uranus are represented, with the rings of Uranus orbiting its sideways axis of rotation. Pluto’s inclined orbit is also represented in contrast with the other planets that all orbit within the same plane. Venus spins upside down which cause its orbit to move in the opposite way to the other planets which is also represented in the visualisation.

For the simulation, there was a number of housekeeping tasks needed. There was a change size function that handled whether the user tries to change the size of the window. It set the aspect ratio of the window and also made sure the size was within defined parameters. There was also a setup method which handled the lighting of the simulation and the default colour. There was a timer function to specify how many times the scene was redrawn every second. The render scene function was the main method that drew all the objects into the scene. I used a method to handle user input and used this to create a camera. I used the buttons I and O to zoom in and out and the W, A, S and D buttons for rotations on the X and Y axes. I also used Z and X for rotation about the Z axis. I did this by using global values to store the rotation and X, Y and Z coordinates. These values are incremented or decremented depending on what buttons the user presses. I set a restraint on the z coordinate to make sure the user cannot go out of the sky box or go into the Sun. I created an initial distance on the Z axis of -1650 to give the user an initial view of the solar system as a whole when the program begins.

The objects were drawn using matrices. For each object, the glPushMatrix() command would be called and then the colour, position and object itself would be specified. The positions would themselves be specified in separate commands for translations and rotations about each axis. When each object is finished then the glPopMatrix() command would be used. Rotation commands also accounted for the axis of the planets, and the rotations about their axes. To have a nested orbit for the moon to rotate around the earth while it rotated about the sun, the moon’s detail were specified inside the same push and pop body as the earth, and was drawn after. All the planets were drawn within the sun’s PushMatrix() and PopMatrix() commands and all the specific information about sizes, distances, and orbital speeds were contained within global arrays to be modified when needed.

The images were textured onto the planets using two methods, LoadBMP() and CreateTextures().  The LoadBMP() method is used to open the image file. It uses the file name, the width and the height of the texture as parameters. The CreateTexture() uses a pre declared set of texture variables to generate the textures for each planet and then binds each texture onto the planets. This method was called within the main method for each planet. To create the background a skybox was used. In the DrawSpace() method the skybox was drawn by binding 6 images into the scene, one for each side of the skybox (front, back, left, right, top and bottom). A quad was then created for each side and each corner of the quad given a position. As a result the images were set into the scene on all sides to create the illusion that the objects were orbiting in space.

The rings around Saturn and Uranus were drawn using gluDisk(). With this I specified the distance of the inner part of the ring from the plant centre and the distance of the outer part of the ring from the planet centre. I could use these 2 values to manipulate the size and distance of the ring. I drew multiple rings on both planets of different sizes to give them the unique look for each planet. To make the colour of the rings similar to the planets themselves, I bound the planet textures onto the rings. I encapsulated all this data into another method to be called in the DrawPlanets() method. To create the incline of the orbit on Pluto, a method was drawn with a simple algorithm to specify its orbit incline. The algorithm specifies the initial orbit incline as 17 degrees and, after each degree of orbit around the sun, the planet moves the corresponding amount of degrees down. When the incline reaches -17 degrees the planet begins to move back upwards until it reaches its initial position again. This calculated planet incline value was passed into a rotate command for Pluto to allow the incline to be drawn.

To create the asteroid belt another method was created, DrawAsteroid(), that passed in numerous parameters to control orbital speed, size, orbital distance and so on. The method is very similar to the draw planet method except only the asteroid texture is being mapped onto the objects, and the various attributes of the asteroid are passed in the method call and not in global arrays. This method binds the asteroid texture onto the object, and then draws the object with the various passed in parameters. Dozens of asteroids with different positions and speeds were drawn in order to form an asteroid belt between Mars and Jupiter.

bottom of page