Difference between distance based collision and bounding box collision

Started by
13 comments, last by rXpSwiss 12 years, 8 months ago
You usually select the type of bounding primitive based on the object you want to represent. Spheres, Cylinders, Boxes, etc, all have specific cases where they work better. There is usually no one-solution-for-all approach.

As Molle85 said, distance is usually used for elimination of candidates for collision detection.
Advertisement
unledqrg.png


Here's an example where it's pretty clear when to use what.
Hope you appreciate my awesome cloud painting skills :P

unledqrg.png


Here's an example where it's pretty clear when to use what.
Hope you appreciate my awesome cloud painting skills :P





Microsoft should have hired you for their bootscreen graphic. just throw a RGBY microsoft windows swazi on there.


In my 3D projects I typically use spherical (distance) and cylindrical volumes for everything. In Molle's example the bounding circle/sphere is set on the outer-most point of whatever object it represents the collision volume of, in my experience I try to find a happy medium because there are no simple shapes that accurately depict the collision area of any of the objects I typically use in my projects. So instead I will use a bounding sphere that is actually smaller than the model so there aren't large areas where collision will be occuring without the model actually touching anything, or sometimes combinations of bounding volumes for different collision checks. This also can result in the farther portions of the model going through stuff to a degree, but like I said it's a happy medium.

Most especially I use distance checking because you can avoid its slowness by NOT doing the square root and simply squaring the other side of the equation..


As for bounding boxes, do you really think they are really any more accurate ? They are actually slower than a distance check because the CPU is making two variable comparisons, provided that you optimize your distance check to not use the squareroot.

So for example:



//here's your typical pythagorean distance check

objectA.position = [1, 2];
objectA.radius = 5;
objectB.position = [12, 4];
objectB.radius = 6;

radiisum = objectA.radius + objectB.radius;
delta = | objectA.position - objectB.position |;

//pythag
distance = sqrt(delta.x * delta.x + delta.y * delta.y);


if(distance < radiisum)
colliding();



but to eliminate the slowness of square root calls (in projects where I have many objects that I am comparing for collisions with) I would do this:



//square-rootless distance check

objectA.position = [1, 2];
objectA.radius = 5;
objectB.position = [12, 4];
objectB.radius = 6;

radiisum = objectA.radius + objectB.radius;
delta = | objectA.position - objectB.position |;

//pythag without the sqrt
distancesqr = delta.x * delta.x + delta.y * delta.y;

radiisumsqr = radiisum * radiisum ;

if(distancesqr < radiisumsqr)
colliding();



The end result is the same and I did it without a square root call!

If you wanted to get fancy, use a distance check like this between your sprites to see if they could potentially be colliding, then do a per-pixel collision check ;) then you'd be uberleet gamedev guy.
Thank you for all your answers but a little followup question : What if you have to check a 2D collision between the arrow and the cloud... what do you use ?
Hi again,

I put a little method together to be able to check the collision between a rectangle and a round object...
Sure it needs resources but could be useful right ?

unledtzt.png

<div></div><div>bool Physics::IsCollidingRectRound(MySprite *rect, MySprite *round)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//exp</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float exp = 2;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//rectangle&nbsp;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>STRUCT_Location location = rect-&gt;getLocation();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>STRUCT_Size size = rect-&gt;getSize();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float scaling = rect-&gt;getScaling();</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//round</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float radius2 = 0;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>STRUCT_Location location2 = round-&gt;getLocation();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float scaling2 = round-&gt;getScaling();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>STRUCT_Size size2 = round-&gt;getSize();</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the radius</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if(size2.height &gt; size2.width)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>radius2 = (size2.height * scaling2) / 2;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>else</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>radius2 = (size2.width * scaling2) / 2;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the x distance between the 2 center points</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float x = (location.x + size.width/2) - (location2.x + size2.width/2);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if (x &lt; 0)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>x = x * -1;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the y distance between the 2 center points</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float y = (location.y + size.height/2) - (location2.y + size2.height/2);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if(y&lt;0)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>y = y * -1;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the angle</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float angle = atan(y/x) * 180 / PI;</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the radius of the rect object</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float rectRadius = (size.width/2)/cos(angle*PI/180);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the biggest radius possible</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float biggestRadiusPossible = pow(size.width/2,exp) + pow(size.height/2,exp);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//if the wrong angle is used</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if(rectRadius &lt; 0 || pow(rectRadius,exp) &gt; biggestRadiusPossible)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>{</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the radius of the rect object</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>rectRadius = (size.height/2)/sin(angle*PI/180);</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>}</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//get the hypotenus^2</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float hyp = pow(y,exp) + pow(x,exp);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>//add the 2 radius</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>float radiusAdd = pow(rectRadius, exp) + pow(radius2, exp);</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"> </span>if(radiusAdd &lt; hyp)</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>return false;</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>else return true;</div><div>}<br></div>

This topic is closed to new replies.

Advertisement