I'm making a simulation about two springs and one mass. I've made it through VPython using some graphics elements. I used the slider function from Vpython to try to change the variables of radius and mass of the ball, but it doesn't work properly. I want that the slider change the value of the mass and the radius of the ball in real time. Can someone help me please:(?
this is the code:
this is the information of the ball
massball=1
mass=massball
radius=2.5
ball=sphere(pos=vector(2,0,0),velocity=vector(0,0,0),radius=radius,mass=massball, color=color.blue)
this is the information of the sliders
scene2.caption = "Variación de la masa: Variación del radio:"
sl = slider(min=0.3, max=10, value=massball, length=220, bind=acc(), right=15)
sl2 = slider(min=0.3, max=10, value=radius, length=220, bind=acc(), right=15)
this is the main loop that affects the position of the ball
t=0
dt=0.01
while (t<100):
rate(500)
ball.velocity=ball.velocity+acc()*dt
ball.pos=ball.pos+ball.velocity*dt
spring_right.axis=ball.pos - wall_right.pos
spring_left.axis=ball.pos - wall_left.pos
ball.trail.append(pos=ball.pos)
t=t+dt
There are two problems.
bind
needs function's name without ()
and when you move slider then it automatically use ()
to run this function with values from slider. You had bind=acc()
which works as result = acc()
and bind=result
- so it tried run function result()
but result
is not function - and this raised error in console/terminal.
bind
shouldn't run acc()
because it is useless. This function doesn't change ball.mass
nor ball.radius
. It calculate some value and use return
to send this value but bind
can't get this value, and it can't use it to change ball parameters. Better is to use bind=function
with function which changes ball.radius = slider.value
By the way: Function without ()
which is asigned to variable in other function is often called "callback"
(not only in Python but also in other languages, ie. in JavaScript).
This code changes ball.radius
and ball.mass
when you move sliders.
At least you can see that ball changes size.
from vpython import *
# --- functions ---
def acc():
dr_right = ball.pos - wall_right.pos
force_right = -spring_right.constant*(mag(dr_right) - length)*norm(dr_right)
dr_left = ball.pos - wall_left.pos
force_left = -spring_left.constant*(mag(dr_left) - length)*norm(dr_left)
return (force_right+force_left) / ball.mass
def change_radius(widget):
print('radius:', widget.value)
ball.radius = widget.value
def change_massball(widget):
print('massball:', widget.value)
ball.mass = widget.value
# --- main ---
length = 30.
fric = 0.01
massball = 1
mass = massball
radius = 2.5
scene2 = canvas(title='Masa con dos sistemas', width=400, height=200, center=vector(0,0,0), background=color.white)
ball = sphere(pos=vector(2,0,0), velocity=vector(0,0,0), radius=radius, mass=massball, color=color.blue)
wall_right = box(pos=vector(length,0,0), size=vector(0.2, 5, 5), color=color.green)
wall_left = box(pos=vector(-length,0,0), size=vector(0.2, 5, 5), color=color.green)
spring_right = helix(pos=wall_right.pos, axis=ball.pos-wall_right.pos, constant=1, coils=10, thickness=0.2, radius=1, color=color.red)
spring_left = helix(pos=wall_left.pos, axis=ball.pos-wall_left.pos, constant=1, coils=10, thickness=0.2, radius=1, color=color.red)
scene2.caption = "Variación de la masa: Variación del radio:"
sl1 = slider(min=0.3, max=10, value=massball, length=220, bind=change_massball, right=15)
sl2 = slider(min=0.3, max=10, value=radius, length=220, bind=change_radius, right=15)
ball.trail = curve(color=ball.color)
t = 0
dt = 0.01
while t < 100:
rate(500)
ball.velocity = ball.velocity + acc() * dt
ball.pos = ball.pos + ball.velocity * dt
spring_right.axis = ball.pos - wall_right.pos
spring_left.axis = ball.pos - wall_left.pos
ball.trail.append(pos=ball.pos)
t = t + dt
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.