简体   繁体   中英

Finding intersection between ellipse and a line

I am trying to find intersection points between an elipse and a line, but seem to be unable to do so. I have tried two approaches, one with shapely by trying to find intersection between LineString and LinearRing as in the code bellow, but did not get any usable values out of it. One of the problems, is the elipse will always be off center and at an small or high angle

  # -*- coding: utf-8 -*-
"""
Created on Mon Aug 19 17:38:55 2013

@author: adudchenko
"""
from pylab import *
import numpy as np
from shapely.geometry.polygon import LinearRing
from shapely.geometry import LineString
def ellipse_polyline(ellipses, n=100):
    t = np.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, line):
    ea = LinearRing(a)
    eb = LinearRing(b)
    mp = ea.intersection(eb)
    print mp
    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)
line=LineString([[0,0],[4,4]])
x, y = intersections(a, line)
figure()
plot(x, y, "o")
plot(a[:,0], a[:,1])
plot(b[:,0], b[:,1])
show()

I also tried using fsolve as in example bellow, but it finds the wrong intersect points ( or actually one wrong point.

from pylab import *
from scipy.optimize import fsolve
import numpy as np

def ellipse_polyline(ellipses, n=100):
    t = np.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 * np.cos(t) - b * sa * np.sin(t)
        p[:, 1] = y0 + a * sa * np.cos(t) + b * ca * np.sin(t)
        result.append(p)
    return result
def ellipse_line(txy):
    t,x,y=txy
    x0, y0, a, b, angle,m,lb=1, 1, 2, 1, 45,0.5,0
    sa = np.sin(angle)
    ca = np.cos(angle)
    return (x0 + a * ca * np.cos(t) - b * sa * np.sin(t)-x,y0 + a * sa * np.cos(t) + b * ca * np.sin(t)-y,m*x+lb-y) 
a,b= ellipse_polyline([(1, 1, 2, 1, 45), (2, 0.5, 5, 1.5, -30)])
t,y,x=fsolve(ellipse_line,(0,0,0))
print t,y,x
#print a[:,0]
m=0.5
bl=0
xl,yl=[],[]
for i in range(10):
    xl.append(i)
    yl.append(m*i+bl)
figure()
plot(x, y, "o")
plot(a[:,0], a[:,1])
plot(xl,yl)

Any help would be appriceated?

With the Shapely part, def intersections(a, line) can be fixed. First, there is an error, where it references a global b instead of using the line parameter, which is ignored. Thus the comparison is between the two ellipses a and b , and not between each ellipse to line , as I think is intended.

Also, the intersection between two lines can be one of several outcomes: an empty set, a point (1 intersection) a multipoint (more than 1 intersection), a linestring (if any part(s) of the linestrings overlap and are parallel to each other), or a collection of points and lines. Assuming only the first three outcomes:

def intersections(a, line):
    ea = LinearRing(a)
    mp = ea.intersection(line)
    if mp.is_empty:
        print('Geometries do not intersect')
        return [], []
    elif mp.geom_type == 'Point':
        return [mp.x], [mp.y]
    elif mp.geom_type == 'MultiPoint':
        return [p.x for p in mp], [p.y for p in mp]
    else:
        raise ValueError('something unexpected: ' + mp.geom_type)

So now these look correct:

>>> intersections(a, line)
([2.414213562373095], [2.414213562373095])
>>> intersections(b, line)
([0.0006681263405436677, 2.135895843256409], [0.0006681263405436642, 2.135895843256409])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM