編輯:我現在修復了我問到的問題。球體離開盒子的角落,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
感謝您的幫助!
不會簡單地顛倒粒子的速度分量,也可以將它們放在盒子內 - 例如,簡單地將粒子的位置夾在盒子內(減小球體半徑的兩倍)。如果需要完全彈性反彈,則需要計算每個粒子和每個牆的每個碰撞點的所有碰撞點,進行第一次碰撞,將粒子移動到那裏,固定其速度,重新計算餘下步驟的碰撞等... – BeyelerStudios
我實際上已經意識到出了什麼問題,現在已經糾正了,不過謝謝 –
當然,對於不遵守協議的道歉! –