2016-03-16 12 views
1

Редактировать: Я исправил проблему, о которой я просил. Шары покидали ящик в углах, где утверждения 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 

Еще раз спасибо за любую помощь!

+0

не просто переверните компонент скорости частиц, поместите их также в коробку - например, просто закрепите положение частицы внутри коробки (уменьшенную вдвое радиус сферы). если вам нужны полные упругие отскоки, вам нужно будет вычислить все точки столкновения для каждой частицы и каждой стены за один шаг, совершить первое столкновение, перенести туда частицу, зафиксировать ее скорость, пересчитать столкновения для оставшейся части шага, ect ... – BeyelerStudios

+0

Я действительно понял, что случилось, и теперь исправил его, спасибо, хотя –

+0

Конечно, мои извинения за несоблюдение протокола! –

ответ

1

Утверждения elif в цикле while в коде, указанном в исходном вопросе, являются/являются причиной проблемы. Условное выражение elif применимо только в том случае, если исходное условие if не выполняется. Тот факт, что сфера соответствует углу коробки, удовлетворяет по меньшей мере двум из условий для изменения компонентов скорости. Это означает, что, хотя можно было бы ожидать (по крайней мере) двух компонентов скорости, чтобы обратить вспять, только один из них. То есть направление, указанное выражением if, отменяется, тогда как компонент (ы), упомянутый в заявлении (-ях) elif, не является, поскольку первое условие выполнено, и, следовательно, утверждения elif игнорируются.

Если каждый elif изменен как отдельный оператор if, код работает по назначению.