Редактировать: Я исправил проблему, о которой я просил. Шары покидали ящик в углах, где утверждения if (в цикле while, показанные ниже) запутались. В битах кода, которые изменяют отдельные компоненты скорости при контакте со стенками, использовались некоторые утверждения elif. Когда elif используется (насколько я могу судить), если сфера превышает более одного предела позиции, программа только меняет компонент скорости для одного из них. Это исправляется при замене elif просто, если. Я не уверен, насколько я понимаю причину этого, поэтому, надеюсь, кто-то умнее, чем я буду комментировать такую информацию, но пока, если у кого-то такая же проблема, я надеюсь, что мой ограниченный ввод поможет!Kinetic Theory Model
Некоторые контекст первых:
Я пытаюсь построить модель кинетической теории газов в VPython, как пересмотр упражнения для моего (физика) степени. Это связано с тем, что я строил полый ящик и клал в него кучу шариков, случайно расположенных по всей коробке. Затем мне нужно назначить каждой из сфер своей собственной случайной скоростью, а затем использовать петлю для настройки положения каждой сферы по отношению к ее вектору скорости и временному шагу.
Сферы также должны испытывать упругие столкновения с каждой стеной и всеми другими сферами.
Когда сфера пересекает стену в направлении x, ее составляющая x-velocity изменяется и аналогично в направлениях 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
Еще раз спасибо за любую помощь!
не просто переверните компонент скорости частиц, поместите их также в коробку - например, просто закрепите положение частицы внутри коробки (уменьшенную вдвое радиус сферы). если вам нужны полные упругие отскоки, вам нужно будет вычислить все точки столкновения для каждой частицы и каждой стены за один шаг, совершить первое столкновение, перенести туда частицу, зафиксировать ее скорость, пересчитать столкновения для оставшейся части шага, ect ... – BeyelerStudios
Я действительно понял, что случилось, и теперь исправил его, спасибо, хотя –
Конечно, мои извинения за несоблюдение протокола! –