PDA

View Full Version : Moving Circle vs Moving Circle



TOdorus
June 3rd, 2009, 04:58 PM
I've been working on a tile-engine lately and I've hit a bit of a snag when doing object to object collision. My moving objects are defined as cylinders, but I'm having trouble with the two dimensional circle part of it, so consider this a circle to circle problem. I can calculate the exact time and point of the collision, that's not the problem, but currently the physics in my engine are, that an object can move in a dimension if it isn't blocked in that dimension. That means that if I would diagonally jump into a horizontal wall, only the y-dimension would be blocked, so I stop moving in the y dimension, but keep moving in the x and z dimensions. If that doesn't make sense, try the link to the current build at the end of this post.

This is the current code I'm using.


private function movingObjektBlock(Red:RigidBody, Blue:RigidBody, LINE:Line):Number {
var RR:Number = Red.radius+Blue.radius;
var dX:Number = Red.x-Blue.x;
var dY:Number = Red.y-Blue.y;
//
var Vx:Number = Red.Vl.x-Blue.Vl.x;
var Vy:Number = Red.Vl.y-Blue.Vl.y;
//
//
var a = Vx*Vx+Vy*Vy;
var b = 2*dX*Vx+2*dY*Vy;
var c = dX*dX+dY*dY-(RR*RR);
//
var Ta = (-b+Math.sqrt(b*b-(4*a*c)))/(2*a);
var Tb = (-b-Math.sqrt(b*b-(4*a*c)))/(2*a);
//
var T1:Number
var T2:Number
if (Ta<Tb) {
T1 = Ta
T2 = Tb
} else {
T1 = Tb
T2 = Ta
}
//
var z1:Number = LINE.getZforT(T1)
var z2:Number = LINE.getZforT(T2)
var T:Number = -1
if ((z1 > Blue.z && z1 < Blue.z + Blue.height) || (z1 + Red.height > Blue.z && z1 + Red.height < Blue.z + Blue.height) || (z1 < Blue.z && z1 + Red.height > Blue.z + Blue.height)) {
//Collision
T = T1
} else if ((z2 > Blue.z && z2 < Blue.z + Blue.height) || (z2 + Red.height > Blue.z && z2 + Red.height < Blue.z + Blue.height) || (z2 < Blue.z && z2 + Red.height > Blue.z + Blue.height)) {
//Collision
T = T2
}
//
//
if (T>0 && T<1) {
return (T);
} else {
return (-1);
}
}


The problem with just one time is, that I wouldn't know the time for the individual dimensions. What I was thinking of, is moving the circles to the state of collision. Draw a line from centre to centre and get the left and right normal of that line. This would be the virtual dimension that the other circle isn't blocking. If I project the remaining movement vector on that line, would that be the solution to my problem?

I'm a bit fried at the moment so any other suggestions are welcome.


CURRENT BUILD (http://home.planet.nl/~bogaa096/Marshmellow/TileTest.html)

Arrows to move, space to jump
c = fire
x = incendary grenade
z = frag grenade

TOdorus
June 6th, 2009, 07:44 PM
Finally got round to testing my logic. If anyone's interested it's called sliding (http://www.peroxide.dk/download/tutorials/tut10/pxdtut10.html). Now to test the slide against tiles again and I'm done with collision detection & response and on to the good stuff.

SparK_BR
June 6th, 2009, 08:01 PM
the updated tutorial http://www.peroxide.dk/papers/collision/collision.pdf

about your game:
i killed everything, including myself but i couldn't kill that tree in the middle...
is there a impact grenade? that would kill that tree rightaway!

about the circle on circle collision:
your hitTest must be a custom function that instead of checking hitBoxes would check the distance betwen the circles and return true if the distance is smaller than one's width/2 + other's width/2

if your checking collision betwen the same group of objects(2 for loops to the same array)
one for goes up, the other one goes down to the index of the first for, that way collisions will be checked only once betwen them.

i know i don't know much but that's what i have to share :2c:

TOdorus
June 7th, 2009, 09:00 AM
about your game:
i killed everything, including myself but i couldn't kill that tree in the middle...
is there a impact grenade? that would kill that tree rightaway!

I thought I would be the only one to try that. :D Yeah there will probably be a grenade launcher which uses impact grenades and a rpg launcher.



about the circle on circle collision:
your hitTest must be a custom function that instead of checking hitBoxes would check the distance betwen the circles and return true if the distance is smaller than one's width/2 + other's width/2
The code in my first code actually gives the exact time of the collision. My question was more on collision resolvement, which is solved by sliding.



if your checking collision betwen the same group of objects(2 for loops to the same array)
one for goes up, the other one goes down to the index of the first for, that way collisions will be checked only once betwen them.


I never thought of that one. Thanks, that's a nice trick that can come in handy with a lot of algorithms. To really have accurate collision I should make the collision function recursive (in the case the collision resolvement forces the object into a new collision), but I'm gonna opt for speed and hope that situation won't occur that much.