Title: Determine where a line intersects a circle in C#
The FindLineCircleIntersections method shown shortly finds the points where line intersects a circle. It takes as parameters a circle's center point and radius, and two points on the line. It uses out parameters to return the coordinates of the points of intersection. The method returns the number of points of intersection (0, 1, or 2).
To find the points of intersection, the code considers the line as generated by the equations:
X(t) = x1 + (x2 - x1) * t
Y(t) = y1 + (y2 - y1) * t
Where t ranges from 0 to 1 to generate the points on the line segment.
The code plugs those two equations into the following equation for a circle:
(X - Cx)2 + (Y - Cy)2 = radius2
It then solves for t by using the quadratic formula. The result is 0, 1, or 2 real values for t depending on whether the line cuts through the circle, touches it tangentially, or misses it entirely. The method plugs those values back into the equations for the line to get the points of intersection.
Here's the FindLineCircleIntersections method.
// Find the points of intersection.
private int FindLineCircleIntersections(
float cx, float cy, float radius,
PointF point1, PointF point2,
out PointF intersection1, out PointF intersection2)
{
float dx, dy, A, B, C, det, t;
dx = point2.X - point1.X;
dy = point2.Y - point1.Y;
A = dx * dx + dy * dy;
B = 2 * (dx * (point1.X - cx) + dy * (point1.Y - cy));
C = (point1.X - cx) * (point1.X - cx) +
(point1.Y - cy) * (point1.Y - cy) -
radius * radius;
det = B * B - 4 * A * C;
if ((A <= 0.0000001) || (det < 0))
{
// No real solutions.
intersection1 = new PointF(float.NaN, float.NaN);
intersection2 = new PointF(float.NaN, float.NaN);
return 0;
}
else if (det == 0)
{
// One solution.
t = -B / (2 * A);
intersection1 =
new PointF(point1.X + t * dx, point1.Y + t * dy);
intersection2 = new PointF(float.NaN, float.NaN);
return 1;
}
else
{
// Two solutions.
t = (float)((-B + Math.Sqrt(det)) / (2 * A));
intersection1 =
new PointF(point1.X + t * dx, point1.Y + t * dy);
t = (float)((-B - Math.Sqrt(det)) / (2 * A));
intersection2 =
new PointF(point1.X + t * dx, point1.Y + t * dy);
return 2;
}
}
Click and drag to draw the line segment. The main program uses the FindLineCircleIntersections method to find the points of intersection (if any). It then draws the segment you selected and the points of intersection. If the points don't lie on the segment, it extends the segment through the points with a dashed line.
Download the example to experiment with it and to see additional details.
|