多边形的凹凸性判断及python实现

博客围绕给定二维封闭图形点集判断各点凹凸性展开。采用矢量判断法检测多边形凸点,先找到图形中第一个凸点(y坐标最大,若多个则x坐标最大),利用叉乘公式计算,第一个凸点叉乘为正,其他点叉乘为负则为凹点,还给出了Python实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 问题描述:给定一个二维封闭图形点集,判断图形中各点的凹凸性。
  2. 方法:使用矢量判断凹凸性,检测多边形的凸点。参考:判断平面多边形的凹凸性
  3. 关键点:
    (1)通过矢量判断时,需找到图形中第一个凸点:y坐标最大的点,若y坐标最大点不止一个,则寻找其中x坐标最大点
    (2)叉乘公式: 向量A(x1,y1),向量B(x2,y2)
    叉乘结果 = x1 * y2 - x2 * y1
    (3)第一个凸点的叉乘必为正,如果其他点叉乘结果为负,则说明该点为凹点。

下面是该问题的python实现

import numpy as np

def find_ymax(data):
    """寻找封闭图形中y坐标最大的点
       若y坐标最大点不止一个,则寻找其中x坐标最大点
    Args:
        data (list): 封闭图形点集
    Returns:
        封闭图形中第一个凸点
    """
    ploy = np.array(data)
    y = ploy[:,1]
    y_max = y.max()
    Conv_list = list()
    for p in data:
        if p[1] == y_max:
            Conv_list.append(p)
    
    if len(Conv_list) != 1:
        temp_list = []
        for p in Conv_list:
            temp_list.append(p[0])
        return Conv_list[temp_list.index(max(temp_list))]
    else:
        return Conv_list[0]
    
def Conv(data):
    """对多边形各点进行凹凸性判断
    Args:
        data (list): 封闭图形点集
    Returns:
        [list]: 多边形中凹点坐标集合
    """
    Norm_dot = find_ymax(data)
    num = len(data)
    Ind = data.index(Norm_dot)
    Conv_dots = []
    # 第一个凸点的两条向量边叉乘
    # if num == 0:
    #     Vec_A = [data[num][0] - data[Tonum - 1][0] , data[num][1] - data[Tonum - 1][1]]
    #     Vec_B = [data[num+1][0] - data[num][0] , data[num+1][1] - data[num][1]]
    # elif num == Tonum - 1:
    #     Vec_A = [data[num][0] - data[num - 1][0] , data[num][1] - data[num - 1][1]]
    #     Vec_B = [data[0][0] - data[num][0] , data[0][1] - data[num][1]]
    # else:
    #     Vec_A = [data[num][0] - data[num - 1][0] , data[num][1] - data[num - 1][1]]
    #     Vec_B = [data[num+1][0] - data[num][0] , data[num+1][1] - data[num][1]]
    Vec_A = [data[Ind%num][0] - data[(Ind-1)%num][0], data[Ind%num][1] - data[(Ind-1)%num][1]]
    Vec_B = [data[(Ind+1)%num][0] - data[Ind%num][0], data[(Ind+1)%num][1] - data[Ind%num][1]]
    Vect_Norm = (Vec_A[0] * Vec_B[1]) - (Vec_A[1] * Vec_B[0])
    # 向量法判断图形中每个点的凹凸性
    for i in range(num):
        V_A = [data[(i)%num][0] - data[(i-1)%num][0], data[(i)%num][1] - data[(i-1)%num][1]]
        V_B = [data[(i+1)%num][0] - data[(i)%num][0], data[(i+1)%num][1] - data[(i)%num][1]]
        Vec_Cross = (V_A[0] * V_B[1]) - (V_A[1] * V_B[0])
        if (Vec_Cross * Vect_Norm) < 0:
            Conv_dots.append(data[(i) % num])
    
    return Conv_dots

data = [[20,12],[25,0],[30,15],[15,17],[15,20],[10,20],[10,10]]    
print(Conv(data))

如有不足,还请各位大佬不吝赐教!

### 使用叉乘法确定多边形边缘凹凸方法和原理 对于一个多边形而言,其顶按照一定顺序排列形成一系列连续的边。为了判断某一边是否属于边还是凸边,可以利用相邻两条边的方向向量之间的关系来进行判定。 具体来说,假设存在一条由顶 \( P_i \) 到 \( P_{i+1} \) 的边以及下一条由 \( P_{i+1} \) 到 \( P_{i+2} \) 组成的边。这两条边分别对应方向向量: \[ V_1 = (P_{i+1}.x - P_i.x, P_{i+1}.y - P_i.y) \] \[ V_2 = (P_{i+2}.x - P_{i+1}.x, P_{i+2}.y - P_{i+1}.y) \] 接着计算这两个向量的二维叉积(也称为外积),即: \[ CrossProduct(V_1,V_2)=V_{1_x}\times V_{2_y}-V_{1_y}\times V_{2_x} \][^1] 当上述表达式的值大于零时,表示当前考察的角度小于180度,意味着这是一个内角较小的情况,因此该处表现为“凸”。反之,若结果小于零,则说明角度超过180度,“”的特显现出来;等于零则代表两直线共线或平行。 下面给出一段简单的Python代码实现这一逻辑: ```python def is_convex(p1, p2, p3): """ Determine whether the angle formed by three points forms a convex or concave corner. Args: p1, p2, p3: Three consecutive vertices of polygon as tuples/lists with two elements each Returns: bool: True if it's a convex turn; False otherwise """ v1 = (p2[0]-p1[0], p2[1]-p1[1]) v2 = (p3[0]-p2[0], p3[1]-p2[1]) cross_product = v1[0]*v2[1] - v1[1]*v2[0] return cross_product >= 0 ``` 此函数接收三个参数作为输入——构成待测转角的三坐标,并返回布尔类型的输出指示给定序列形成的转向质。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值