Check if line intersects with circles perimeter

You can find the shortest distance from a point to a line using the formula $$\operatorname{distance}(ax+by+c=0, (x_0, y_0)) = \frac{|ax_0+by_0+c|}{\sqrt{a^2+b^2}}. $$ Put $(x_0,y_0)$ = center of circle. If this distance is smaller (or equal) than radius of circle, then your line and circle intersects.

Since you know start point $(x_1,y_1) $ and end point $(x_2, y_2) $, you can get the equation of line using formula $$y - y_1 = \frac{y_2 - y_1}{x_2 - x_1}(x-x_1)$$ Simplifying, we get $$ (x_2 - x_1) y + (y_1 - y_2)x +(x_1-x_2)y_1 + x_1(y_2-y_1) = 0$$ It would be nice to store $a = y_1 - y_2, b = x_2 - x_1, c = (x_1-x_2)y_1 + x_1(y_2-y_1)$

It would be something like

return (Math.abs((l2.lat() - l1.lat())*c.lng() +  c.lat()*(l1.lng() -     
       l2.lng()) + (l1.lat() - l2.lat())*l1.lng() +
       (l1.lng() - l2.lng())*l1.lat())/ Math.sqrt((l2.lat() - l1.lat())^2 +
       (l1.lng() - l2.lng())^2) <= r)

something like $$ \frac{\left | (x_2 - x_1)x_0 + (y_1 - y_2)y_0 + (x_1-x_2)y_1 + x_1(y_2-y_1) \right |}{\sqrt{(x_2 - x_1)^2 + (y_1 - y_2)^2}} \le r$$


Let $A = (A_x,A_y)$ and $B = (B_x,B_y)$ be the end points of a line segment. Then all points of the line are $A + t (B-A)$ for $0 < t < 1$.

Let $C = (C_x,C_y)$ be the center of the circle and $R$ its radius. Then all points of the circle are $(x,y)$ such that $(x-C_x)^2 + (y-C_y)^2 = R^2$ by Pythagoras theorem.

By moving everything we can have $C = (0,0)$, this makes calculations a bit simpler. The equation of the circle becomes $x^2 + y^2 = R^2$.

As for number of points of intersection: there will be either 0 - no intersection, 1 - it is a tangent line or 2 - it goes right through the circle.

The points of intersection must satisfy both equations simultaneous. $(x,y)$ is a point of intersection if $x^2 + y^2 = R^2$ and $(x,y) = A + t (B-A)$ for some $0 < t < 1$.

We can split $(x,y) = A + t (B-A)$ into components:

  • $x = A_x + t (B_x - A_x)$
  • $y = A_y + t (B_y - A_y)$

and put this into the circle equation

$$(A_x + t (B_x - A_x))^2 + (A_y + t (B_y - A_y))^2 = R^2$$

multiply it out

$$[A_x^2 + A_y^2 - R^2] + 2 [A_x (B_x - A_x) + A_y (B_y - A_y)] t + [(B_x - A_x)^2 + (B_y - A_y)^2] t^2 = 0$$

this is a simple quadratic equation, you can use the discriminant ("$b^2 - 4ac > 0$") to check if there are two real values of $t$, then you must check if they are between 0 and 1.

// parameters: ax ay bx by cx cy r
ax -= cx;
ay -= cy;
bx -= cx;
by -= cy;
a = (bx - ax)^2 + (by - ay)^2;
b = 2*(ax*(bx - ax) + ay*(by - ay));
c = ax^2 + ay^2 - r^2;
disc = b^2 - 4*a*c;
if(disc <= 0) return false;
sqrtdisc = sqrt(disc);
t1 = (-b + sqrtdisc)/(2*a);
t2 = (-b - sqrtdisc)/(2*a);
if((0 < t1 && t1 < 1) || (0 < t2 && t2 < 1)) return true;
return false;

Here is a simpler calculation that avoids squareroots, based on this:

x1 -= cx
x2 -= cx
y1 -= cy
y2 -= cy
dx = x2 - x1
dy = y2 - y1
dr_squared = dx**2 + dy**2
D = x1*y2 - x2*y1
return cr**2 * dr_squared > D**2