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

  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))

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值