2016-04-08 8 views
0

Итак, я кодирую игру в снукер, и я решил, что лучший способ выяснить, как заставить шары столкнуться друг с другом, - это сделать это в отдельной программе, а затем скопировать ее. m довольно грамотный математик, поэтому я сел, провел мероприятие и прошел математику о том, что происходит на самом деле.Мячи сталкиваются - проблемы с vPython

Мой подход состоит в том, чтобы разбить начальную скорость каждого шара на xr- и yr-компоненты в системе отсчета, в которой xr-компонент находится в соответствии с вектором через центр каждого шара, а yr- компонент перпендикулярен этому. Затем я делаю простой переключатель xr-компонентов шаров и оставляю yr-компоненты такими, какие они есть, затем вычисляем, какие x- и y-компоненты скорости возвращаются в стандартную систему отсчета.

По какой-то причине, будь то математическая или программная ошибка, я не могу заставить ее работать. Следующее - это то, что у меня есть до сих пор, и я просмотрел практически каждую связанную страницу в Интернете, которую я мог найти, и все похожие вопросы, заданные на этом сайте. Я тоже не совсем хороший программист.

from visual import * 

dt = 0.01 
r = 5 

red = sphere(pos=(-25,25,0),radius = r,color=color.red) 
green = sphere(pos=(25,-25,0),radius = r,color=color.green) 


red.velocity = vector(10,-10,0) 
green.velocity = vector(-10,10,0) 


def posupdate(ball): 

     ball.pos = ball.pos + ball.velocity*dt 


def ballhit(ball1,ball2): 

     v1 = ball1.velocity 
     v1x = ball1.velocity.x 
     v1y = ball1.velocity.y 
     v2 = ball2.velocity 
     v2x = ball2.velocity.x 
     v2y = ball2.velocity.y 
     xaxis = vector(1,0,0) 

     btb = ball2.pos - ball1.pos 
     nbtb = btb/abs(btb) 

     if abs(btb) < 2*r: 
       phi = acos(dot(nbtb,xaxis)/abs(nbtb)*abs(xaxis)) 
       ang1 = acos(dot(v1,xaxis)/abs(v1)*abs(xaxis)) 
       ang2 = acos(dot(v2,xaxis)/abs(v2)*abs(xaxis)) 

       v1xr = abs(v1)*cos((ang1-phi)) 
       v1yr = abs(v1)*sin((ang1-phi)) 
       v2xr = abs(v2)*cos((ang2-phi)) 
       v2yr = abs(v2)*sin((ang2-phi)) 

       v1fxr = v2xr 
       v2fxr = v1xr 
       v1fyr = v1yr 
       v2fyr = v2yr 

       v1fx = cos(phi)*v1fxr+cos(phi+pi/2)*v1fyr 
       v1fy = sin(phi)*v1fxr+sin(phi+pi/2)*v1fyr 
       v2fx = cos(phi)*v2fxr+cos(phi+pi/2)*v2fyr 
       v2fy = sin(phi)*v2fxr+sin(phi+pi/2)*v2fyr 

       ball1.velocity.x = v1fx 
       ball1.velocity.y = v1fy 
       ball2.velocity.x = v2fx 
       ball2.velocity.y = v2fy 

     return ball1.velocity, ball2.velocity 


while 1==1: 

     rate(100) 

     posupdate(red) 
     posupdate(green) 
     ballhit(red,green) 

Заранее благодарим за любую помощь, которую вы можете дать.

Редактировать: обнаружение столкновения не является проблемой, просто вычисление векторов скорости шаров после столкновения. Извинения, я должен был сделать это яснее.

+0

Что не работает? – Carcigenicate

+0

Направление, на которое попадают шары, в большинстве случаев неверно. Есть немного, например движение только вдоль оси X, которые работают правильно, но в целом направление отталкивания просто неверно. – Cowmilker

ответ

0

Заканчивать Physics of Billiards:

Сохранение импульса применяется и, предполагая, что неупругие столкновения, кинетическая энергия сохраняется. Таким образом, вы получаете следующие векторные уравнения (индексы _0 и _1 показывают до и после столкновения):

m1*v1_0 + m2*v2_0 = M1*v1_1 + m2*v2_1 

0.5*m1*v1_0**2 + 0.5*m2*v2_0**2 = 0.5*m1*v1_1**2 + 0.5*m2*v2_1**2 

Обычно m1 == м2, так что они упрощаются:

v1_0 + v2_0 = v1_1 + v2_1 

v1_0**2 + v2_0**2 = v1_1**2 + v2_1**2 
+0

Проблема больше связана с углами, но в любом случае спасибо. Я проверил эту статью раньше, и это очень удобно, когда дело доходит до понимания того, что происходит при столкновении. Моя основная проблема заключается в создании кода. – Cowmilker