我有扩展多边形的代码,它的工作原理是把xs和ys乘以一个因子,然后将生成的polyn重新定心在原始polyn的中心。
我还有代码来查找膨胀系数的值,给定多边形需要达到的点:
import numpy as np
import itertools as IT
import copy
from shapely.geometry import LineString, Point
def getPolyCenter(points):
"""
http://stackoverflow.com/a/14115494/190597 (mgamba)
"""
area = area_of_polygon(*zip(*points))
result_x = 0
result_y = 0
N = len(points)
points = IT.cycle(points)
x1, y1 = next(points)
for i in range(N):
x0, y0 = x1, y1
x1, y1 = next(points)
cross = (x0 * y1) - (x1 * y0)
result_x += (x0 + x1) * cross
result_y += (y0 + y1) * cross
result_x /= (area * 6.0)
result_y /= (area * 6.0)
return (result_x, result_y)
def expandPoly(points, factor):
points = np.array(points, dtype=np.float64)
expandedPoly = points*factor
expandedPoly -= getPolyCenter(expandedPoly)
expandedPoly += getPolyCenter(points)
return np.array(expandedPoly, dtype=np.int64)
def distanceLine2Point(points, point):
points = np.array(points, dtype=np.float64)
point = np.array(point, dtype=np.float64)
points = LineString(points)
point = Point(point)
return points.distance(point)
def distancePolygon2Point(points, point):
distances = []
for i in range(len(points)):
if i==len(points)-1:
j = 0
else:
j = i+1
line = [points[i], points[j]]
distances.append(distanceLine2Point(line, point))
minDistance = np.min(distances)
#index = np.where(distances==minDistance)[0][0]
return minDistance
"""
Returns the distance from a point to the nearest line of the polygon,
AND the distance from where the normal to the line (to reach the point)
intersets the line to the center of the polygon.
"""
def distancePolygon2PointAndCenter(points, point):
distances = []
for i in range(len(points)):
if i==len(points)-1:
j = 0
else:
j = i+1
line = [points[i], points[j]]
distances.append(distanceLine2Point(line, point))
minDistance = np.min(distances)
i = np.where(distances==minDistance)[0][0]
if i==len(points)-1:
j = 0
else:
j = i+1
line = copy.deepcopy([points[i], points[j]])
centerDistance = distanceLine2Point(line, getPolyCenter(points))
return minDistance, centerDistance
minDistance, centerDistance = distancePolygon2PointAndCenter(points, point)
expandedPoly = expandPoly(points, 1+minDistance/centerDistance)
此代码仅在点与一条多边形直线直接相对时有效。
最佳答案
将方法distancePolygon2PointAndCenter
修改为
返回从点到多边形最近直线的距离
返回从点到与光线相交的线段的距离。这是多边形完全展开后与点相交的线。要得到这个线段,取多边形每个线段的两个端点,并将它们插入到与前面提到的光线相交的平行线的方程中即y = ((centerY-pointY)/(centerX-pointX)) * (x - centerX) + centerY
。您希望找到其中一个端点与直线相交,或者两个端点位于直线的相对边上。
然后,剩下要做的唯一事情是确保我们选择与直线的右侧“边”相交的线段要做到这一点,有几个选择。故障安全方法是使用公式cos(theta) = sqrt((centerX**2 + centerY**2)*(pointX**2 + pointY**2)) / (centerX * pointX + centerY * pointY)
但是,您可以使用方法,例如比较x和y值,采用arctan2()
,以及确定哪一段位于中心的正确“侧”你只需要盖很多边缘的箱子。在所有这些都说完并完成之后,您的两个端点(除非它不是凸的,在这种情况下取离您中心最远的线段)构成要展开的线段。