Sphere collision with Line (two vectors)

Started by
1 comment, last by Meshboy 16 years, 8 months ago
Sorry, this thread should be in Math and physics!?!?! Hi! my idéa was to build my collisions by using a sphere with a redius that check for collisions with line(s). I load up my entire level build as one Mesh. (my game is FPS-genre). My plan was then to fill a array with lines (two vectors) that was the bounderies for wall. bounderies for one wall would be the lines P1-P2 etc. This is the code i have for the function that calculate if my Sphere is in collison with a line. public Boolean CheckForIntersection(Vector3 p1, Vector3 p2, Vector3 sc, double r) { Vector3 dp; dp.X = p2.X - p1.X; dp.Y = p2.Y - p1.Y; dp.Z = p2.Z - p1.Z; a = dp.X * dp.X + dp.Y * dp.Y + dp.Z * dp.Z; b = 2 * (dp.X * (p1.X - sc.X) + dp.Y * (p1.Y - sc.Y) + dp.Z * (p1.Z - sc.Z)); c = sc.X * sc.X + sc.Y * sc.Y + sc.Z * sc.Z; c += p1.X * p1.X + p1.Y * p1.Y + p1.Z * p1.Z; c -= 2 * (sc.X * p1.X + sc.Y * p1.Y + sc.Z * p1.Z); c -= r * r; bb4ac = (b * b - 4 * a * c)/10000; if (bb4ac > 0) { return false; } else { return true; } } This seems to be working except that it always gives me a 0 eaven though i am not in between these two points. This means that the lines would cut through my entire level and set too large bounderies. Right now my goal of good collision with sliding walls seems very very very far away. I am not the best of linear algebra, but i need to know what techique i should use for this and then what kind of Math that is implemented so i can dig into these kinds of problems. Shoulden´t the code above just give the value 0 if the player is between these lines?
Advertisement
How come at the end of your quadratic equation you're dividing by 10000? This seems a bit arbitrary and will distort results.

Your code is close, but needs a bit of tweaking. First, with your quadratic equation, you want to be getting positive values, which will indicate a hit, so you'll need to flip your if statement around. Second, you need to test more than just the discriminant of the equation for a positive value; you still have a +/- (plus or minus) to deal with, along with a denominator of 2 * a.

In other words, should go something like this:
if(bb4ac >= 0){    double e = sqrt(bb4ac);    double denom = 2.0 * a;    if(((-b - e) / denom) > epsilon  ||  ((-b + e) / denom) > epsilon)    {        // successful collision    }}
Epsilon is a small value, something like 0.0001, which is a rough hack to weed out some of the "almost zero" results that we don't want. The reason for this is that it's possible for a line to strike a sphere only once (tangentially), and these are difficult to handle so we just ignore them.

To be a bit more informative, here's the low-down of what's going on with this whole deal... Quadratic equations, as you should know, can have either zero, one, or two real roots. In our sphere collision equation, these roots indicate the points in time in which the sphere's shell is struck. Typically a sphere is hit twice by a line--once when the line penetrates the sphere, and again when the line exits the sphere on the opposite end. As mentioned, its possible for a sphere to be struck only once if that line just barely skims the surface (these are the results that are zero or close to it). Zero roots or negative ones are either a miss or a result that we don't have to concern ourselves with because where the line is hitting is either behind the viewer or unknown.

But, some of this may sound a bit complicated. Sorry. Trying to explain as best I can. This link will help to alleviate any possible confusion: http://en.wikipedia.org/wiki/Quadratic_equation#Quadratic_formula

Post if you have more questions/problems.
Thanks you for all your help, i think i will be able to make the collision work. But the thing i also want in my game and that seems very hard to learn and has complex math is wall sliding. i don´t know if im even gona try implement that in my project. i will clear my code up by using your code, why i skipped the last snippets is just because i didn´t understand it from the example i got it from, with your example its much more clearer!

thanks

This topic is closed to new replies.

Advertisement