如何扩展多边形直到其中一个边界到达一点

问题描述 投票:0回答:3

我有扩展多边形的代码,它的工作原理是将 xs 和 ys 乘以一个因子,然后将所得多边形重新居中于原始多边形的中心。

我还有代码来查找扩展因子的值,给定多边形需要到达的点:

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)

此代码仅在该点与其中一条多边形线直接相对时才有效。

python algorithm geometry polygon computational-geometry
3个回答
4
投票

将您的方法

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()
 等方法来找出哪一段位于中心的正确“一侧” 。您将需要处理很多边缘情况。完成所有这些操作后,您的两个端点(除非它不是凸的,在这种情况下取距离您中心最远的线段)端点构成要扩展的线段。


1
投票
确定什么是“多边形中心”作为展开的中心点C。也许它是质心(或者具有其他属性的某个点?)。

从点 P 到 C 作一条线段。找到 PC 和多边形边之间的交点 I。如果多边形是凹的并且有一些交点,则选择最接近 P 的一个。

计算膨胀系数:

E = Length(PC) / Length(CI)

计算新的顶点坐标。对于多边形的第 i 个顶点:

V'[i].X = C.X + (V[i].X - C.X) * E V'[i].Y = C.Y + (V[i].Y - C.Y) * E
    

1
投票
决定要到达哪个点,然后计算多边形需要扩展多少%才能到达该点,并使用

shapely.affinity.scale 函数。例如,在我的例子中,我只需要使多边形变大 5%:

region = shapely.affinity.scale(myPolygon, xfact=1.05, yfact=1.05 )
    
© www.soinside.com 2019 - 2024. All rights reserved.