How can I clear gcurve or gdots from a gdisplay, so that I can recompute & display it with new parameters?
(I didn't originally define rst as a separate function, but it was suggested on another thread... it seems to have made no difference.)
More specifically, I'd be really grateful for some more detailed feedback from Bruce. I'm teaching for the first time out of Matter & Interactions. I'm also totally new to python and vpython, so I'm sure my code is really clunky. But I'm trying to implement the "momentum principle in update form" to demonstrate two effects:
(1) no matter what I try, the slider bar & dropdown menu stubbornly overlay themselves on top of the scene1 instead of beneath it, so they obscure the animation
(2) I can't erase the old gcurve & gdots, so each time the user changes a parameter, it just plots a new curve on top of the old and clutters up the whole gdisplay
GlowScript 1.1 VPython
# Written by Jenny Hoffman, University of British Columbia.
# Fall 2015, Physics 107
# Illustrates the Momentum Principle in Update Form.
# Inspired by Chabay & Sherwood, "Matter & Interactions", 4th ed
k=10 # spring constant in N/m
L=1 # spring rest length in m
br=0.1 # ball radius in m
bm=0.1 # ball mass in kg
anchor=vector(0,L+br,0) # anchor point of top of spring
stretch=1.2 # starting stretch of the spring
dt=0.1
tmax=4 # 4 seconds should be 4 periods of the spring
val="vf" # whether to update using vi, vf, or vavg
Nth=0 # just for debugging: how many times did we run the bounceball loop?
sz=200
scene1=canvas(x=0,y=0,width=sz,height=sz,range=L+br,userzoom=False,userspin=False)
spring = helix(canvas=scene1, pos=anchor, axis=vector(0,-stretch*L,0), radius=br, color=color.green, coils=10)
ball = sphere(canvas=scene1, pos=spring.pos+spring.axis-vector(0,br,0), radius=br, color=color.red)
ball.p = vector(0,0,0) # initial momentum
ball.m = bm
# here we make a slider to change the time interval dt
scene1.caption.text("Vary the time interval: ")
def setdt():
global dt
dt = $("#dt_slider").slider("value")
bounceball()
$('<div id="dt_slider"></div>').appendTo(scene1.caption).css(width="200px")
$(def ():
$("#dt_slider").slider(value=dt, min=0.01, max=0.5, range="min", slide=setdt, change=setdt)
)
# here we choose between using vi, vf, or vavg to update
choose = $("<p>Change the velocity update method: </p>").appendTo(scene1.caption)
# Create a drop-down menu (a "select" object). Set up the options to appear:
s = ""
s += "<option select=selected>vf</option>"
s += "<option>vavg</option>"
s += "<option>vi</option>"
$('<select/>').html(s).css(font="sans").change(def (): # come here when a change is made in the menu choice
global val
val = $(this).val()
bounceball()
).appendTo(choose) # place drop-down menu beside the text, "Change the v update method: "
gd = gdisplay(width=400, height=scene1.height,
# xtitle='t', ytitle='y',
foreground=color.black, background=color.white,
xmax=tmax, xmin=0, ymax=L+br, ymin=-L-br)
line1 = gcurve(color=color.blue)
dots1 = gdots(color=color.red)
scene1.wrapper.css("float", "left")
gd.wrapper.css("float", "right")
bounceball()
while True: # this should just wait for the user to change dt or vupdate method
rate(10)
pass
def rst():
global spring, ball, line1, dots1
spring.axis=vector(0,-stretch*L,0)
ball.pos=spring.pos+spring.axis-vector(0,ball.radius,0)
ball.p = vector(0,0,0)
line1.clear()
dots1.clear()
line1 = gcurve(color=color.blue)
dots1 = gdots(color=color.red)
def bounceball():
global ball, spring, line1, dots1, Nth
print("Entering function bounceball: ", Nth)
rst()
t=0.0
while t<tmax:
rate(10)
line1.plot(pos=(t,ball.pos.y))
dots1.plot(pos=(t,ball.pos.y))
F=-k*ball.pos
ball.p = ball.p+F*dt
ball.vf = ball.p/ball.m
if val == "vi":
elif val == "vf":
vupdate=ball.vf
elif val == "vavg":
vupdate=ball.vavg
ball.pos = ball.pos+vupdate*dt
spring.axis = ball.pos+vector(0,ball.radius,0)-anchor
t=t+dt
Nth=Nth+1