【发布时间】:2016-03-16 14:32:33
【问题描述】:
编辑:我现在已经解决了我询问的问题。球体将盒子留在角落里,if 语句(在下面显示的 while 循环中)被混淆了。在反转与墙壁接触时速度的各个分量的代码中,使用了一些 elif 语句。当使用 elif 时(据我所知),如果球体一次超过一个以上的位置限制,程序只会反转其中一个的速度分量。这在用简单的 if 替换 elif 时得到纠正。我不确定我是否完全理解这背后的原因,所以希望比我更聪明的人会评论这些信息,但现在,如果有人遇到同样的问题,我希望我有限的输入有所帮助!
先了解一下上下文:
我正在尝试在 VPython 中建立气体动力学理论模型,作为我(物理)学位的复习练习。这涉及到我构建一个空心盒子并将一堆球体放入其中,随机放置在整个盒子中。然后我需要为每个球体分配自己的随机速度,然后使用循环参考其速度矢量和时间步长调整每个球体的位置。
球体还应该与每面墙和所有其他球体发生弹性碰撞。
当球体在 x 方向遇到墙壁时,它的 x 速度分量会反转,并且在 y 和 z 方向上也是如此。 当一个球体遇到另一个球体时,它们会交换速度。
目前,我的代码可以创建正确数量的球体并随机分布它们,并为每个球体提供自己的随机速度。除了碰撞之外,球体也会按应有的方式移动。球体应该全部留在盒子内,因为它们应该从所有墙壁上反弹。它们似乎相互反弹,但偶尔会有一两个球体直接穿过盒子。
我对编程非常陌生,我不太了解这里发生了什么或为什么会发生,但如果有人能帮助我,我将不胜感激。
以下是我到目前为止的代码(我试图评论我在每个步骤中所做的事情):
##########################################################
# 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
再次感谢您的帮助!
【问题讨论】:
-
不要简单地反转粒子的速度分量,也要把它们放在盒子里——例如简单地夹住盒子里粒子的位置(减少两倍的球体半径) .如果你想要完全弹性反弹,你需要计算每个粒子和每一步墙的所有碰撞点,进行第一次碰撞,将粒子移动到那里,固定它的速度,重新计算剩余步骤的碰撞,等等...
-
我实际上意识到出了什么问题,现在已经纠正了,不过还是谢谢
-
当然,我很抱歉没有遵守协议!