What is most efficient way to find the intersection of a line and a circle in python?

I have a polygon consists of lots of points. I want to find the intersection of the polygon and a circle. Providing the circle center of [x0,y0] and radius of r0, I have wrote a rough function to simply solve the quadratic equation of the circle and a line. But what about the efficiency of find the intersection of every line segment of the polygon one by one? Is there more efficient way?

I know sympy already provide the feature to get the intersections of different geometry. But also what about the efficiency of external library like sympy compared to calculate it by my own function, if I want to deal with lots of polygons?

def LineIntersectCircle(p,lsp,lep):
# p is the circle parameter, lsp and lep is the two end of the line
  x0,y0,r0 = p
  x1,y1 = lsp
  x2,y2 = esp
  if x1 == x2:
    if abs(r0) >= abs(x1 - x0):
        p1 = x1, y0 - sqrt(r0**2 - (x1-x0)**2)
        p2 = x1, y0 + sqrt(r0**2 - (x1-x0)**2)
        inp = [p1,p2]
        # select the points lie on the line segment
        inp = [p for p in inp if p[1]>=min(y1,y2) and p[1]<=max(y1,y2)]
    else:
        inp = []
  else:
    k = (y1 - y2)/(x1 - x2)
    b0 = y1 - k*x1
    a = k**2 + 1
    b = 2*k*(b0 - y0) - 2*x0
    c = (b0 - y0)**2 + x0**2 - r0**2
    delta = b**2 - 4*a*c
    if delta >= 0:
        p1x = (-b - sqrt(delta))/(2*a)
        p2x = (-b + sqrt(delta))/(2*a)
        p1y = k*x1 + b0
        p2y = k*x2 + b0
        inp = [[p1x,p1y],[p2x,p2y]]
        # select the points lie on the line segment
        inp = [p for p in inp if p[0]>=min(x1,x2) and p[0]<=max(x1,x2)]
    else:
        inp = []
  return inp

geometry, I guess maybe your question is about how to in theory do this in the fastest manner. also seems to be python, but seems to have lots of quite complex math integrated into it. The other check: "whether the line is outside the circle" is already� Python counter and dictionary intersection example (Make a string using deletion and rearrangement) Python | Find common elements in three sorted arrays by dictionary intersection Python set operations (union, intersection, difference and symmetric difference)

Here's a solution that computes the intersection of a circle with either a line or a line segment defined by two (x, y) points:

def circle_line_segment_intersection(circle_center, circle_radius, pt1, pt2, full_line=True, tangent_tol=1e-9):
    """ Find the points at which a circle intersects a line-segment.  This can happen at 0, 1, or 2 points.

    :param circle_center: The (x, y) location of the circle center
    :param circle_radius: The radius of the circle
    :param pt1: The (x, y) location of the first point of the segment
    :param pt2: The (x, y) location of the second point of the segment
    :param full_line: True to find intersections along full line - not just in the segment.  False will just return intersections within the segment.
    :param tangent_tol: Numerical tolerance at which we decide the intersections are close enough to consider it a tangent
    :return Sequence[Tuple[float, float]]: A list of length 0, 1, or 2, where each element is a point at which the circle intercepts a line segment.

    Note: We follow: http://mathworld.wolfram.com/Circle-LineIntersection.html
    """

    (p1x, p1y), (p2x, p2y), (cx, cy) = pt1, pt2, circle_center
    (x1, y1), (x2, y2) = (p1x - cx, p1y - cy), (p2x - cx, p2y - cy)
    dx, dy = (x2 - x1), (y2 - y1)
    dr = (dx ** 2 + dy ** 2)**.5
    big_d = x1 * y2 - x2 * y1
    discriminant = circle_radius ** 2 * dr ** 2 - big_d ** 2

    if discriminant < 0:  # No intersection between circle and line
        return []
    else:  # There may be 0, 1, or 2 intersections with the segment
        intersections = [
            (cx + (big_d * dy + sign * (-1 if dy < 0 else 1) * dx * discriminant**.5) / dr ** 2,
             cy + (-big_d * dx + sign * abs(dy) * discriminant**.5) / dr ** 2)
            for sign in ((1, -1) if dy < 0 else (-1, 1))]  # This makes sure the order along the segment is correct
        if not full_line:  # If only considering the segment, filter out intersections that do not fall within the segment
            fraction_along_segment = [(xi - p1x) / dx if abs(dx) > abs(dy) else (yi - p1y) / dy for xi, yi in intersections]
            intersections = [pt for pt, frac in zip(intersections, fraction_along_segment) if 0 <= frac <= 1]
        if len(intersections) == 2 and abs(discriminant) <= tangent_tol:  # If line is tangent to circle, return just one point (as both intersections have same location)
            return [intersections[0]]
        else:
            return intersections

What is most efficient way to find the intersection of a line , But what about the efficiency of find the intersection of every line segment of the p is the circle parameter, lsp and lep is the two end of the line x0,y0,r0 = p x1,y1 to be python, but seems to have lots of quite complex math integrated into it. Shown below is the graph of the circle, the line and the two points of intersection. Figure 1. Intersection of a circle and a line. More References and links Step by Step Math Worksheets SolversNew ! Find Points Of Intersection of Circle and Line - Calculator. Tutorials on equation of circle. Tutorials on equation of circle (2).

A low cost spacial partition might be to divide the plane into 9 pieces

Here is a crappy diagram. Imagine, if you will, that the lines are just touching the circle.

  | |
__|_|__
__|O|__
  | |
  | |

8 of the areas we are interested in are surrounding the circle. The square in the centre isn't much use for a cheap test, but you can place a square of r/sqrt(2) inside the circle, so it's corners just touch the circle.

Lets label the areas

A |B| C
__|_|__
D_|O|_E
  | |
F |G| H

And the square of r/sqrt(2) in the centre we'll call J

We will call the set of points in the centre square shown in the diagram that aren't in J, Z

Label each vertex of the polygon with it's letter code.

Now we can quickly see

AA => Outside
AB => Outside
AC => Outside
...
AJ => Intersects
BJ => Intersects
...
JJ => Inside

This can turned into a lookup table

So depending on your dataset, you may have saved yourself a load of work. Anything with an endpoint in Z will need to be tested however.

Check if a line touches or intersects a circle, The task is to check if the given line collide with the circle or not. Output : Intersect Input : radius = 5, center = (0, 0), a = 5, b = 0, c = 0. How to find the perpendicular distance ? python program to check if a line write comments if you find anything incorrect, or you want to share more information about� Python Set intersection() The intersection() method returns a new set with elements that are common to all sets. The intersection of two or more sets is the set of elements that are common to all sets.

I think that the formula you use to find the coordinates of the two intersections cannot be optimized further. The only improvement (which is numerically important) is to distinguish the two cases: |x_2-x_1| >= |y_2-y_1| and |x_2-x1| < |y_2-y1| so that the quantity k is always between -1 and 1 (in your computation you can get very high numerical errors if |x_2-x_1| is very small). You can swap x-s and y-s to reduce one case to the other.

You could also implement a preliminary check: if both endpoints are internal to the circle there are no intersection. By computing the squared distance from the points to the center of the circle this becomes a simple formula which does not use the square root function. The other check: "whether the line is outside the circle" is already implemented in your code and corresponds to delta < 0. If you have a lot of small segments these two check should give a shortcut answer (no intersection) in most cases.

Geometry — SymPy 1.6.1 documentation, Most of the work one will do will be through the properties and methods of these of the methods and their return values please see the list of classes at the end of The following Python session gives one an idea of how to work with some of the c = Circle(x, 5) from sympy.geometry import Point, Triangle, intersection. The find() method finds the first occurrence of the specified value. The find() method returns -1 if the value is not found. The find() method is almost the same as the index() method, the only difference is that the index() method raises an exception if the value is not found. (See example below)

Circle-Line Intersection, This way we get a more accurate solution from the point of view of numerical stability. We assume without loss of generality that the circle is centered at the origin. If� Intersection of two lines. A necessary condition for two lines to intersect is that they are in the same plane—that is, are not skew lines. Satisfaction of this condition is equivalent to the tetrahedron with vertices at two of the points on one line and two of the points on the other line being degenerate in the sense of having zero volume.

Geometry Module — SymPy 0.7.4.1 documentation, Most of the work one will do will be through the properties and methods of these The following Python session gives one an idea of how to work with some of the geometry module. See Plotting Geometric Entities in the plotting module entry. from sympy.geometry import Point, Line, Circle, intersection >>> p1, p2,� Equations for a circle or ellipse have an term and a term. To find the intersection of a circle and a straight line, solve for x in the linear equation. Substitute the solution for x in the circle equation, and you'll have an easier quadratic equation. These problems can have 0, 1, or 2 solutions, as described in the method above.

Area of intersection of two circles python, One of the four line segment endpoints is considered the "active" endpoint, circle python how two algorithm find with detection area the algorithm - Best way to� Note segment 1 does not equal segment2. So in my code I've also been calculating the slope and y-intercept, it would be nice if that could be avoided but I don't know of a way how. I've been using Cramer's rule with a function I wrote up in Python but I'd like to find a faster way of doing this.

Comments
  • seems to me that you consider the intersections of the circle with the whole line, not only the line segment between the two given points. Is this what you want?
  • The only possible optimisation I can think of involves the use of some kind of spatial partition. E.g. a quad-tree. But there is non-trivial cost associated in computing these, so it depends on your larger problem if that's useful or not.
  • @EmanuelePaolini,Thank you.I've modified the script according to your concern.
  • stackoverflow.com/questions/1073336/… - may be relevant
  • Are there still any open issues not answered by any of the answers posted?
  • Yeah...What about the efficiency of calculate the intersection by the library like Shapely or SymPy, compared to define function myself? That's one of what I want to know.
  • Shapely is based on GEOS (trac.osgeo.org/geos) which is built in C++ and considerably faster than anything you write natively in python. SymPy seems to be based on mpmath (mpmath.org) which also seems to be python, but seems to have lots of quite complex math integrated into it. Implementing that yourself may require a lot of work, and will probably not be as fast as GEOS C++ implementations.