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

2024-09-30 01:29:06 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我也有代码可以找到展开因子的值,给定多边形需要到达的点:

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)

此代码仅在点与其中一条多边形直线正相反时有效。在


Tags: theimportlenreturndefnplineresult
2条回答

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

从点p到C做一个线段。找出PC和多边形边的交点I。如果多边形是凹的,并且有一些交点,请选择离P最近的一个

计算膨胀系数:

 E = Length(PC) / Length(CI)

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

^{pr2}$

将方法distancePolygon2PointAndCenter改为

Returns the distance from a point to the nearest line of the polygon

返回从一个点到的距离,该距离是由一条光线从中心到该点相交的线段。这是一条完全展开的多边形的交点。要得到这个线段,取多边形每个线段的两个端点,并将它们插入到前面提到的与光线平行和相交的直线的方程式中。那就是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()等方法来确定哪个段在中心的正确“侧”。你会有很多边缘案件要处理。在所有这些都说了,并做了,你的两个端点(除非它不是凸的,在这种情况下,取离你中心最远的线段)组成要展开的线段。在

相关问题 更多 >

    热门问题