Geometry – How to Tell if a Line Segment Intersects with a Circle?

geometry

Given a line segment, denoted by it's $2$ endpoints $(X_1, Y_1)$ and $(X_2, Y_2)$, and a circle, denoted by it's center point $(X_c, Y_c)$ and a radius $R$, how can I tell if the line segment is a tangent of or runs through this circle? I don't need to be able to discern between tangent or running through a circle, I just need to be able to discern between the line segment making contact with the circle in any way and no contact. If the line segment enters but does not exit the circle (if the circle contains an endpoint), that meets my specs for it making contact.

In short, I need a function to find if any point of a line segment lies in or on a given circle.

EDIT:

My application is that I'm using the circle as a proximity around a point. I'm basically testing if one point is within R distance of any point in the line segment. And it must be a line segment, not a line.

Best Answer

Find the intersections of the line containing the segment and the circle. This amounts to solving a quadratic equation. If there are no intersections (i.e. the solutions of the corresponding equation are non-real), then your segment does not intersect the circle. Now, if there are intersections, see whether they are inside the segment or not.

To implement this, let $P$ and $Q$ be the endpoints of your segment and $C$ and $r$ be the center and the radius of your circle. Then every point of the line through $P$ and $Q$ is given by the formula $$t P + (1-t) Q$$ for exactly one value of $t\in\mathbb R$, and the points in the segment are precisely those for which the corresponding $t$ is in the interval $[0,1]$.

Now the point corresponding to $t\in\mathbb R$ is on the circle if and only if $$\langle t P + (1-t) Q - C,t P + (1-t) Q - C\rangle = r^2,$$ where $\langle\mathord\cdot,\mathord\cdot\rangle$ is the usual inner (dot) product of vectors. If you solve this equation—this is easy, as it is a quadratic equation for $t$—, you find the $t$'s corresponding to the points of intersection of the circle and the line, and if at least one of those $t$'s belong to the interval $[0,1]$, then the segment intersects the circle.

Later: I tried to have Mathematica do the computation for me. Assuming $C=(0,0)$ and $r=1$, as we may up to translation and rescaling, and letting $P=(p1,p2)$, $Q=(q1,q2)$, the following computes the $t$'s:

P = {p1, p2};
Q = {q1, q2};
ts = t /. Solve[Norm[t P + (1 - t) Q]^2 == 1, t];

This ends up with the variable ts having the value

$$\left\{\frac{-p_1 q_1-p_2 q_2-\sqrt{p_1^2 \left(-q_2^2\right)-2 p_1 q_1+2 p_2 p_1 q_1 q_2-p_2^2 q_1^2-2 p_2 q_2+p_1^2+p_2^2+q_1^2+q_2^2}+q_1^2+q_2^2}{-2 p_1 q_1-2 p_2 q_2+p_1^2+p_2^2+q_1^2+q_2^2},\frac{-p_1 q_1-p_2 q_2+\sqrt{p_1^2 \left(-q_2^2\right)-2 p_1 q_1+2 p_2 p_1 q_1 q_2-p_2^2 q_1^2-2 p_2 q_2+p_1^2+p_2^2+q_1^2+q_2^2}+q_1^2+q_2^2}{-2 p_1 q_1-2 p_2 q_2+p_1^2+p_2^2+q_1^2+q_2^2}\right\}$$

(This was a huge formula, which will likely not fit on your browser window...) If the expression inside the square roots is negative, there are no real $t$'s, so the line (hence, a fortiori the segment) and the circle are disjoint. If not, now we need to see if at least one of the roots in in $[0,1]$.

If I now tell Mma to tell me when then first of the roots is in $[0,1]$, by telling her to compute

Reduce[0 <= ts[[1]] <= 1, Reals]

it works for a while, and comes up with a huge answer, presumably equivalent to the original

0 <= ts[[1]] <= 1

Can anyone make sense of the huge answer? (if one asks instead for the more meaningful

Reduce[0 <= ts[[1]] <= 1 || 0 <= ts[[2]] <= 1, t, Reals]

the same thing happens)

PS: Please notice that I have made absolutely no attempt at being fast or particularly smart with this idea: it is just the straightforward was to set up the problem and solve it.

Related Question