I've tried many techniques to find line intersections. Most of my early attempts started out with finding the slope and doing a lot of calculations (like you're doing), but it was always messy and complicated.
The big problem with slope is that vertical lines have undefined slope, which means you have to throw in all sorts of special cases to work with vertical lines. I always had to write 2x the code (one for vertical and one for non-vertical), and it was a big headache.
Not to mention the math is quite complicated. I mean just look at your equation there in Kyon's post. That's nuts.
I've since abandoned slope calculations in favor of basic linear algebra, which I admittedly don't fully understand, but I know more or less how to use it.
Here's a simple line intersection function I'm currently using in my game:
1 2 3
|
// support functions
inline double Dot(const Point& a,const Point& b) { return (a.x*b.x) + (a.y*b.y); }
inline double PerpDot(const Point& a,const Point& b) { return (a.y*b.x) - (a.x*b.y); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
bool LineCollision( const Point& A1, const Point& A2,
const Point& B1, const Point& B2,
double* out )
{
Point a(A2-A1);
Point b(B2-B1);
double f = PerpDot(a,b);
if(!f) // lines are parallel
return false;
Point c(B2-A2);
double aa = PerpDot(a,c);
double bb = PerpDot(b,c);
if(f < 0)
{
if(aa > 0) return false;
if(bb > 0) return false;
if(aa < f) return false;
if(bb < f) return false;
}
else
{
if(aa < 0) return false;
if(bb < 0) return false;
if(aa > f) return false;
if(bb > f) return false;
}
if(out)
*out = 1.0 - (aa / f);
return true;
}
|
A2-A1 is a line segment, as is B2-B1. out (if provided) is how far along line B you can move before the intersection (scaled between [0..1]). This was more useful than the exact intersect point for my purposes (seeing how far something can move before it hits a wall, for example).
If you need the intersect point, you can change it like so:
1 2 3 4 5 6 7 8 9 10
|
bool LineCollision( const Point& A1, const Point& A2,
const Point& B1, const Point& B2,
Point* out )
{
//...
if(out)
*out = (b * (1.0 - (aa / f))) + B1; // this could probably be simplified -- but I'm lazy
return true;
}
|
This code will work to find intersection between any two line segments of any angle and length. As you can see the code is actually pretty short and simple, and it's surprisingly fast.
I've had much better luck with this than with any method that involved calculating slope. What's more, when you get more familiar with other linear algebra concepts, the slope becomes less and less useful.
EDIT:
Oh wait, I just read that this was for some graphing program and not for a C++ program. Har. Oh well. XD