2016-03-16 88 views
1

編輯:我現在修復了我問到的問題。球體離開盒子的角落,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 

感謝您的幫助!

+0

不會簡單地顛倒粒子的速度分量,也可以將它們放在盒子內 - 例如,簡單地將粒子的位置夾在盒子內(減小球體半徑的兩倍)。如果需要完全彈性反彈,則需要計算每個粒子和每個牆的每個碰撞點的所有碰撞點,進行第一次碰撞,將粒子移動到那裏,固定其速度,重新計算餘下步驟的碰撞等... – BeyelerStudios

+0

我實際上已經意識到出了什麼問題,現在已經糾正了,不過謝謝 –

+0

當然,對於不遵守協議的道歉! –

回答

1

原始問題中給出的代碼中的while循環中的elif語句是問題的原因。條件語句elif只適用於原始if條件不滿足的情況。其中球體遇到盒子的角部的情況滿足用於反轉速度分量的至少兩個條件。這意味着,儘管人們期望(至少)兩個速度分量被顛倒,但只有一個是。也就是說,由if語句指定的方向是相反的,而elif語句中提到的組件不是,因爲第一個條件已經被滿足,因此elif語句被忽略。

如果每個elif更改爲單獨的if語句,則該代碼按預期工作。