10. Line-line intersection

There are several ways you can approach this problem. One approach that doesn't work well is to use slope-intercept equations of the form y = m × x + b for the lines. The problem with that approach is that it doesn't work for vertical lines. If a line is vertical, then the equation's slope, m, is effectively infinite.

The approach that I use defines a line by giving a point p0 on the line and a vector v that points in the direction of the line. Then the following equation defines the points on the line:

Here, t is any real number. For example, if t = 0, then the point is p0.

This is a parametric equation. In a parametric equation, a parameter generates a set of points. In this example, the parameter t generates the points on a line.

If v is the vector between two points, p0 and p1, then you can use this equation to generate the points along the line segment between those points by setting t to values between 0 and 1.

Note that the preceding vector equation really represents two equations involving X and Y coordinates. If v = <vx, vy>, then the vector equation really represents the following two equations:

Now, assume you have two line segments, one defined by points p00 and p01 and the other defined by points p10 and p11, so their parametric equations are the following:

When the two lines intersect, their parametric equations give the same point. Setting the two equations equal to each other and considering the equations' x and y components gives us the following two equations with two unknowns t0 and t1:

You can rearrange these to get the following:

Now, multiply the first equation by v1y and the second equation by –v1x to get the following:

If you add these two equations, the t1 terms cancel leaving the following:

Grouping the t0 terms gives the following equation:

Now, you can solve for t0:

You can solve for t1 similarly:

If the denominator is zero, then you cannot calculate t1 and t2 because you would need to divide by zero. In that case, the two lines are parallel so they never intersect.

In practice, you don't need to specifically check to see if the denominator is zero. Instead, you can calculate t0 and use float.IsInfinity to see if the result is undefined.

The LineLineIntesection example solution uses the following method to determine where two lines intersect:

// Find the point of intersection between lines p00-p01 and p10-p11.
private PointF IntersectLines(PointF p00, PointF p01, PointF p10,
PointF p11)
{
// Get the segments' parameters.
float v0x = p01.X - p00.X;
float v0y = p01.Y - p00.Y;
float v1x = p11.X - p10.X;
float v1y = p11.Y - p10.Y;

// Solve for t0 and t1.
float denominator = v0y * v1x - v0x * v1y;

float t0 = (v1y * (p00.X - p10.X) - v1x * (p00.Y - p10.Y))
/ denominator;
if (float.IsInfinity(t0))
throw new Exception("The lines are parallel");

PointF p0 = new PointF(
p00.X + t0 * v0x,
p00.Y + t0 * v0y);

// Check.
float t1 = (v0y * (p10.X - p00.X) - v0x * (p10.Y - p00.Y))
/ -denominator;
PointF p1 = new PointF(
p10.X + t1 * v1x,
p10.Y + t1 * v1y);
Debug.Assert(Math.Abs(p0.X - p1.X) < 0.0001);
Debug.Assert(Math.Abs(p0.Y - p1.Y) < 0.0001);

return p0;
}

This method first calculates the X and Y components of the lines' direction vectors v0 and v1. It then solves for t0. Notice the check that uses the float.IsInfinity method to see if the denominator is zero.

The code then uses t0 to find the point of intersection. The method doesn't really need to calculate t1, but it does so anyway. It uses t1 to calculate the point of intersection again and verifies that the two calculations give the same point.

The method finishes by returning the point it calculated.

Download the LineLineIntersection example solution to see additional details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.235.23