Variation on Solar System, help!

I’m taking the solar system tutorial code and building an atom with revolving electrons around it.

I’ve been using for loops since it’s all the electrons have mostly the same properties, except for the direction they orbit in. So around line 72 you’ll see I set up a random number generator to determine if the electron will orbit forward, backward, or not at all on each axis.

However, when I compile, all the electrons follow the exact same path, which is a strange path indeed. It goes all the way around, then pulls a couple loop-the-loops before repeating. I’m baffled.

I’m not even entirely sure if all the electrons are rendering, since they’re all in the same position at start. Any suggestions on how to distribute them random along all axis at equal distance from the center would be also be appreciated.

It’s a pretty small file so I’ll post the code:


# Orbit Simulation

import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.gui.DirectGui import *
from direct.showbase.DirectObject import *
from direct.showbase.RandomNumGen import * 

import sys

class World(DirectObject): #Main Class
    
    def __init__(self):    #Init: Called when a World obj is made
        self.title = OnscreenText(      #Display text onscreen
            text = "Experiment 1",      #Text input
            style = 3,                  #Text style
            fg= (1,1,1,1),              #Text color (r,g,b,a)
            pos = (1,-.95),             #Text position (-1-1,-1-1)
            scale = .07)                #Text scaling
        
        
        base.disableMouse()
        base.setBackgroundColor(.3,0,0)
        camera.setPos(0,0,45)    #Set camera position x,y,z
        camera.setHpr(0,-90,0)   #Set camera Heading,Pitch,Roll
        
        self.sizescale = .6
        self.orbitscale = 10
        self.yearscale = .1
        self.dayscale = self.yearscale / 365.0*10
        
        self.loadElectrons()
        self.rotateElectrons()
    
        
    
    def loadElectrons(self):
    
        self.sky = loader.loadModel("models/solar_sky_sphere")
        self.sky.reparentTo(render)  #Change parent to top node
        self.sky.setScale(40)        #Set scale
        self.sky_tex = loader.loadTexture("models/stars_1k_tex.jpg")
        self.sky.setTexture(self.sky_tex,1)
        
        #Load Nucleus
        self.nucleus = loader.loadModelCopy("models/planet_sphere")
        self.nucleus.reparentTo(render)
        self.nucleus.setScale(2 * self.sizescale)
        self.nucleus_tex = loader.loadTexture("models/phobos_1k_tex.jpg")
        self.nucleus.setTexture(self.nucleus_tex, 1)
        
        self.orbits = [0,0,0,0,0,0]
        self.electrons = [0,0,0,0,0,0]
        i = 0
        for i in range(6):               #Render and Texture electrons
            self.orbits[i] = render.attachNewNode('orbit_root_election'+str(i))
            self.electrons[i] = loader.loadModelCopy("models/planet_sphere")
            self.electron_tex = loader.loadTexture("models/sun_1k_tex.jpg")
            self.electrons[i].setTexture(self.electron_tex, 1)
            self.electrons[i].reparentTo(self.orbits[i])
            self.electrons[i].setPos(0.90 * self.orbitscale,0,0)
            self.electrons[i].setScale(.5 * self.sizescale)

                      
    def rotateElectrons(self):
            self.day_period_nucleus = self.nucleus.hprInterval(1, Vec3(360, 0, 0))
            
            self.day_period = [0,0,0,0,0,0]
            self.orbit_period = [0,0,0,0,0,0]
            
            for i in range(6):
                rn = RandomNumGen(5)
                x = rn.randint(-1,1)
                y = rn.randint(-1,1)
                z = rn.randint(-1,1)
                self.orbit_period[i] = self.electrons[i].hprInterval(
                    (0.241 * self.yearscale), Vec3(360*x,360*y,360*z))
                self.day_period[i] = self.orbits[i].hprInterval(
                    (59*self.yearscale), Vec3(360*x,360*y,360*z))
            
            self.day_period_nucleus.loop()
            for i in range(6):
                self.orbit_period[i].loop()
                self.day_period[i].loop()

#end class World
w = World()
run()

:open_mouth: You didn’t actually re-seed the radom number generator with the same value at the beginning of each loop did you? You realize that a pseudo-random number generator is completely deterministic, right?

Right, what he said. Try moving the call:


rn = RandomNumGen(5)

two lines up, so that it is outside the for loop. Otherwise you will be creating a new random number sequence for each electron, but using the same seed for each one (5), so that each will actually be exactly the same sequence as all the others.

To help you visualize the strange loop-the-loop behavior, try parenting an axis to the orbit point of one of your electrons, like this:

        axis = loader.loadModelCopy('zup-axis.egg')
        axis.reparentTo(self.orbits[0])

David

oh duh, I didn’t even realize that was the seed. Thanks!

Now they’re all taking their own orbits, but some seem to be orbitting around the original electron position, or around the midpoint of that position and the nucleus.

Dave, I’m not quite sure what you meant in the second part of your post?

Brian

You have two intervals that rotate nested NodePaths for each electron. This causes the electrons to move in a three-dimensional pattern because of the way the NodePaths are parented to each other. On the two-dimensional screen, it looks like they are just moving in some crazy loop-the-loop pattern, but it’s actually much simpler than that.

If you load a 3-d model, such as the axis, and parent it to the first NodePath of the two that control electron 0, it will help show what the electrons are actually doing, by making the three-dimensional motion apparent. One easy place to do this is at the end of the loadElectrons() method.

David