3

我想找到一条线与多边形相交的点。我使用来自这个线程的凹轮廓计算获得了这个多边形。

import alphashape
from shapely.geometry import LineString
import matplotlib.pyplot as plt
from descartes import PolygonPatch

points = [(17, 158),(15, 135),(38, 183),(43, 19),(93, 88),(96, 140),(149, 163),(128, 248),(216, 265),(248, 210),(223, 167),(256, 151),(331, 214),(340, 187),(316, 53),(298, 35),(182, 0),(121, 42)]
points = np.array(points)

alpha = 0.99 * alphashape.optimizealpha(points)
hull = alphashape.alphashape(points, alpha)
hull_pts = hull.exterior.coords.xy
path = PolygonPatch(hull, fill=False, color='green')
print(path.contains_point([128,248]))

fig, ax = plt.subplots()
ax.scatter(hull_pts[0], hull_pts[1], color='red')
ax.scatter(points[:,0], points[:,1], color='red')

p = np.array([[350, 100],[0, 100]])
ax.plot(p[:, 0], p[:, 1], color='blue')
ax.add_patch(path)

在此处输入图像描述

到目前为止,我尝试定义一条线:

l = LineString(p)
inters = l.intersection(hull)

inters.xy返回一个 NotImplemented 错误,所以我不确定如何获取线与多边形相交的点的坐标。

4

2 回答 2

3

交集返回 a MultilineString,它是 list of 的一个花哨的词LineStrings。然后我们可以从每个 Linestring 中检索坐标,例如:

import alphashape
from shapely.geometry import LineString
import matplotlib.pyplot as plt
import numpy as np

#replicating your example
fig, ax = plt.subplots()

line_xy = [[350, 100],[0, 120]]
points = np.asarray([(17, 158),(15, 135),(38, 183),(43, 19),(93, 88),(96, 140),(149, 163),(128, 248),(216, 265),(248, 210),(223, 167),(256, 151),(331, 214),(340, 187),(316, 53),(298, 35),(182, 0),(121, 42)])

alpha = 0.99 * alphashape.optimizealpha(points)
hull = alphashape.alphashape(points, alpha)
hull_pts = hull.exterior.coords.xy

p = LineString(line_xy)

ax.plot(*hull_pts, c="green")
ax.scatter(points[:,0], points[:,1], marker="o", color="red")
ax.scatter(*hull_pts, marker="s", color="red")

ax.plot(*p.coords.xy, color='blue')

#retrieving intersection 
inters = hull.intersection(p)

#checking for object type to retrieve all intersection coordinates
if inters.type == "LineString":
    coords = np.asarray([inters.coords.xy])
elif inters.type == "MultiLineString":
    coords = np.asarray([l.coords.xy for l in inters.geoms])
    
#reshaping array point coordinates into a form that does not make my head hurt
coords = coords.transpose(1, 0, 2).reshape(2, -1)
print(coords)

plt.show()

返回coords[:, i]交点的 xy 值i

样本输出:

[[324.67707894 234.24811338 176.4217078   18.88111888]
 [101.44702406 106.61439352 109.91875955 118.92107892]]

在此处输入图像描述

奇怪的是,将船体内shapely的线点300, 100视为交点。严格来说,必须检查所有已识别的点是否都位于船体多边形内。

并且 alphashape(此处使用 1.3.1)应该更新他们的例程,因为alphashape.alphashape(points, alpha)生成错误消息ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry.

于 2022-01-31T15:40:22.897 回答
0

a当一条边的端点(let和b)的纵坐标跨越直线的纵坐标(let )时,一条边与一条水平线相交Y。因此,相交测试非常简单。要获取交点本身,请使用

Xi = Xa + (Y - Ya) (Xb - Xa) / (Yb - Ya)
Yi = Y

什么时候做Y = Ya = Yb取决于应用程序。


如果线是垂直的,只需交换 和 的X角色Y

如果线条是倾斜的,您可以使用使线条水平的旋转。这可以通过变换方便地用复数表示

Z = z e^(-iΘ)

尽管您不需要复数来实现这一点,但获得旋转系数的方式取决于线的指定方式。

计算交点后,您将其反向旋转。

于 2022-02-01T09:26:34.343 回答