I'm having some trouble with vpython for my first-year programming project. The code below is a solar system simulator and I'm having issues with pausing animations and restarting them. I also tried to add a feature where if you click on a planet it will refocus the camera on the planet, which seems to work, but the problem is that it will also stop the animation when you click anywhere at all, including the planet.
I know it's a lot of code, just skip by all the initial vectors to get to the actual code.
from visual import*
animationState = True #false means paused
timeCounter = 0
planet = []
#############################################################################################
#initial settings used for restart
rR = array([(0.000000000000000E+00, 0.000000000000000E+00, 0.000000000000000E+00),#sun
(5.090545062081090E-02, 3.026749904512873E-01, 2.005828108770193E-02), #mercury
(5.334568267378945E-02, -7.251674649396830E-01, -1.300923639252336E-02), #venus
(-1.760244040998966E-01, 9.674489289012235E-01, -2.152342191820744E-05), #earth-moon
(-7.296712817647736E-01, 1.454285819941169E+00, 4.838986949012574E-02), #mars
(4.509063595460582E+00, -2.166481579004603E+00, -9.190951290863629E-02), #jupiter
(-9.464255599948979E+00, 2.586904325731433E-01, 3.722092945090654E-01), #saturn
( 2.003661872741455E+01, -1.532716169377917E+00, -2.652270073457507E-01), #uranus
( 2.481716786736616E+01, -1.689759430268212E+01, -2.239327824583291E-01), #neptune
(1.627770587515934E+00, -3.158742490014637E+01, 2.909968799374562E+00)])#pluto
#################################################################################################
#initial velocity vectors in AU/day from the same JPL website
vR = array([(0.000000000000000E+00, 0.000000000000000E+00, 0.000000000000000E+00),#sun
(-3.338635380394891E-02, 5.708050085963649E-03, 3.529857082782131E-03),#mer
(2.003526527891491E-02, 1.410781574977480E-03, -1.136957543801592E-03),#ven
(-1.720617443239716E-02, -3.144616524430499E-03, 1.224741879777691E-07), #e-m
(-1.197728348484489E-02, -5.087002418322004E-03, 1.875195874058323E-04), #mars
( 3.177262470956793E-03, 7.166559251884697E-03, -1.008630859310389E-04), #jupiter
( -4.491079436483178E-04, -5.582715023870477E-03, 1.148209432467037E-04), #saturn
(2.738017799392548E-04, 3.743826969651156E-03, 1.030420822391787E-05), #uranus
(1.749280849208349E-03, 2.619195748602472E-03, -9.404378151664699E-05), #neptune
( 3.204276100513413E-03, -4.279441339910556E-04, -8.750106823643653E-04)])#plu
##################################################################################################
#gravitational constant times mass of body
GmR = array([
2.959122082855911e-004, # SUN
4.912547451450812e-011, # Mercury
7.243456209632766e-010, # Venus
8.997011658557308e-010, # Earth
9.549528942224058e-011, # Mars
2.825342103445926e-007, # Jupiter
8.459468504830660e-008, # Saturn
1.288816238138035e-008, # Uranus
1.532112481284276e-008, # Neptune
2.276247751863699e-012 ]) # Pluto
####################################################################################################
#making the array of initial planet positions, hardcoded
#these are 3-D position vectors in Astronomical Units taken from JPL NASA website
r = array([(0.000000000000000E+00, 0.000000000000000E+00, 0.000000000000000E+00),#sun
(5.090545062081090E-02, 3.026749904512873E-01, 2.005828108770193E-02), #mercury
(5.334568267378945E-02, -7.251674649396830E-01, -1.300923639252336E-02), #venus
(-1.760244040998966E-01, 9.674489289012235E-01, -2.152342191820744E-05), #earth-moon
(-7.296712817647736E-01, 1.454285819941169E+00, 4.838986949012574E-02), #mars
(4.509063595460582E+00, -2.166481579004603E+00, -9.190951290863629E-02), #jupiter
(-9.464255599948979E+00, 2.586904325731433E-01, 3.722092945090654E-01), #saturn
( 2.003661872741455E+01, -1.532716169377917E+00, -2.652270073457507E-01), #uranus
( 2.481716786736616E+01, -1.689759430268212E+01, -2.239327824583291E-01), #neptune
(1.627770587515934E+00, -3.158742490014637E+01, 2.909968799374562E+00)])#pluto
######################################################################################################
#initial velocity vectors in AU/day from the same JPL website
v = array([(0.000000000000000E+00, 0.000000000000000E+00, 0.000000000000000E+00),#sun
(-3.338635380394891E-02, 5.708050085963649E-03, 3.529857082782131E-03),#mer
(2.003526527891491E-02, 1.410781574977480E-03, -1.136957543801592E-03),#ven
(-1.720617443239716E-02, -3.144616524430499E-03, 1.224741879777691E-07), #e-m
(-1.197728348484489E-02, -5.087002418322004E-03, 1.875195874058323E-04), #mars
( 3.177262470956793E-03, 7.166559251884697E-03, -1.008630859310389E-04), #jupiter
( -4.491079436483178E-04, -5.582715023870477E-03, 1.148209432467037E-04), #saturn
(2.738017799392548E-04, 3.743826969651156E-03, 1.030420822391787E-05), #uranus
(1.749280849208349E-03, 2.619195748602472E-03, -9.404378151664699E-05), #neptune
( 3.204276100513413E-03, -4.279441339910556E-04, -8.750106823643653E-04)])#plu
######################################################################################################
#gravitational constant times mass of body
Gm = array([
2.959122082855911e-004, # SUN
4.912547451450812e-011, # Mercury
7.243456209632766e-010, # Venus
8.997011658557308e-010, # Earth
9.549528942224058e-011, # Mars
2.825342103445926e-007, # Jupiter
8.459468504830660e-008, # Saturn
1.288816238138035e-008, # Uranus
1.532112481284276e-008, # Neptune
2.276247751863699e-012 ]) # Pluto
#######################################################################################################
bodyList = ["sun", "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"]
def animate(r, v, Gm):
global animationState
global timeCounter
global bodyList
global planet
totalNumberOfPlanets = len(v)
center=0
a=zeros((totalNumberOfPlanets,3)) # acceleration of ith by jth
planet=range(totalNumberOfPlanets)
for i in range(totalNumberOfPlanets):
planet[i]=sphere( pos=r[i]-r[center],radius = 0.2)
planet[i].trail=curve( color=(1.,7,2))#draws a path behind the planet as it moves
planet[0].color=color.orange #sun specifics
planet[0].material = materials.emissive
planet[0].radius= 0.004652468615890587*10
planet[1].color=color.red #merc specifics
planet[1].radius = 1.6310378480995735e-05*1000
planet[2].radius = 4.04537494e-5*1000 #venus
planet[2].material = materials.wood
planet[3].radius = 4.26349283e-5*1000#earth
planet[3].material = materials.earth
planet[4].radius = 2.27075228e-5*1000 #mars
planet[4].color = color.orange
planet[4].material = materials.earth
planet[5].radius = 0.000477894089*1000 #jupiter
planet[6].radius = .000402866348*1000 #saturn
planet[7].radius = .000170851215*1000 #uranus
planet[8].radius = .000165536972*1000 #neptune
planet[9].radius = 7.88780599e-6*1000 #pluto
dt=.01
while True:
if animationState == True:
# get new interplanet acceleration vectors
for i in range(totalNumberOfPlanets): # N is number of bodies: loop over all
a[i]=vector(0,0,0) # initialise acceleration of body i to 0
for j in range(totalNumberOfPlanets): # cycle through all moving bodies
if i == j: continue # if i and j are the same, then they refer to the same planet
R = r[i]-r[j] # displacement
a[i]=a[i]-Gm[j]*R/mag(R)**3
v=v+a*dt #continuously
r=r+v*dt
timeCounter+=dt #number of days elapsed
# move everything
for i in range(totalNumberOfPlanets):
planet[i].pos=r[i]-r[center]
planet[i].trail.append( pos=planet[i].pos )
mousePressed()
keyPressed(r, rR, v, vR, Gm, GmR)
elif animationState == False:
mousePressed()
keyPressed(r, rR, v, vR, Gm, GmR)
#################
#sunLabel =label(pos=planet[0].pos,text= bodyList[0], xoffset= (planet[0].radius),\
#yoffset=planet[0].radius, space=planet[0].radius, height=10, border=6,\
# font='sans')
#labels
#MercuryLabel
#VenusLabel
#earthLabel
#marsLabel
#jupiterLabel
##########################################################
def keyPressed(r, rR, v, vR, Gm, GmR):
global animationState
global stop
global timeCounter
if scene.kb.keys: #waits for input
keyEntered = scene.kb.getkey()
if keyEntered == "r": #r restarts everything
r= rR #resets everything to initial
v=vR
Gm=GmR
timeCounter = 0
#animationState == False
if keyEntered == "p":
if animationState == True:
animationState = False
elif animationState == False:
animationState == True
if keyEntered == "<space>":
scene.center = (0,0,0)
########################################################
def mousePressed():
global planet
if scene.mouse.events:
for i in range(len(planet)):
click = scene.mouse.getevent()
if click.pick == planet[i]: #focuses on planet getting clicked
scene.center = (planet[i].pos)
else:
continue
#zoom?
#display label?
#display planet info in other window?
########################################################
def storePlanetNames():
global planet
sun = planet[0]
mercury = planet[1]
venus = planet[2]
earth = planet[3]
mars = planet[4]
jupiter = planet[5]
saturn = planet[6]
def controlBox():
42 #placeholder
def displayInformation():
42 #placeholder
animate(r, v, Gm)
while animationState == False:
mousePressed()
keyPressed(r, rR, v, vR, Gm, GmR)