【问题标题】:Change value of variables in Vpython在 Vpython 中更改变量的值
【发布时间】:2021-12-29 21:27:31
【问题描述】:

我正在模拟两个弹簧和一个质量。我已经使用一些图形元素通过 VPython 实现了它。我使用 Vpython 中的滑块函数来尝试更改球的半径和质量变量,但它不能正常工作。我希望滑块实时更改质量的值和球的半径。有人可以帮我吗:(?

This is the system

这是代码:

这是球的信息

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)

这是滑块的信息

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)

这是影响球位置的主循环

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

【问题讨论】:

  • 现在我们不能简单地复制所有代码并运行它。您是否在控制台/终端中运行它?当我运行以前的版本时,它会在控制台中显示错误。 bind= 需要没有 () 的函数名称 - bind=acc - 当您移动 silder 时,它将使用 () 运行它 acc()
  • 我正在使用最新版本的 VPython 和 Spyder,我也使用了 VPython7 中描述的函数来制作所有程序。我真的不知道为什么它在您的控制台中显示错误:(
  • 我认为bind=acc 没用。滑块运行acc(),但无法获得返回值,也无法使用while循环改变位置。
  • 正如我所说 - 它显示错误,因为您在 bind=acc() 中使用了 ()bind 只需要名称 bind=acc 并且当您移动滑块时,它应该使用 () 来运行此功能。目前它作为value = acc()bind=value 工作 - 所以它分配了一些value,而不是函数,它尝试运行value()value 不是函数,这会引发错误。
  • 顺便说一句:您可以添加有问题的链接。更多的人会看到它——也许会有更多的人帮助你。

标签: python css animation vpython


【解决方案1】:

有两个问题。

  1. bind 需要没有() 的函数名称,当您移动滑块时,它会自动使用() 使用滑块中的值运行此函数。 你有bind=acc(),它作为result = acc()bind=result工作——所以它尝试运行函数result()result不起作用——这在控制台/终端中引发了错误。

  2. bind 不应该运行acc(),因为它没用。此函数不会更改 ball.massball.radius。它计算一些值并使用return 发送该值,但bind 无法获取该值,也无法使用它来更改球参数。更好的是使用 bind=function 与更改 ball.radius = slider.value 的功能


顺便说一句: 没有() 的函数在其他函数中分配给变量通常称为"callback"(不仅在Python 中,而且在其他语言中,即在JavaScript 中)。


当您移动滑块时,此代码会更改 ball.radiusball.mass
至少你可以看到球的大小发生了变化。

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

【讨论】:

  • 非常感谢。这真的是我需要的:D。另外,感谢您在这个社区开始的所有建议,您是大师。
猜你喜欢
  • 1970-01-01
  • 2013-06-28
  • 1970-01-01
  • 2019-03-21
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多