I have a circle with origin at (cx, cy). Radius is r. Then, there is a line segment defined by two points: (x1,y1) and (x2,y2). How to determine if the line segment (not the extended line) is tangent to the circle? And if yes, where do the two touch?
What I am doing now: find out the distance of the point (cx, cy) from the extended line. If the distance != r, then certainly the line segment is NOT tangent to circle. Even if the distance == r, then we need to find out the point where they touch. Then check whether that point lies on the segment between (x1,y1) and (x2,y2). If yes, the line segment IS tangent to the circle - and the touch point is computed already. This works but involves too much math. And all with float or double variables. Isn't there a smarter, faster algorithm to achieve same result?
Thanks and regards, Pramod
I recommend you stop reasoning with slopes because the singularity at the vertical is always nasty to deal with. Try instead the parametric form:
p = p1 + t v where v = p2 - p1
Now project the vector p1 - c
onto v
, take the derivative wrt t
, set to zero, and you quickly have an expression for the value of t
that describes the point on the infinite line closest to c
, which is the tangent point:
(c - p1) dot v
t = --------------
v dot v
If this value is between 0 and 1, then the tangent point is between p1
and p2
. This is a pretty cheap computation. When it's true, you can follow up with a radius check
(c - p1 - tv) dot (c - p1 - tv) ~= r^2 ?
Note the sub-term c - p1
is already calculated above.
You mentioned only the circle is moving, so you can compute v dot v
once and save it.