SymPy中线段与多边形内部的交点

4
我希望能够计算由多边形覆盖的线段长度。 为此,我使用以下sympy代码。不幸的是,它将多边形视为一组线条,而不是一个区域,因此我只得到交点的坐标。
>>> import sympy
>>> t = sympy.geometry.Polygon((0,0), (0,1), (1,0))
>>> l = sympy.geometry.Segment((1/3,1/3), (2,2))
>>> t.intersect(l)
{Point2D(1/2, 1/2)}

我尝试使用多边形的闭合属性 closure,但不幸的是,这似乎没有实现。

>>> t.closure
NotImplementedError                       Traceback (most recent call last)

使用sympy返回的点,也许我可以尝试自己计算生成的线段,但是这似乎涉及很多特殊情况,所以我希望有一个库可以为我完成这个任务。

我是否忽略了什么?


如果我没记错的话,你的线只在多边形边界处相交于一个点,因此并不构成一条线。 - NaN
1个回答

3

Polygon类可以称为PolygonalCurve;它目前不是用来描述填充平面图形的。

多边形被视为封闭路径而不是2D区域。

对于凸多边形,以下方法适用:

def intersection_length(l, t):
    endpoints = [p for p in [l.p1, l.p2] if t.encloses(p)]
    endpoints.extend(iter(t.intersect(l)))
    if len(endpoints) < 2:
        return 0
    else: 
        intersection = sympy.geometry.Segment(*endpoints)
    return intersection.length

在你的例子中,它返回sqrt(2)/6。其想法是,如果交点是一个非平凡线段,则其端点将来自于(a)与t的边界相交的l的交点;(b)由t包围的l的端点。因此,收集所有候选项,如果我们有两个候选项,则找到它们之间的距离。
(虽然可以在不形成Segment对象的情况下计算距离,但我认为拥有一个对象也很好)。
对于非凸多边形,我们可能会有更复杂的交点,有几个部分。我也为这种情况编写了一个解决方案,但您需要使用SymPy的GitHub版本,因为它使用了最近添加的parameter_value方法(它将在SymPy 1.2中提供)。
这里的方法是像以前一样找到所有端点(可能不止2个),根据线段的方向对它们进行排序,然后对每个部分进行测试,看看是否应该包含它(通过考虑部分的中点是否被包围)。
import sympy

def intersection_length(segment, polygon):
    endpoints = [p for p in [segment.p1, segment.p2] if polygon.encloses(p)]
    endpoints.extend(iter(polygon.intersect(segment)))
    u = sympy.Symbol('u')
    endpoints.sort(key=lambda p: segment.parameter_value(p, u)[u])
    total_length = 0
    for a, b in zip(endpoints[:-1], endpoints[1:]):
        piece = sympy.geometry.Segment(a, b)
        if polygon.encloses(piece.midpoint):
            total_length += piece.length
    return total_length

t = sympy.geometry.Polygon((0, 0), (5, 0), (1, 1), (0, 5))
l = sympy.geometry.Segment((-1, 5), (5, -1))
print(intersection_length(l, t))

非凸多边形可能会有更复杂的交集。如果多边形自相交,情况将变得更加复杂。但是,对于非自相交的情况,您所拥有的看起来很不错。 - smichr
将线段分成若干部分的过程仍然适用,问题在于何时将一段长度计入交点。我相信encloses会做正确的事情,无论正确的事情是什么。 - user6655984

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接