You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Numpy:基于顶点选取任意凸形区域的实现方案求助

嘿,你说的没错,numpy本身确实没有直接支持任意凸多边形索引的原生功能,但完全不用退回到Python循环!有几个高效又简洁的办法能解决这个问题,我给你详细说说:

方法一:用matplotlib.path快速生成掩码

matplotlib的Path类专门用来处理多边形路径,它的contains_points方法可以批量判断大量点是否在多边形内部,底层是C实现,效率非常高,而且支持任意凸(甚至非凸)多边形,完全符合你的需求。

代码示例(对应你给出的10x10数组和顶点):

import numpy as np
from matplotlib.path import Path

# 定义凸多边形顶点(顺序可以是顺时针或逆时针)
vertices = np.array([(2, 2), (6, 3), (4, 8), (7, 9)])
# 创建初始零数组
arr = np.zeros((10, 10))

# 生成数组所有位置的坐标网格
y_coords, x_coords = np.meshgrid(np.arange(arr.shape[0]), np.arange(arr.shape[1]))
# 将网格坐标转换为N×2的点数组(每个元素是(x,y))
all_points = np.vstack((x_coords.ravel(), y_coords.ravel())).T

# 创建Path对象并判断点是否在多边形内
polygon_path = Path(vertices)
mask = polygon_path.contains_points(all_points).reshape(arr.shape)

# 应用掩码,将区域设为1
arr[mask] = 1

print(arr)

运行这段代码就能得到你想要的掩码数组,而且处理大尺寸数组时,速度远快于Python循环。

方法二:纯numpy实现凸多边形点内判断

如果不想依赖matplotlib,可以利用凸多边形的几何性质:凸多边形内部的所有点,都在每条边的同一侧(比如逆时针排列的顶点,所有内部点在每条边的左侧)。我们可以通过向量叉积来判断点的位置,并用numpy的向量化操作批量处理所有点。

代码示例:

import numpy as np

def point_in_convex_polygon(points, vertices):
    """判断一组点是否在凸多边形内(顶点需按顺时针/逆时针顺序排列)"""
    # 闭合多边形(将第一个顶点追加到末尾)
    closed_vertices = np.vstack([vertices, vertices[0]])
    # 初始化掩码为全True
    mask = np.ones(len(points), dtype=bool)
    
    for i in range(len(closed_vertices) - 1):
        v1, v2 = closed_vertices[i], closed_vertices[i+1]
        # 计算叉积:(v2 - v1) × (point - v1)
        cross_product = (v2[0] - v1[0]) * (points[:, 1] - v1[1]) - \
                        (v2[1] - v1[1]) * (points[:, 0] - v1[0])
        # 凸多边形内部点的叉积符号一致(这里假设顶点是逆时针排列,取>=0)
        mask &= cross_product >= 0
    
    return mask

# 测试代码
vertices = np.array([(2, 2), (6, 3), (4, 8), (7, 9)])
arr = np.zeros((10, 10))

y_coords, x_coords = np.meshgrid(np.arange(arr.shape[0]), np.arange(arr.shape[1]))
all_points = np.vstack((x_coords.ravel(), y_coords.ravel())).T

mask = point_in_convex_polygon(all_points, vertices).reshape(arr.shape)
arr[mask] = 1

print(arr)

这个方法不需要额外依赖,但要注意顶点必须按顺时针或逆时针顺序排列(不能乱序),否则判断会出错。不过你已经明确说明是凸形,只要保证顶点顺序正确就没问题。

总结

两种方案都能高效解决你的问题:

  • 要是项目里已经用到matplotlib,第一种方法最省心,代码简洁且兼容性好;
  • 要是不想引入新依赖,第二种纯numpy实现的方案也能搞定,而且因为用了numpy向量化操作,速度比Python循环快几个数量级。

内容的提问来源于stack exchange,提问作者Skum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:15:48