提问人:Chris Ze Third 提问时间:4/13/2023 更新时间:4/22/2023 访问量:51
滑块的标题不可见 (VPython)
Captions of slider not visible (VPython)
问:
我用VPython创建了一个小小的3D模拟。有了它,滑块可以控制位置和颜色或对象。但是,我找不到一种方法来显示标题来指示滑块的内容。
我在定义滑块时添加了一个参数。我没有收到任何错误消息,因此我认为它的定义是正确的,但标题可能被隐藏或我在某处遗漏了某个步骤。wtitle
这是我的代码:
""" Import libraries """
import vpython as vp
""" Create Canvas """
canvas = vp.canvas(width=1080, height=720)
scene = vp.scene
""" Create objects """
# Define the planet
planet_radius = 5
# planet_texture = 'planet.jpg' # You can replace this with your own custom picture
planet = vp.sphere(radius=planet_radius, texture=vp.textures.earth, shininess=0)
def atm_opacity(wavelength):
return atm_density * (550 / wavelength)**4
# Define the atmosphere
atm_thickness = 3.0 # You can modify this using a slide cursor
atm_density = 0.5 # You can modify this using a slide cursor
atm_radius = planet.radius+atm_thickness
atm = vp.sphere(radius=atm_radius, opacity=0.25)
atm.opacity_function = atm_opacity
# Define the light source
def light_color(wavelength):
r, g, b = 0, 0, 0
if wavelength >= 400 and wavelength < 440:
r = -(wavelength - 440) / (440 - 400)
b = 1.0
elif wavelength >= 440 and wavelength < 490:
g = (wavelength - 440) / (490 - 440)
b = 1.0
elif wavelength >= 490 and wavelength < 510:
g = 1.0
b = -(wavelength - 510) / (510 - 490)
elif wavelength >= 510 and wavelength < 580:
r = (wavelength - 510) / (580 - 510)
g = 1.0
elif wavelength >= 580 and wavelength < 645:
r = 1.0
g = -(wavelength - 645) / (645 - 580)
elif wavelength >= 645 and wavelength <= 700:
r = 1.0
return vp.vector(r, g, b)
light_type = 'red' # You can modify this using a drop-down menu
# light_wavelength = 550 # You can modify this using a slide cursor
light_size = 2 # You can modify this using a slide cursor
light_intensity = 1.0 # You can modify this using a slide cursor
pos_drift = 50
light_xpos = atm_radius+pos_drift
light_ypos = atm_radius+pos_drift
light_zpos = atm_radius+pos_drift
light_pos = vp.vector(light_xpos, light_ypos, light_zpos)
wavelength = 400
light = vp.local_light(pos=light_pos, color= light_color(wavelength), radius=light_size)
light.color_function = light_color
# Define the camera
scene.autoscale = False
scene.range = 10
scene.forward = vp.vector(0, 0, -1)
scene.up = vp.vector(0, 1, 0)
scene.caption = 'Click and drag on the light source to move it. Use the drop-down menu and slide cursors to adjust its properties.'
""" Define the event handlers """
def on_light_down(evt):
global light_dragging, light_drag_pos
light_dragging = True
light_drag_pos = evt.pos
def on_light_move(evt):
global light_dragging, light_drag_pos
if light_dragging:
light.pos += evt.pos - light_drag_pos
light_drag_pos = evt.pos
def on_light_up(evt):
global light_dragging
light_dragging = False
# Bind the event handlers
vp.scene.bind('mousedown', on_light_down)
vp.scene.bind('mousemove', on_light_move)
vp.scene.bind('mouseup', on_light_up)
def on_mouse_down(event):
global dragging, last_mouse_pos
obj = scene.mouse.pick
if obj == light:
dragging = True
last_mouse_pos = scene.mouse.pos
canvas.bind('mousedown', on_mouse_down)
# Create the slider to rotate the light source around
def set_rotation_angle(slider):
# light.rotate(angle=slider.value, axis=vp.vector(0, 1, 0), origin=planet.pos)
# Calculate the rotation angle
angle = vp.radians(slider.value)
# Calculate the new position of the object
x = atm_radius+pos_drift * vp.cos(angle)
y = 0
z = atm_radius+pos_drift * vp.sin(angle)
# Set the position of the object
light.pos = vp.vector(x, y, z)
# Create the slider
slider = vp.slider(wtitle='Rotate light source', min=0, max=360, step=1, value=0, bind=set_rotation_angle)
# Create slider to change light source wavelength
def WL_cursor(slider):
val = slider.value
new_wavelength = light_color(val)
global light
light.color = new_wavelength
slider = vp.slider(wtitle='Change light source color', min=400, max=700, length=250, bind=WL_cursor)
# Define the white light button
def white():
global light
light.color = vp.color.white
# Create the exit button
white_button = vp.button(bind=white, text="White light")
""" Run the simulation """
while True:
vp.rate(30)
# Update the atmosphere
atm.radius = planet.radius+atm_thickness
atm.opacity = 0.25*atm_density
# Update the light source
light.radius = light_size
light.intensity = light_intensity
light.pos = light.pos
# Update the camera
vp.scene.center = planet.pos
答:
1赞
Chris Ze Third
4/14/2023
#1
出于某种原因,您需要将其添加到滑块中,而不是将滑块添加到中。所以像这样:scene
canvas
slider_angle = vp.slider(wtitle='Rotate light source', min=0, max=360, step=1, value=0, bind=set_rotation_angle, right=15)
canvas.append_to_caption('Slide the cursor to move the light source.')
canvas.append_to_caption('\n\n')
1赞
user1114907
4/22/2023
#2
VPython 会自动创建一个名为“scene”(或您中为“vp.scene”)的画布。然后说 scene = vp.scene,并设置此画布的各种属性,例如 scene.autoscale = False。但是,您还会创建第二个画布,名为 canvas: canvas = vp.canvas(...)。您的大多数程序都引用了名为 scene 的画布,但您将“mousedown”绑定到 canvas,这很令人困惑。最干净的方法是删除“画布”的创建并将鼠标向下绑定到场景。
评论