Professional Documents
Culture Documents
3D Planetary system
Florin Nicusor Coada
SID:2887289
Contents
Abstract
Page 3
The Task
Page 3
1.Background Theory
Page 3
Page 3
Page 3
Page 4
Page 4
1.4.1 Camera 1
Page 4
1.4.2 Camera 2
Page 6
Page 6
Page 7
Page 7
Page 7
Page 7
Page 9
Page 9
Page 10
Page 11
2.4 Textures
Page 12
Page 13
2.6 Sounds
Page 13
2.7 Lighting
Page 14
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 Wikipedia.org , 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
Radius
Revolution
sun)
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
0.93
A.U.
Sun
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 www.lighthouse3d.com/ 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 <angleX> is the angle
between the vectors (x1,z1) and (x2,z2) in the XZ coordinates system ;
z
(x2,z2)
(x1,z1)
x
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
1.4.2 Camera 2
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.
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
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.
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);
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<nrMoons;i++)
{
moons[i].draw();
}
The Spin() function is used to increment the rotation angle stored in the
spin variable with the value stored in _speed. The function also checks to see if the
angle is greater than 360, and if it is true, will convert the angle to the first
quadrant.
The moon function is used to initialize the moons that will later spin around
the planet. This is done by calling the constructor of the moon class inside the
function. The k integer has the purpose to set which one of the moons from the
vector, if there is any, will be initialized.
The function setTextures() is used to store the textures path in the string
path[10] defined in the header. These textures will later be applied to planets.
setTag(char *s) and printTag() functions are used to store and print the
planets name. While the first functions just stores the name inside the *tag
variable, the second function is more complex and its not only used to print out
the stored value, but also to determine the planets position in the XZ coordinates
system using trigonometric functions.
angle=spin*2*M_PI/360;
int len, i;
//Set the new position for the text
glRasterPos3f(_x*cos(angle),_radius+0.1,-_x*sin(angle));
Because the spin angle is in degrees, a new angle variable is used to store
the same value written in radians.
In order to draw the orbit for the planet the function drawOrbit() has been
created. The function is called inside the draw function, before all the other
functions. It is mainly based on a function created to draw a circle by rotating a
vector. The idea for drawing the orbit was discussed in class during the lectures.
for(int i=0;i<360;i++)
{
angle = i*2*M_PI/360;
glVertex3f(_x*cos(angle),0,_x*sin(angle));
}
The function draws 360 points and connects them with lines giving the
impression of a circle.
Because the system was created using a scale, the speed of some planets
will be very low so a function updateSpeed() was created to increase and decrease
the value stored in the _speed variable.
The last function created was ring(float angle, double size) where angle is
used to rotate the ring around the Y axis and size sets the distance between the
inner and the outer radius of the ring.
One of the most important functions in the class is the constructor. Even
though it is only used to store values, it could also be used to add extra features to
the application, like placing the planets randomly on their orbit. This is done
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)
{
// 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;
Camera 1
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 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.4 Textures
The textures for this project have been done using tutorials from the
internet. One of the most useful tutorial was found at
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Nu
mber=267363 . 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
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.
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
Assigning textures path for the planet type items
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
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.
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);
There was no need for a light equation because glut does all these
calculations by itself.
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.
References
1. Lighthouse 3D, (n/a) OpenGL Tutorials [online] available from
<http://www.lighthouse3d.com/opengl/> [20 November 2010]
2. Gold Standard Group,(2010) The OpenGL Programming Guide The Redbook[online]
available from < http://www.opengl.org/documentation/red_book/> [15 November 2010]
3. Gold Standard Group, (2010) Transparency, Translucency and Blending [online] available
from < http://www.opengl.org/resources/faq/technical/transparency.htm> [25 November
2010]
November 2010
5. Gold Standard Group, (2010) OpenGL Documentation [online] available from
< http://www.opengl.org/sdk/docs/man/xhtml/ > [17 November 2010]
6. Liarokapis, F. (2010) Introduction to 3D Graphics Programming [online] available from <
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=12191> [ 10 November
2010]
7. Liarokapis, F. (2010) Introduction to OpenGL-GLUT [online] available from <
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=12940> [ 15 November
2010]
8. Liarokapis, F. (2010 Interaction and Callbacks [online] available from <
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=13424> [ 17 November
2010]
9. Liarokapis, F. (2010) Color [online] available from
<http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=12940> [ 25 November
2010]
10. Liarokapis, F. (2010) Introduction to OpenGL - Part I [online] available from
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=12945> [ 20 November
2010]
11. Liarokapis, F. (2010) Introduction to OpenGL - Part II [online] available from
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=12946> [ 25 November
2010]
12. Liarokapis, F. (2010) Introduction to OpenGL - Part III [online] available from
< http://moodle.coventry.ac.uk/ec/mod/resource/view.php?id=14305> [ 25 November
2010]