2009-12-07 4 views
1

У меня есть проблема с круг-круг столкновений detection.I используется следующий алгоритмкруг-круг проблема столкновения

func collision(id,other.id) 
{ 

var vaP1,vaP2,dis,va1,vb1,va2,vb2,vp1,vp2,dx,dy,dt; 


if (id!=other.id) 

    { 
     dx=other.x-x; 
     dy=other.y-y; 
     dis=sqrt(sqr(dx)+sqr(dy)); 

     if dis<=radius+other.radius 
     { 
      //normalize 
      dx/=dis; 
      dy/=dis; 

      //calculate the component of velocity in the direction 
      vp1=hspeed*dx+vspeed*dy; 
      vp2=other.hspeed*dx+other.vspeed*dy; 

      if (vp1-vp2)!=0 
      { 
       dt=(radius+other.radius-dis)/(vp1-vp2); 

       //move the balls back so they just touch 
       x-=hspeed*dt; 
       y-=vspeed*dt; 
       other.x-=other.hspeed*dt; 
       other.y-=other.vspeed*dt; 

       //projection of the velocities in these axes 
       va1=(hspeed*dx+vspeed*dy); 
       vb1=(vspeed*dx-hspeed*dy); 
       va2=(other.hspeed*dx+other.vspeed*dy); 
       vb2=(other.vspeed*dx-other.hspeed*dy); 

       //new velocities in these axes. take into account the mass of each ball. 
       vaP1=(va1+bounce*(va2-va1))/(1+mass/other.mass); 
       vaP2=(va2+other.bounce*(va1-va2))/(1+other.mass/mass); 

       hspeed=vaP1*dx-vb1*dy; 
       vspeed=vaP1*dy+vb1*dx; 
       other.hspeed=vaP2*dx-vb2*dy; 
       other.vspeed=vaP2*dy+vb2*dx; 

       //we moved the balls back in time, so we need to move them forward 
       x+=hspeed*dt; 
       y+=vspeed*dt; 
       other.x+=other.hspeed*dt; 
       other.y+=other.vspeed*dt; 
      } 
     } 
    } 

x=ball 1 x-position 

y=ball 1 y-position 

other.x= ball 2 x position 

other.y=ball 2 y position 

этот алгоритм работает хорошо, когда у меня есть шар изображение 40 х 40 пикселя и мяч центр (20,20) означает, что изображение состоит только из мяча. Но проблема возникает, когда размер изображения составляет 80 х 80. и положение шарового центра (60,60) означает, что мяч является нижним правым углом с радиусом 20. в этом случае есть возникает множественное столкновение, означает участок

x+=hspeed*dt; 

y+=vspeed*dt; 

other.x+=other.hspeed*dt; 

other.y+=other.vspeed*dt; 

Невозможно отделить мяч/скорость не меняется в зависимости от столкновения. Я изменил значение x, которое является центром изображения 40,40 - 60,60, центр шара добавляет 20. но результат тот же. Можно сказать, какая проблема. Я считаю, что алгоритм правильный, потому что он хорошо работает во всех остальных случаях, и многие люди использовали этот алгоритм. Проблема меняет положение от центра изображения до центра мяча. Какую поправку я должен сделать для этого? или любая идея. Если кто-то хочет помочь мне сообщить мне адрес электронной почты, чтобы я мог отправить свой полный проект.

+0

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

ответ

3

я не имел умственные способности, чтобы переварить весь ваш вопрос, но вот мои 2 цента о том, как решить вашу проблему

1) Самый простой способ обнаружения столкновения окружности с другой, чтобы проверить, если их расстояние меньше радиуса объединенных окружностей. (Я мог бы быть неправильно с математикой, так Поправьте меня, если я ошибаюсь)

Circle c1,c2; 
float distance = DISTANCE(c1.center,c2.center); 
if(distance < c1.radius + c2.radius) 
{ 
    // collision .. BOOOOOOM 
} 

2) Попробуйте использовать точные типы данных. Старайтесь не конвертировать поплавки в целые числа без проверки переполнения, нижних и десятичных точек. Еще лучше, просто используйте поплавки.

3) Напишите журнал и проследите через свои значения. Посмотрите, есть ли очевидные ошибки математики.

4) Разделите свой код на его простейшую часть. Попытайтесь удалить все вычисления скорости, чтобы получить самые простые движения, которые помогут вам отлаживать.

-1

Я не дам вам ответ, который вы ищете, и я не уверен, что кто-то еще это сделает. Объем кода, который должен быть расшифрован, чтобы получить ответ, не может гарантировать вознаграждение. То, что я бы рекомендовал, - это ослабить связь в вашем алгоритме. Функция выше делает слишком много работы.

В идеале у вас было бы обнаружение столкновения, которое было сосредоточено только на столкновении, а не на продвижении шаров. Что-то вроде функции, показанной ниже, и это позволит другим разработчикам легче помочь вам, если у вас все еще есть проблемы.

function(firstCircleCenterX, firstCircleCenterY, secondCircleCenterX, secondCircleCenterY, firstCircleRadius, secondCircleRadius) 
{ 
    ...this code should concentrate on logic to determine collision 
    ...use pythagoran theory to find distance between the two centers 
    ...if the distance between the two centers is less than ((2*firstCircleRadius)+(2*secondCircleRadius) then you have a collision 

    ...return true or false depending on collision 
} 
+1

... э-э, я думаю, вы имеете в виду (firstCircleRadius + secondCircleRadius) – Pedery

+0

Вот здесь. OP должен создавать отдельные функции 'collided' (или, возможно,' didCollide') и 'bounce'. – outis

+0

Ahh ... yes .. (firstCircleRadius + secondCircleRadius) – FernandoZ

Смежные вопросы