在python中找到一条直线和一个圆的交点最有效的方法是什么? [英] What is most efficient way to find the intersection of a line and a circle in python?

查看:1570
本文介绍了在python中找到一条直线和一个圆的交点最有效的方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个由很多点组成的多边形。我想找到多边形和一个圆的交点。提供[x0,y0]的圆心和r0的半径,我写了一个粗略的函数来简单地求解圆和线的二次方程。但是多边形的每一条线段的效率一个接一个地寻找? 是否有更高效的方法?



我知道sympy已经提供了获取不同几何体相交的功能。如果我想处理大量的多边形,那么像sympy这样的外部库的效率如何与我自己的函数计算

  def LineIntersectCircle(p,lsp,lep):
#p是圆参数,lsp和lep是行的两端
x0,y0, r0 = p
x1,y1 = lsp
x2,y2 = esp
如果x1 == x2:
如果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]
#选择位于线段上的点
inp = [p for inp如果p [1]> = min(y1, y2)和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如果Δ> = 0:
p1x =(y0)** 2 + x0 ** 2 - r0 ** 2
delta = b ** 2 - 4 * a * c
-b-sqrt(delta))/(2 * a)
p2x =(-b + sqrt(delta))/(2 * a)
p1y = k * x1 + b0
p2y = k * x2 + b0
inp = [ [p1x,p1y],[p2x,p2y]]
#选择位于线段上的点
inp = [p for inp如果p [0]> = min(x1,x2 )和p [0] <= max(x1,x2)]
else:
inp = []
return inp


解决方案

我想也许你的问题是关于如何在理论上以最快的方式做到这一点。但如果你想快速做到这一点,你应该真的使用C / C ++编写的东西。



我非常习惯于匀称的,所以我将提供一个如何在这个库中做到这一点的例子。 python有很多几何库。

  from shapely.geometry import lineString $ b $ from shapely.geometry import Point 

p = Point(5,5)
c = p.buffer(3).boundary
l = LineString([(0,0),(10,10)])
i = c.intersection(l)

print i.geoms [0] .coords [0]
(2.8786796564403576,2.8786796564403576)

打印i .geoms [1] .coords [0]
(7.121320343559642,7.121320343559642)

什么是在Shapely中有一点直观的地方就是圆圈是缓冲区域点的边界。这就是为什么我做 p.buffer(3).bound



交点是一个几何形状的列表,在这种情况下它们都指向一个点,这就是为什么我必须从 i.geoms []



有另外一个Stackoverflow问题,其中详细介绍了这些库对于那些有兴趣的人。



编辑是因为评论:

Shapely是基于GEOS(trac.osgeo.org/geos),它是用C ++编写的,比你在本地编写的任何东西蟒蛇。 SymPy似乎基于mpmath(mpmath.org),它似乎也是python,但似乎有很多相当复杂的数学运算。实现这一点可能需要很多工作,并且可能不会像GEOS C ++实现那样快。


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

解决方案

I guess maybe your question is about how to in theory do this in the fastest manner. But if you want to do this quickly, you should really use something which is written in C/C++.

I am quite used to Shapely, so I will provide an example of how to do this with this library. There are many geometry libraries for python. I will list them at the end of this answer.

from shapely.geometry import LineString
from shapely.geometry import Point

p = Point(5,5)
c = p.buffer(3).boundary
l = LineString([(0,0), (10, 10)])
i = c.intersection(l)

print i.geoms[0].coords[0]
(2.8786796564403576, 2.8786796564403576)

print i.geoms[1].coords[0]
(7.121320343559642, 7.121320343559642)

What is a little bit counter intuitive in Shapely is that circles are the boundries of points with buffer areas. This is why I do p.buffer(3).boundry

Also the intersection i is a list of geometric shapes, both of them points in this case, this is why I have to get both of them from i.geoms[]

There is another Stackoverflow question which goes into details about these libraries for those interested.

EDIT because comments:

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.

这篇关于在python中找到一条直线和一个圆的交点最有效的方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆