如何用NumPy生成指定三角形内的随机点?如何过滤已生成的正方形点阵?
用NumPy快速筛选目标三角形内的随机点
判断逻辑
凸多边形的核心性质就是,内部区域是所有相邻边分割出的半平面的交集,所以只要点满足所有边的同侧条件,就一定落在多边形内部。你不需要逐点写循环判断,直接靠NumPy的广播能力生成布尔掩码,就能一次性完成全部点的筛选。
先理清楚目标三角形(顶点为(0,0)、(0,1)、(1, 0.5))对应的三个半平面约束:
- 连接(0,0)和(0,1)的边是x=0的竖直线,三角形位于x≥0的一侧——你用
np.random.rand生成的正方形随机点本身就在x∈[0,1)、y∈[0,1)的范围内,天然满足这个条件,不需要额外判断。 - 连接(0,0)和(1, 0.5)的边,直线方程为
y = 0.5x,三角形在这条线的上方,也就是需要满足y >= 0.5x。可以用剩下的顶点(0,1)代入验证:1 >= 0.5*0,确实在这个半平面内。 - 连接(0,1)和(1, 0.5)的边,直线方程为
y = -0.5x + 1,三角形在这条线的下方,也就是需要满足y <= -0.5x +1。同样用剩下的顶点(0,0)代入验证:0 <= -0.5*0 +1,确实在这个半平面内。
实现代码
在你现有代码的基础上追加几行筛选逻辑即可,全程没有Python层的循环,执行效率很高:
import numpy as np # 你原本生成正方形随机点的代码 pts = np.random.rand(1000, 2) # 拆分所有点的x、y坐标 x_coords = pts[:, 0] y_coords = pts[:, 1] # 按两个半平面条件生成布尔掩码 mask_below_bc = y_coords <= (-0.5 * x_coords + 1) mask_above_ac = y_coords >= 0.5 * x_coords # 合并两个掩码,两个条件同时满足的点才属于三角形 in_triangle_mask = mask_below_bc & mask_above_ac # 筛选得到三角形内的随机点 triangle_pts = pts[in_triangle_mask]
补充说明
- 目标三角形的面积是0.5,对比它覆盖的单位正方形面积为1,大概会有50%的随机点被保留,没有明显的生成浪费,这种筛选方案的整体效率是够用的。
- 如果之后遇到位置不这么规整的三角形,可以直接用通用的叉积法做矢量化判断:对三角形的每条边,计算边向量、点到边端点的向量的叉积,所有叉积符号一致的点就位于三角形内部,原理和这次的半平面判断完全一致。
- 因为是连续随机生成的浮点数,刚好落到三角形边上的概率几乎为0,所以用带等号的不等式判断不会出现边界误判的问题。
内容的提问来源于stack exchange,提问作者Dan Grahn
相关产品推荐
相关产品推荐

