Download - 3D Planetary System

  • 212CR 3D Graphic Programming:

    3D Planetary system

    Florin Nicusor Coada


  • Contents

    Abstract Page 3

    The Task Page 3

    1.Background Theory Page 3

    1.1 The Sun Page 3

    1.2 The planets Page 3

    1.3 Setting-up the Solar System Page 4

    1.4 Setting up the cameras Page 4

    1.4.1 Camera 1 Page 4

    1.4.2 Camera 2 Page 6

    1.5 Creating The Universe Page 6

    1.6 The menu Page 7

    2. Methodology and results Page 7

    2.1 Creating the classes: Page 7

    a. Planet class Page 7

    b. Moon class Page 9

    c. Asteroid class Page 9

    2.2 Cameras settings Page 10

    2.3 Sun and skybox Page 11

    2.4 Textures Page 12

    2.5 The menu Page 13

    2.6 Sounds Page 13

    2.7 Lighting Page 14

    2.8 General programming concepts Page 14

    Conclusion Page 15

    References Page 16

  • Abstract

    The task was implementing a 3D planetary system based on computer graphics principles. For this assignment glut has been used to create and

    animate the Solar system. The development of the system started from a piece of code offered by Prof. Fotis Liarokapis which was further developed and turned into a planetary system. The simulation was done using glut

    special functions and basic trigonometry for creating cameras and orbits. The finished version of the task is a 3D application with basic menus and

    user interactions with the system. Another important part of the project is that the construction allows easy customization of the planetary system and menus. This task was a very good chance for exercising programming

    techniques and acquiring basic OpenGL knowledge.

    The task

    Implement a 3D planetary system based on computer graphics principles. You will need to write from scratch a complete OpenGL programme that renders a Sun with an orbiting planet and a moon orbiting the planet simulating a planetary system.

    1. Background theory

    1.1 The Sun

    For the complition of this task I have decided to start my project from a example code offered by Prof. Fotis Liarokapis during the tutorials for 212CR 3D Graphics Programming. The code presented a torus being orbited by a a light source represented by yellow sphere. The first step taken towards the complition of the task was changing the light source into a static object, which will later be transformed into the Sun. After setting the center of the solar system the planets started to be put in place. The first planet in the system was done by simply drawing a solid sphere with no colour or texture to stay and positioning it at a specified distance from the Sun. 1.2 The planets After adding the first planet I started to add a few more, which I named at that point Mercury,Earth and Mars. Making the planets spin on an orbit was fairly

    easy since this function was set up in the example that I was offered for the tutorial classes. The only thing required in order to make the planets move on an orbit was changing the axis of movement to Y, which initialy was set to X. An additional spinning function has been added for makige the planets to spin aound their self axis like in order to make it look more realistic. Because in the real situation planets have different speeds I decided to do the same for my planetary system and add different speeds to the planets. Similar to the way I added planets around the Sun, I have decided to add a moon around the planet I named Earth. The moon had the capacity to speen around itself and on an determined orbit around a planet. Because drawing each planet individualy maked the code look mesy I have decide to create a planet class

  • that included draw, spin and other functions about which I will talk later in the Methodology section. 1.3 Setting-up the Solar System The system I have decided to simulate in my project is the system in which we live so I have used online information to try and represent a scale version of it. The scale is only appli ed to the planets radius, distance from the sun, orbital speed and the sun radius. Other elements represented in the system are placed to demonstrate the functionality of the system. Because the system I decided to simulate has an asteroid belt I have implemented a simple model constructed from ransom shaped items placed on a circle situated between two of my planets, Mars and Jupiter. The distances were taken from , The Free Encyclopedia, and were scaled down to be placed inside my aplication. The coversion made was by using 1 unit of distance in OpenGL as 1 A.U. (Astronomic Unit) in the Solar system.

    To keep the scale of the system I used a table, which is presented below:

    Name Satellites Nr. Distance(from sun)

    Radius Revolution time

    Mercury 0 0.4 A.U 0.016 A.U. 88

    Venus 0 0.7 A.U. 0.04 A.U. 225

    Earth 1 1 A.U. 0.04 A.U. 365

    Mars 0 1.5 A.U. 0.02 A.U. 687

    Jupiter 4 5.2 A.U. 0.44 A.U. 4,331

    Saturn 2 9.5 A.U. 0.37 A.U. 10,759

    Uranus 3 19.6 A.U. 0.16 A.U. 30,799

    Neptune 1 30 A.U. 0.15 A.U. 60,190

    Sun 0.93 A.U.

    Asteroids belt 2.3 and 3.3

    The initial source had the radius of the planets and the sun based on the radius of the earth, e.g. the radius of Jupiter is approximately 11times the radius of Earth. In order to maintain the scale, the radius of Earth measuring 6,378.1 Km is converted into 0.04 A.U. From this point on, all the other planets radiuses have been converted to Astral Units. Because the asteroids and the moons will be too small if the scale is kept, their radiuses have been slightly increased.

    1.4 Setting up the cameras The application created has two types of camera. The first camera is defined as a free roam camera, capable of going wherever the user might want, while the second camera is a mobile camera that is orbiting around the Sun with the ability of going closer or further from the Sun, based on the users needs. The second camera is also available to move up and down allowing the user to watch the

    system directly from above or below, while the first one is used mainly for closing in on different planets, moons and even the sun. The movement and orientation of the cameras is based on different techniques that will be presented below. 1.4.1 Camera 1 The main idea behind the camera 1 is to orient the camera on a sphere and move towards the point to witch the camera is looking at. The advantages of this camera are the possibility of free roaming and getting close to any point of interest, like the asteroids belt, a moon, a planet, or a planetary ring. The base idea for the camera was found in a tutorial presented on website, where the camera implement is changing its focus point on a circle and then is

  • moving towards it. The rotation is done by incrementing the rotation angle and then applying a trigonometric function to that angle. By normalizing the sphere, making the radius equal to 1, each coordinate will be the direct result of a trigonometric function. For the camera, the coordinates are calculated this way:

    sin(angleX) for the x coordinate, where is the angle between the vectors (x1,z1) and (x2,z2) in the XZ coordinates system ; z (x2,z2) (x1,z1) x

    -cos(angleX) for the z coordinate, where is the same angle as the one above;

    sin(angleY) for the y coordinate, where is the angle between the vectors (x1,y1) and (x2,y2) in the XY coordinates system; y (x2,y2) (x1,y1) x

    1.4.2 Camera 2

    Camera 1 -Orientation: x, y, z axis -Movement : x, y, z axis -Advantages: free roam -Drawbacks: -the camera is unable to look straight down or above - possibility to get lost

    Camera 1

    O represents the point where the camera is place

  • This camera is based on a cylinder type movement. While the Sun remains in the centre point of the cylinder, the radius and the height are suffering changes, allowing the user to define new viewing perspectives. In other words, the camera is moving on the outside of a cylinder by focusing always on the sun. Because the first camera presented is based on trigonometric functions, I have decided to make this camera using classic geometry, meaning the equation of the circle. Moving the camera left or right is based on incrementing or decrementing the value of x according to the type of movement the user wants to apply. After getting the value of x, because the centre of the circle on which the camera is

    moving the equation for finding the z value is , where r is the radius. The camera is also capable for up and down movements on the cylinder and this has been made possible by changing the value of y according to the needs of the user, without altering the value of x or z. The last feature of the camera is the Zoom In or Out function. The technique for zooming in or out is in fact based on increasing or decreasing the

    radius for the cylinder base. The equation used is x=x*(r+size)/r, where x is the coordinate on the x axis , r is the radius for the base of the cylinder, and size the value used to increase or decrease the radius.

    1.5 Creating The Universe Making the background for the system black has made the system feel unrealistic and increased the difficulty to orientate. In order to improve this aspects of the application a Skybox has been added. The skybox was created as a sphere on which was applied a star map like texture. Because the light source for the planetary system has been set inside the sphere, the texture that was applied was visible from the inside, creating the impression of endless space. Even though the skybox sphere has a big radius, limitations have been added to the camera to avoid

    it from getting outside the skybox. 1.6 The menu The main ideea of the menu was to create buttons and also to enable the use of keyboard to navigate through the menu. This plan was however abandoned because of the dificulty of creating buttons for the menu. As a result a new menu

    Camera 2 -Movement : x, z or y axis -Advantages: simulate the orbit of a planet -Drawbacks: -focus only on the sun -no possibility for looking behind the camera -reduced orientation options

    Camera 2 model

    Outside view of the Skybox

  • was designed, based upon having a moving sun in the left part of the screen and the instructions for the user o the right side. At the press of a buton the user can go to the planetary system and start interacting with the application. The application also uses a right-click base menu, available during the simulation.

    2. Methodology and results 2.1Creating the classes:

    a. Planet class The first created class for the project has been the planet class. This class has ben used to draw the planets, initialize and aply the textures, and other features that the planets have. Class variables: The variables _x, _y, _z are used to store the position in the XYZ coordinates system, while the _radius store the radius of the planet to be drawn. spin and

    _speed variables are used to store the current rotation angle and the value used to increment or decrement the rotation angle. texNr and *tag are used to store the number of the texture to be applied and the named of the planet which will be later printed. The *planet and planetTexture are used to define a new orthogon used for aplying the textures stored in the second variable. Because the planets can have none or multiple moons a vector of Moon class type has been defined and an integer nrMoons has been used to store the number of the moons. Class functions:

    The class constructor uses 6 arguments: x,y,z for the _x,_y,_z coordinates, r for the _radius value, the _speed value which is used to alter the rotation angle. The last value nr is assigned to texNr variable. The first listed function is called init() and it is used to initialize the textures for the planets and also helps initializing textures for the moons. The second listed function, draw() is the most important function of the class and it is used for drawing the planet base, a solid sphere, apllying textures and calling other functions used to draw the moons, the orbit and to print the name for each planet. One of the biggest problem while creating this functions was how apllying the textures. Because the spheres are by default drawn by the glut library along the Z axis a rotation of 90 degrees along the X axis was required in

    order to have the textures properly set.

    This rotation however changed the way the planets are spinning and rotating, so for a rotation around the Y the rotation should in fact take place around the Z axis. //Spin planet around self axis

    glRotated((GLdouble) spin*40, 0.0, 0.0, 1.0);

    Planet class header - variables

    //Rotate planet -90 on x axis, so the emispheres are set corectlly glRotated((GLdouble) -90, 1.0, 0.0, 0.0);

    Planet class header - functions 1

  • After drawing the spheres and applying the textures, the rings are being drawn if the planet that is being drawn is Saturn or Uranus. The program checks if the planet has a ring by looking if the *tag value is one of the planets mentioned above and then calls the ring function. if(tag=="Saturn") ring(20,0.2); if(tag=="Uranus") ring(5,0.1);

    The last stage of the draw() function is drawing the moons. This is done by calling the draw function for each moon located in the moons vector. for(i=0;i

  • assigning a random value, smaller than 360 and greater than0, to the spin value that defines the rotation angle. By having a random value the planets will start to spin each time from a different point.

    b. Moon class Even though the moon class is similar to the planet class, it does not

    inherit it. It is defined as an independent class used to draw and animate the moon or moons for each planet. The variable _x, _y, _z, _spin, _speed and _radius have the same use and purpose as the ones explained for the planet class. As in the planet class described above the draw(),spinm() and init() functions, have the role to draw the moons, define the rotation angle and initialize the textures. The textures are applied inside the draw() function, with the exception that here all the moons have the same texture.

    c. Asteroid class

    This class is used to draw the asteroid belt. It is based on a random generation of parameters like the x ,y and z coordinates and shape parameters used to define the shape of the sphere. By using random values for the asteroids, the resulting asteroid belt will be chaotic and will be similar to the model its trying to simulate. The most important function for this class is the main constructor. The only parameter sent, i, is used as an angle, to disperse the asteroids over a circle like area.

    Special features: 2.2 Cameras settings The application makes use of two cameras, operating using the systems described above. Both the cameras are keyboard controlled and have similar controls. The function used to read the keys is a special glut function glutKeyboardFunc(Keyboard) where Keyboards is a second function used for reading keys and assigning action to them. void Keyboard(unsigned char key, int A, int B) sending the ASCII code to be read by a switch function.

    if(cameraType==2) switch(key)

    Asteroid class constructor

  • { // Start rotation case '1': glutIdleFunc(spinScene2); // Sets the global idle callback break; // Stop rotation case '2': glutIdleFunc(spinScene1); // Sets the global idle callback break; //Camera 2 case 'a':

    moveLeft();break; case 'd':

    moveRight();break; }

    The cameraType variable is used to decide which one of the cameras is working and will be modified. If the value is 1 the keyboard will work with the

    Camera 1 while the value of 2 will enable the use of Camera 2. A special function has been assigned for the # key, which will switch from one camera type to the other. The switch between cameras is also enabled by right click mouse menu. Camera 2 Camera 1 case '#': cameraType=1; break;

    case '#': cameraType=2; break;

    The functions for each camera have been defined using a special function file camera.cpp and a header, camera.h, used for declaring the functions and the variables altered during the simulation. Because the cameras are based on different principles, different variables have been constructed for each camera, and also each camera has its own call for the gluLookAt() function that defines the viewing point.

    Variables //Camera 1 static float angleY=-0.630000, angleX=0.180000, ratio; static float x=-0.062538, y=23.972706, z=43.393322; static float lx=0.179030, ly=-0.589145, lz=-1.0;

    //Camera 2 static float speedL=-0.1,speedR=0.1; static float xp=8.0, yp=2.0, zp=6.0, side=1, radius=10;

    Functions //Camera 1 void moveMeFlat(int direction); void orientMeX(float angx,float angy); void orientMeY(float angx,float angy); void setCamera1();

    //Camera 2 void zoom(float size); void moveUp(float speed); void moveRight(); void moveLeft(); void setCamera2();

    gluLookAt() void setCamera1() { gluLookAt(x,y,z, x+lx,y+ly,z+lz, 0.0, 1.0, 0.0); }

    void setCamera2() { gluLookAt(xp,yp,zp, 0,0,0, 0.0,1.0,0.0); }

  • The inner part of the sun // Draw a sphere gluSphere(sun, sunRad-0.02, 100, 100); The outer part of the sun //Enable blend mode, this will make textures Transparent glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //set color and transparency below texture glColor4f(1.0,0.8,0.0,0.6); //Spin sun along self-axis glRotated((GLdouble) spin*2, 0.0, 0.5, -0.5); //draw sphere gluSphere(sun, sunRad, 100, 100);

    The variables are initialized with values that are used to set initial position of the camera and the viewpoint. For Camera 1, the angles were initialized in order to allow the user to continue the rotation of the viewpoint from the current angle. If not initialized, the camera would jump from the current viewing point to the one defined by the angleX=0 and angleY=0. The values used to initialize the cameras were taken by reading them after manually setting the camera in the desired position.

    2.3 Sun and skybox The Sun and the skybox will be explained in the same section of the report because they have been done using similar methods and are both textured and drawn using the same functions. The Sun is composed from two spheres spinning on

    different axes. This technique is used to create the sun of an active sun surface. Even though both spheres have the same texture, a special function offered by the glut library allowed the change in the colour tone for the outer sphere. The same functions enabled the use of alpha channel that made the whole sphere transparent. In order to achieve transparency only for the outer sphere the inner part of the sun has been drawn before the outer part. The sunRad variable used to define the radius for the inner and outer part of the sun is a global define constant with the value of 0.93(A.U.). The skybox has been constructed using a similar technique as the one used for the planets, moons and the Sun. A big sphere with a texture has been drawn right after drawing the Sun. However, this solution is slowing down the program because the time required applying the texture to a big item. The texture is light from the inside and creates for the viewer the effect of endless space. This is though a false assumption, because the cameras are set to stop the movement when they get to close to the edges, allowing the user only to move only inside the sphere where the system is placed. Because of the way it has been constructed, Camera2 in some special cases can go out from the sphere; however, this has been designed to be big enough for the user to see the system without problems. The way the texture is applied creates two black hole areas on the top and the bottom of the skybox. For this reason, in those places, the application is displaying a Black hole tag.

    2.4 Textures The textures for this project have been done using tutorials from the internet. One of the most useful tutorial was found at . The users not only explained how the textures work, they also published a piece of code that was used to load the textures for the application. As stated inside the textures.cpp file, I do not present this piece of code as being developed by myself. I do however understand the code that was presented and I have decided to use it to texture items present in the planetary system. The code is

  • glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0); planet = gluNewQuadric(); gluQuadricTexture( planet, GL_TRUE); planetTexture = LoadBitmap(path[texNr].c_str()); //Initialize textures for the moons

    void print() { int i,len; glRasterPos3f(_x,_y,_z); len = strlen(s); //draw 1 item at a time for (i = 0; i < len; i++) { if(_type==1) glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, s[i]); if(_type==2) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i]);

    } }

    based upon loading .bmp files that are then read pixel by pixel and then applied to an orthogonal. The same orthogonal is later used to represent the face of a sphere, representing a moon, a planet, the Sun or the skybox.

    The paths for the textures are stored in a string called path, which is initialized each time a new planet class type object is created. For the moon, the Sun and the skybox, a single path is directly defined.

    2.5 The menu The menu has been created by defining a still camera. In the left side of the screen, the animated image of the Sun has been placed, in order to make the menu feel more interactive. For printing the text in the menu, a simple text class has been defined. The class stores the text to be printed, and the coordinates used to define the text position. The class incorporates only one function, void print(),

    used to display the required text. The class

    makes use of the inline that allows the declaration of functions inside the header file, without requiring an additional .cpp file. Depending on the type of text that is displayed, title or subtitle, the function glutBitmapCharacter will print one letter at a time, from a predefined string s. The application will close the menu and begin the planetary system simulation when the key Space is pressed, defined by the ASCII code of 32, the pressing of these key will also produce some changes to the camera in order to correctly display the system.

    2.6 Sounds The background sound for the planet system has been created with the use of windows.h library. This library offers a simple audio rendering function PlaySound("soundtrack.wav",NULL,SND_FILENAME|SND_LOOP|SND_ASYNC);. The function loads a wave file which is looped for an infinite number of times or until the application is closed. The sound is only available during the simulation. The initial idea was to create a 3D sound coming from the Sun, but because the alut library was not working properly, an easier method has been used instead. The

    Assigning textures path for the planet type items

    Main menu

  • soundtrack has been kindly offered by Prof. Peter Every from Coventry University and it is a track entitled no invisible thing from the album Recovery.

    2.7 Lighting To better simulate the solar system only one light source has been used. This light source has been placed inside the sphere representing the Sun and it is spreading a constant light over all the objects in the system including the skybox. No other lighting parameter has been modified except the ambient light, which was used to darken the hidden parts of the planets and the moons. There was no need for a light equation because glut does all these

    calculations by itself.

    2.8 General programming concepts While programming one of the main reasons for creating classes was having a clear and well laid out code. Special functions have been added for things like calling the draw() function for the planet, asteroids, the sun and the skybox. By adding these extra functions, those that are located in the main.cpp file are clearer and easier to understand.

    Conclusion The project described above, represents the coursework for the 212CR 3D Graphic Programming and was intended to demonstrate the ability to develop a 3D graphics environment. The system described above represents an approximate simulation of our Solar System, by displaying planets, their approximate orbits, a sun, and other features. A more exact approach would have been put into practice if more time had awarded for this particular task. These changes would have included a new type of defining the asteroid belt, a new style for the planets ring and even a possible particle engine for the Sun.


    1. Lighthouse 3D, (n/a) OpenGL Tutorials [online] available from [20 November 2010]

    2. Gold Standard Group,(2010) The OpenGL Programming Guide The Redbook[online] available from <> [15 November 2010]

    3. Gold Standard Group, (2010) Transparency, Translucency and Blending [online] available from <> [25 November 2010]

    GLfloat ambient[] = {0.1,0.1,0.1,1.0}; //increase the darkness level for the hidden part of the planets and the moon glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);

  • 4. Gold Standard Group,(2010) Texture on a sphere [online] available from

    <> [23 November 2010

    5. Gold Standard Group, (2010) OpenGL Documentation [online] available from

    < > [17 November 2010]

    6. Liarokapis, F. (2010) Introduction to 3D Graphics Programming [online] available from < <> [ 10 November 2010]

    7. Liarokapis, F. (2010) Introduction to OpenGL-GLUT [online] available from < <> [ 15 November 2010]

    8. Liarokapis, F. (2010 Interaction and Callbacks [online] available from < <> [ 17 November 2010]

    9. Liarokapis, F. (2010) Color [online] available from [ 25 November 2010]

    10. Liarokapis, F. (2010) Introduction to OpenGL - Part I [online] available from <> [ 20 November 2010]

    11. Liarokapis, F. (2010) Introduction to OpenGL - Part II [online] available from <> [ 25 November 2010]

    12. Liarokapis, F. (2010) Introduction to OpenGL - Part III [online] available from <> [ 25 November 2010]