编辑:我现在已经解决了我问过的问题。球体在角落里离开了盒子,if语句(在下面显示的while循环中)被混淆了。在与墙壁接触时反转速度的各个组成部分的代码中,使用了一些elif语句。当使用elif(据我所知),如果球体一次超过一个位置限制,程序只会反转其中一个的速度分量。用if if替换elif就可以解决这个问题了。我不确定我是否完全理解这背后的原因,所以希望有人比我更聪明地评论这些信息,但是现在,如果有人有同样的问题,我希望我的有限输入有帮助!
首先是上下文:
我试图在VPython中建立一个气体动力学理论模型,作为我(物理)学位的修订练习。这涉及到我建造一个空心盒子并在其中放置一堆球体,随机放置在整个盒子中。然后,我需要为每个球体分配自己的随机速度,然后使用一个循环来调整每个球体的位置,参考其速度矢量和时间步长。
球体也应与每个墙壁和所有其他球体发生弹性碰撞。
当球体在x方向上与墙壁相遇时,其x速度分量反转,并且在y和z方向上类似。 当球体与另一个球体相遇时,它们会交换速度。
目前,我的代码的工作原理是创建正确数量的球体并随机分布它们并为每个球体提供自己的随机速度。除了碰撞之外,球体也应该移动。球体应该都留在盒子内部,因为它们应该从所有的墙壁上反弹。它们似乎互相反弹,但偶尔会有一两个球直接穿过盒子。
我对编程非常陌生,我不太了解这里发生了什么或者为什么会发生这种情况,但如果有人能帮助我,我会非常感激。< / p>
以下是我到目前为止的代码(我已尝试评论我在每一步所做的事情):
##########################################################
# This code is meant to create an empty box and then create
# a certain number of spheres (num_spheres) that will sit inside
# the box. Each sphere will then be assigned a random velocity vector.
# A loop will then adjust the position of each sphere to make them
# move. The spheres will undergo elastic collisions with the box walls
# and also with the other spheres in the box.
##########################################################
from visual import *
import random as random
import numpy as np
num_spheres = 15
fps = 24 #fps of while loop (later)
dt = 1.0/fps #time step
l = 40 #length of box
w = 2 #width of box
radius = 0.5 #radius of spheres
##########################################################
# Creating an empty box with sides length/height l, width w
wallR = box(pos = (l/2.0,0,0), size=(w,l,l), color=color.white, opacity=0.25)
wallL = box(pos = (-l/2.0,0,0), size=(w,l,l), color=color.white, opacity=0.25)
wallU = box(pos = (0,l/2.0,0), size=(l,w,l), color=color.white, opacity=0.25)
wallD = box(pos = (0,-l/2.0,0), size=(l,w,l), color=color.white, opacity=0.25)
wallF = box(pos = (0,0,l/2.0), size=(l,l,w), color=color.white, opacity=0.25)
wallB = box(pos = (0,0,-l/2.0), size=(l,l,w), color=color.white, opacity=0.25)
#defining a function that creates a list of 'num_spheres' randomly positioned spheres
def create_spheres(num):
global l, radius
particles = [] # Create an empty list
for i in range(0,num): # Loop i from 0 to num-1
v = np.random.rand(3)
particles.append(sphere(pos= (3.0/4.0*l) * (v - 0.5), #pos such that spheres are inside box
radius = radius, color=color.red, index=i))
# each sphere is given an index for ease of referral later
return particles
#defining a global variable = the array of velocities for the spheres
velarray = []
#defining a function that gives each sphere a random velocity
def velocity_spheres(sphere_list):
global velarray
for sphere in spheres:
#making the sign of each velocity component random
rand = random.randint(0,1)
if rand == 1:
sign = 1
else:
sign = -1
mu = 10 #defining an average for normal distribution
sigma = 0.1 #defining standard deviation of normal distribution
# 3 random numbers form the velocity vector
vel = vector(sign*random.normalvariate(mu, sigma),sign*random.normalvariate(mu, sigma),
sign*random.normalvariate(mu, sigma))
velarray.append(vel)
spheres = create_spheres(num_spheres) #creating some spheres
velocity_spheres(spheres) # invoking the velocity function
while True:
rate(fps)
for sphere in spheres:
sphere.pos += velarray[sphere.index]*dt
#incrementing sphere position by reference to its own velocity vector
if abs(sphere.pos.x) > (l/2.0)-w-radius:
(velarray[sphere.index])[0] = -(velarray[sphere.index])[0]
#reversing x-velocity on contact with a side wall
elif abs(sphere.pos.y) > (l/2.0)-w-radius:
(velarray[sphere.index])[1] = -(velarray[sphere.index])[1]
#reversing y-velocity on contact with a side wall
elif abs(sphere.pos.z) > (l/2.0)-w-radius:
(velarray[sphere.index])[2] = -(velarray[sphere.index])[2]
#reversing z-velocity on contact with a side wall
for sphere2 in spheres: #checking other spheres
if sphere2 != sphere:
#making sure we aren't checking the sphere against itself
if abs(sphere2.pos-sphere.pos) < (sphere.radius+sphere2.radius):
#if the other spheres are touching the sphere we are looking at
v1 = velarray[sphere.index]
#noting the velocity of the first sphere before the collision
velarray[sphere.index] = velarray[sphere2.index]
#giving the first sphere the velocity of the second before the collision
velarray[sphere2.index] = v1
#giving the second sphere the velocity of the first before the collision
再次感谢您的帮助!
答案 0 :(得分:1)
原始问题中给出的代码中while循环中的elif语句是导致问题的原因。条件语句elif仅在原始if条件不满足时适用。球体与盒子的角部相遇的情况满足至少两个用于反转速度分量的条件。这意味着,虽然人们期望(至少)两个速度分量被反转,但只有一个是。也就是说,if语句指定的方向是相反的,而elif语句中提到的组件不是,因为第一个条件已经满足,因此忽略了elif语句。
如果将每个elif更改为单独的if语句,则代码按预期工作。