获取线穿过多边形的点的坐标
get coordinate of points where a line crosses a polygon
我想找到一条线与多边形相交的点。我使用 .
的凹轮廓计算得到这个多边形
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
returns一个NotImplemented错误,所以我不确定如何获取线穿过多边形的点的坐标。
交集returns a MultilineString
,这是LineStrings
列表的花哨词。我们可以从每个线串中检索坐标,例如:
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]
返回交点 i
的 x-y 值。
示例输出:
[[324.67707894 234.24811338 176.4217078 18.88111888]
[101.44702406 106.61439352 109.91875955 118.92107892]]
奇怪的是,shapely
将外壳内的线点(如 300, 100
)视为交点。严格来说,必须检查 none 个已识别点是否位于外壳多边形内。
并且 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.
当一条边的端点(令a
和b
)的纵坐标跨越该线的纵坐标(令Y
)时,一条边穿过一条水平线。因此相交测试非常简单。要获取交点本身,请使用
Xi = Xa + (Y - Ya) (Xb - Xa) / (Yb - Ya)
Yi = Y
当 Y = Ya = Yb
取决于应用程序时该怎么办。
如果直线是垂直的,只需交换X
和Y
的角色即可。
如果线是倾斜的,您可以使用使线水平的旋转。这可以通过变换
方便地用复数表示
Z = z e^(-iΘ)
虽然你不需要复数来实现这个,并且获得旋转系数的方式取决于线的指定方式。
计算交集后,你counter-rotate它。
我想找到一条线与多边形相交的点。我使用
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
returns一个NotImplemented错误,所以我不确定如何获取线穿过多边形的点的坐标。
交集returns a MultilineString
,这是LineStrings
列表的花哨词。我们可以从每个线串中检索坐标,例如:
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]
返回交点 i
的 x-y 值。
示例输出:
[[324.67707894 234.24811338 176.4217078 18.88111888]
[101.44702406 106.61439352 109.91875955 118.92107892]]
奇怪的是,shapely
将外壳内的线点(如 300, 100
)视为交点。严格来说,必须检查 none 个已识别点是否位于外壳多边形内。
并且 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.
当一条边的端点(令a
和b
)的纵坐标跨越该线的纵坐标(令Y
)时,一条边穿过一条水平线。因此相交测试非常简单。要获取交点本身,请使用
Xi = Xa + (Y - Ya) (Xb - Xa) / (Yb - Ya)
Yi = Y
当 Y = Ya = Yb
取决于应用程序时该怎么办。
如果直线是垂直的,只需交换X
和Y
的角色即可。
如果线是倾斜的,您可以使用使线水平的旋转。这可以通过变换
方便地用复数表示Z = z e^(-iΘ)
虽然你不需要复数来实现这个,并且获得旋转系数的方式取决于线的指定方式。
计算交集后,你counter-rotate它。