15. Line-circle intersection

Suppose the line is defined by the following parametric equations:

Here, p0 = (p0x, p0y) is a point on the line and <vx, vy> is a vector pointing in the line's direction. If the second point on the line is p1 = (p1x, p1y), then you can use <p1x – p0x, p1y – p0x> as the vector.

If the circle is centered at point (cx, cy) and has the radius r, then the following equation defines the circle:

If we plug the line's parametric equations into the circle's equation, we get the following equation:

If you multiply this out and group the terms containing t, you get the following rather untidy result:

This may look messy, but remember that all of the values vx, vy, p0, cx, cy, and r are part of the problem statement so we know their values. That means this equation simplifies to the following quadratic:

Here the following is true:

Now we can use the quadratic formula to solve for t:

The value inside the square root is called the equation's discriminant because it discriminates among different possible solutions. If the discriminant has a positive, zero, or negative value, the equation has two, one, or zero real solutions respectively. Those correspond to the line cutting through the circle, touching the circle tangentially, or missing the circle entirely.

The following code shows the FindLineCircleIntersections method, which finds the points of intersection between a line and a circle:

// Find the point of intersection between a circle defined by
// points p0, p1, p2 and the line define by points l0, l1.
private List<PointF> FindLineCircleIntersections(
PointF c0, PointF c1, PointF c2,
PointF p0, PointF p1)
{
// Make a list to hold the points of intersection.
List<PointF> results = new List<PointF>();

// Find the circle.
RectangleF circleRect = FindCircle(c0, c1, c2);

// If the points don't define a circle, return the empty results
// list.
if (circleRect.Width < 0) return results;

// Get the circle's center and radius.
float radius = circleRect.Width / 2;
PointF c = new PointF(
circleRect.X + radius,
circleRect.Y + radius);

// Find the intersection.
float vx = p1.X - p0.X;
float vy = p1.Y - p0.Y;
float A = vx * vx + vy * vy;
float B = 2 * (vx * (p0.X - c.X) + vy * (p0.Y - c.Y));
float C =
(p0.X - c.X) * (p0.X - c.X) +
(p0.Y - c.Y) * (p0.Y - c.Y) -
radius * radius;

float discriminant = B * B - 4 * A * C;
if (discriminant < 0)
{
Console.WriteLine("No real solutions");
return results;
}

if (Math.Abs(discriminant) < 0.0001)
{
Console.WriteLine("One solution");
float t = -B / (2 * A);
results.Add(new PointF(
p0.X + t * vx,
p0.Y + t * vy));
}
else
{
Console.WriteLine("Two solutions");
float root = (float)Math.Sqrt(discriminant);

float t0 = (-B + root) / (2 * A);
results.Add(new PointF(
p0.X + t0 * vx,
p0.Y + t0 * vy));

float t1 = (-B - root) / (2 * A);
results.Add(new PointF(
p0.X + t1 * vx,
p0.Y + t1 * vy));
}

return results;
}

The method starts by creating a results list to hold any intersections that it finds. It then calls the FindCircle method used by the preceding solution to find the circle that the user selected. If the user's points don't define a circle because they are colinear, the method returns the empty results list.

If the FindCircle method did find a circle, the code uses its results to find the circle's radius and center.

Next, the method finds the <vx, vy> vector pointing from the line's first point to its second. The method uses the values that it has to calculate A, B, and C for use in the quadratic formula.

The code then calculates and checks the quadratic formula's discriminant to see whether we have zero, one, or two solutions. The code calculates the appropriate number of solutions and adds them to the results list. The method finishes by returning that list.

The rest of the example solution uses methods defined by previous solutions to perform other tasks, such as finding the circle that the user selected. Download the LineCircleIntersection 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.129.20.133