Python 形状多边形与Matplotlib楔体的交点

Python 形状多边形与Matplotlib楔体的交点,python,matplotlib,intersection,shapely,Python,Matplotlib,Intersection,Shapely,在这个场景中,我正在打印对象和缓冲对象。我需要计算这两个物体的重叠面积。但是,Wedge是一个matplotlib.wedges对象,不能与Shapely的.intersection()方法一起使用 我该怎么做? 下面是一些代码: from shapely.geometry import LineString from matplotlib.patches import Wedge from matplotlib import pyplot as plt from descartes.patch

在这个场景中,我正在打印对象和缓冲对象。我需要计算这两个物体的重叠面积。但是,
Wedge
是一个
matplotlib.wedges
对象,不能与Shapely的
.intersection()
方法一起使用

我该怎么做? 下面是一些代码:

from shapely.geometry import LineString
from matplotlib.patches import Wedge
from matplotlib import pyplot as plt
from descartes.patch import PolygonPatch

width = 5
radius = 1
rich = 1

circle_patch = Wedge((0, 0), radius+3,
                     0, 360, 3)

fig, ax = plt.subplots()

ax.add_patch(circle_patch)

ax.plot(0, 0, 'xr')
plt.autoscale()

coords = [
    [0, 0],
    [0, 1],
    [0, 2],
    [1, 2],
    [2, 2]
]

stick = LineString(coords)

stick_patch = PolygonPatch(stick.buffer(0.5))

ax.add_patch(stick_patch)

x, y = stick.xy
ax.plot(x, y, 'r-', zorder=1)

plt.show()

area = stick.buffer(0.5).intersection(circle_patch).area


另外,它必须是环形的,而不是圆形的。有一个
matplotlib.patches
类的
path.vertices
成员,它为您提供了楔形对象的坐标数组,然后您可以使用Shapely的
LinearRing
类来创建Shapely对象,如下所示:

from shapely.geometry import LineString, LinearRing
from matplotlib.patches import Wedge

width = 5
radius = 1
rich = 1

circle_patch = Wedge((0, 0), radius,
                     0, 360,)

ring_coords = circle_patch._path.vertices
ring_coords = ring_coords[(ring_coords[:, 0] != 0) & (ring_coords[:, 1] != 0)]

ring = LinearRing(ring_coords)
然而,它确实需要对坐标数组进行操作,我认为这不是最可靠的方法,但对我来说可以。此外,环不是完全平滑的,但我确信可以使用一些或其他
Numpy
Scipy
函数对坐标数组进行平滑处理。


编辑:要创建单个楔形线条,必须删除楔形的
宽度
成员。但是,稍后可以使用Shapely的
buffer()
函数重新合并此功能。

最简单的解决方案是不使用Matplotlib面片,而首先使用Shapely构建楔形多边形:

import matplotlib.pyplot as plt
from descartes.patch import PolygonPatch
from shapely.geometry import LineString, Point

outer_circle = Point(0, 0).buffer(4)
inner_circle = Point(0, 0).buffer(1)
wedge = outer_circle.difference(inner_circle)

stick = LineString([(0, 0), (0, 2), (2, 2)])
buffered_stick = stick.buffer(0.5)

intersection = buffered_stick.intersection(wedge)

wedge_patch = PolygonPatch(wedge)
stick_patch = PolygonPatch(buffered_stick, alpha=0.5, hatch='/')
intersection_patch = PolygonPatch(intersection, alpha=0.5, hatch='.')

fig, ax = plt.subplots()
ax.add_patch(wedge_patch)
ax.add_patch(stick_patch)
ax.add_patch(intersection_patch)
plt.autoscale()


如果由于某种原因,这是不可能的,并且您必须使用Matplotlib的
楔块
,那么我可以想出两种方法来获得它与Shapely多边形的相交区域。在这两种情况下,我首先将面片转换为形状良好的多边形。仅使用Matplotlib即可获得相交区域

1) 使用Matplotlib面片上的方法,从中可以提取为NumPy数组,并使用以下方法将其转换为形状多边形:

请注意我应用于楔形多边形的
缓冲区(0)
。这是Shapely中的一个常见技巧,用于从无效多边形中生成有效多边形。在这种情况下,当从
环坐标中删除零时,您也会执行类似的操作

2) 通过访问
Wedge
属性:
center
r
width
,并使用它们重新创建多边形:

import matplotlib.pyplot as plt
from descartes.patch import PolygonPatch
from matplotlib.patches import Wedge
from shapely.geometry import LineString, Point

wedge_patch = Wedge(center=(0, 0), 
                    r=4,
                    theta1=0, 
                    theta2=360, 
                    width=3)
stick = LineString([(0, 0), (0, 2), (2, 2)])
buffered_stick = stick.buffer(0.5)

outer_circle = Point(wedge_patch.center).buffer(wedge_patch.r)
inner_circle = Point(wedge_patch.center).buffer(wedge_patch.r - wedge_patch.width)
wedge_polygon = outer_circle.difference(inner_circle)
intersection = buffered_stick.intersection(wedge_polygon)

stick_patch = PolygonPatch(buffered_stick, alpha=0.5, hatch='/')
intersection_patch = PolygonPatch(intersection, alpha=0.5, hatch='.')

fig, ax = plt.subplots()
ax.add_patch(wedge_patch)
ax.add_patch(stick_patch)
ax.add_patch(intersection_patch)
plt.autoscale()
所有解决方案都提供相同的视觉输出

所有方法给出的面积大致相同:

>>> intersection.area
3.3774012986988513  # 1st case
3.3823210603713694  # 2nd case and the original without Matplotlib

也许可以这样制作戒指:谢谢,但我发现了另一种方法,你改变了你在问题中的原始
楔子。有了这个,你会在生成的多边形中丢失一块。
>>> intersection.area
3.3774012986988513  # 1st case
3.3823210603713694  # 2nd case and the original without Matplotlib