简体   繁体   中英

Change value of variables in Vpython

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 system

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

Complete code here

There are two problems.

  1. 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.

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM