Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding intersection points of two ellipses (Python)

I'm writing a basic 2D shape library in Python (primarily for manipulating SVG drawings), and I'm at a loss for how to efficiently calculate the intersection points of two ellipses.

Each ellipse is defined by the following variables (all floats):

c: center point (x, y)
hradius: "horizontal" radius
vradius: "vertical" radius
phi: rotation from coordinate system's x-axis to ellipse's horizontal axis

Ignoring when the ellipses are identical, there could be 0 through 4 intersection points (no intersection, tangent, partially overlapping, partially overlapping and internally tangent, and fully overlapping).

I've found a few potential solutions:

  • SymPy geometry module - This basically just plugs the ellipse equations into SymPy's solver. I'm not sure whether this makes sense without already having the solver. (Incidentally, I would have used SymPy instead of rolling my own, but it performs horribly when dealing with crazy floats)
  • How to detect if an ellipse intersects(collides with) a circle - This could probably be adapted for two ellipses, but I'm a little fuzzy on how to turn it into sensible code.
  • How Ellipse to Ellipse intersection? - The library the answer references (CADEMIA) might have a good algorithm, but I can't even figure out if it's open source.
  • Wikipedia: Intersecting Two Conics - I don't have enough of a grasp of linear algebra to understand this solution.

Any suggestions on how I should go about calculating the intersections? Speed (it might have to calculate a lot of intersections) and elegance are the primary criteria. Code would be fantastic, but even a good direction to go in would be helpful.

like image 544
mrjogo Avatar asked Mar 16 '13 04:03

mrjogo


People also ask

How do you find the point of intersection of two ellipses?

An intersection of x = ¯x with the ellipse w2 + c(x) = 0 occurs when c(¯x) ≤ 0, in which case w = ±√−c(¯x). The intersection is transverse when c(¯x) < 0 or tangential when c(¯x) = 0. These sign tests can be computed accurately when using rational arithmetic.

How do you find the intersection of a line and an ellipse?

The line y=mx+c intersects with the ellipse x2a2+y2b2=1 at two points maximum and the condition for such intersection is that c2<a2m2+b2.

How do you find the number of points of intersection?

The point of intersection formula is used to find the point of intersection of two lines, meaning the meeting point of two lines. These two lines can be represented by the equation a1x+b1y+c1=0 a 1 x + b 1 y + c 1 = 0 and a2x+b2y+c2=0 a 2 x + b 2 y + c 2 = 0 , respectively.


1 Answers

In math, you need to express the ellipses as bivariate quadratic equations, and solve it. I found a doucument. All the calculations are in the document, but it may take a while to implement it in Python.

So another method is to approximate the ellipses as polylines, and use shapely to find the intersections, here is the code:

import numpy as np
from shapely.geometry.polygon import LinearRing

def ellipse_polyline(ellipses, n=100):
    t = linspace(0, 2*np.pi, n, endpoint=False)
    st = np.sin(t)
    ct = np.cos(t)
    result = []
    for x0, y0, a, b, angle in ellipses:
        angle = np.deg2rad(angle)
        sa = np.sin(angle)
        ca = np.cos(angle)
        p = np.empty((n, 2))
        p[:, 0] = x0 + a * ca * ct - b * sa * st
        p[:, 1] = y0 + a * sa * ct + b * ca * st
        result.append(p)
    return result

def intersections(a, b):
    ea = LinearRing(a)
    eb = LinearRing(b)
    mp = ea.intersection(eb)

    x = [p.x for p in mp]
    y = [p.y for p in mp]
    return x, y

ellipses = [(1, 1, 2, 1, 45), (2, 0.5, 5, 1.5, -30)]
a, b = ellipse_polyline(ellipses)
x, y = intersections(a, b)
plot(x, y, "o")
plot(a[:,0], a[:,1])
plot(b[:,0], b[:,1])

and the output:

enter image description here

It takes about 1.5ms on my PC.

like image 157
HYRY Avatar answered Sep 24 '22 06:09

HYRY