2
votes

I am trying to make a solar system in OpenGL but the planet is not revolving around sun. That is revolving around some other axis. How to fix this?

First, I am drawing a sun, Then, there is rotation, translation and again rotation of first planet. So it should revolve around the sun and rotate on it's own axis, but that's not happening.

I also want to make the circle on which planet will revolve. How to make the circles in XZ plane (possibly)

from __future__ import division
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

year = 0
day = 0

def init(): 
   glClearColor (0.0, 0.0, 0.0, 0.0)
   glShadeModel (GL_FLAT)


def display():

   global day, year

   glClear (GL_COLOR_BUFFER_BIT)

   glColor3f (1.0, 1.0, 0, 1)
   glPushMatrix()
   glutSolidSphere(1.0, 20, 16)   # draw sun

   glRotatef(year, 0.0, 1.0, 0.0)
   year = (year + 1) % 360

   glPushMatrix()
   glTranslatef(2.0, 0.0, 0.0)
   glRotatef(day, 0.0, 1.0, 0.0)
   day = (day + 1) % 360

   glColor3f (0, 0, 1.0);
   glutWireSphere(0.2, 10, 8)    # draw smaller planet
   glPopMatrix()

   glPushMatrix()
   glTranslatef(4.0, 0.0, 0.0)
   glRotatef(day, 0.0, 1.0, 0.0)
   glColor3f (1, 0, 0.0, 1)
   glutWireSphere(0.2, 10, 8)
   glPopMatrix()

   glPopMatrix()
   glutSwapBuffers()

   # delay
   for i in range(100000):
      pass

def reshape(w, h):
   glViewport (0, 0, w, h)
   glMatrixMode (GL_PROJECTION)
   glLoadIdentity ()
   gluPerspective(70.0, w/h, 1.0, 20.0)
   glMatrixMode(GL_MODELVIEW)
   glLoadIdentity()
   gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)

glutInit()
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(800, 800)
glutInitWindowPosition (100, 100)
glutCreateWindow("Transformation")
init ()
glutDisplayFunc(display)
glutIdleFunc(display)
glutReshapeFunc(reshape)
glutMainLoop()
1
Planet should go behind the sun (invisible for some time) and then it would be visible after coming back, but that' not happening.Adarsh Jain
If you want the real thing see Is it possible to make realistic n-body solar system simulation in matter of size and mass? and use Kepler's equation. It is also better to manage the matrices for each body a bit differently for more info see Understanding 4x4 homogenous transform matrices so compute position by Kepler, orientation from time and periods and construct your matrix... as glRotate will not give you elliptic trajectory ...Spektre

1 Answers

3
votes

Planet should go behind the sun (invisible for some time) and then it would be visible after coming back, but that' not happening.

You have to enable the depth test and you have to clear the depth buffer.

The depth test can be enabled by glEnable(GL_DEPTH_TEST). The default depth function glDepthFunc is GL_LESS. This causes that fragments which are behind a fragment that was drawn before, are skipped:

Before every frame the depth buffer has to be cleared, by glClear(GL_DEPTH_BUFFER_BIT), to restart this process.

Add the following lines to your code, at the begin of display:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glEnable( GL_DEPTH_TEST )

Of coures you have to create a window with a depth buffer (glutInitDisplayMode(GLUT_DEPTH)):

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)

See the preview:

enter image description here



Can you also tell how to make circle where the planet is revolving?

I recommend to use time for setting up the simulation. The following example shows the sun, earth and the moon (Of course it is a very very simplified simulation with completely wrong sizes and distance relations):

import time

start_time = time.time()

def display():

    t = time.time() - start_time
    year_period = 5.0                  # 5 seconds for simulating one year 
    year     = (t / year_period)
    day      = 365 * year
    moon_sid = (365 / 27.3) * year

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
    glEnable( GL_DEPTH_TEST )

    glColor4f (1.0, 1.0, 0, 1)
    glPushMatrix()
    glutSolidSphere(1.0, 20, 16)             # sun

    glRotatef(year*360.0, 0.0, 1.0, 0.0)     # earth rotation around the sun 
    glTranslatef(3.0, 0.0, 0.0)              # earth location

    glPushMatrix()                           # push earth system 

    glPushMatrix()
    glRotatef(day*360.0, 0.0, 1.0, 0.0)      # earth spinn
    glRotatef(90-23.4, 1.0, 0.0, 0.0)        # earth axis
    glColor3f (0, 0, 1)                      # blue
    glutWireSphere(0.3, 10, 8)               # earth
    glPopMatrix()

    glPushMatrix()
    glRotatef(moon_sid*360.0, 0.0, 1.0, 0.0) # moon sidereal
    glTranslatef(1.0, 0.0, 0.0)              # distance moon to earth
    glRotatef(90, 1.0, 0.0, 0.0)
    glColor4f (0.4, 0.5, 0.6, 1)                         
    glutWireSphere(0.1, 10, 8)               # moon
    glPopMatrix()

    glPopMatrix()                            # pop earth system 

    glPopMatrix()
    glutSwapBuffers()

enter image description here