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
相关产品推荐
相关产品推荐

