简体   繁体   English

在 Vpython 中更改变量的值

[英]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.我已经使用一些图形元素通过 VPython 实现了它。 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.我使用 Vpython 中的 slider function 尝试更改球的半径和质量变量,但它不能正常工作。 I want that the slider change the value of the mass and the radius of the ball in real time.我希望 slider 实时更改球的质量值和半径。 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这是影响球的 position 的主回路

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. bind需要不带()的函数名称,当您移动 slider 时,它会自动使用()运行此 function,其值来自 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=acc()它作为result = acc()bind=result - 所以它尝试运行 function result()result不是 function - 这在控制台/终端中引发了错误。

  2. bind shouldn't run acc() because it is useless. bind不应该运行acc()因为它没用。 This function doesn't change ball.mass nor ball.radius .这个 function 不会改变ball.massball.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.它计算一些值并使用return发送这个值,但是bind不能得到这个值,也不能用它来改变球的参数。 Better is to use bind=function with function which changes ball.radius = slider.value更好的是使用bind=function和 function 改变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).顺便说一句: Function 没有() ,它被分配给其他 function 中的变量,通常称为"callback" (不仅在 Python 中),而且在其他语言中也是如此。


This code changes ball.radius and ball.mass when you move sliders.当您移动滑块时,此代码会更改ball.radiusball.mass
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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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