如何用NumPy在指定矩形内无重叠随机放置椭圆并获取参数
用NumPy在矩形内随机放置无重叠椭圆的实现方案
核心思路
采用尝试-验证策略实现无重叠放置:
- 先按面积占比需求生成所有椭圆的半轴参数
- 随机生成椭圆中心点,确保椭圆完全落在目标矩形边界内
- 检查新椭圆与已放置椭圆是否重叠,符合条件则保留
- 重复操作直到所有椭圆放置完成,或触发最大尝试次数避免死循环
完整实现代码
import numpy as np import math import random # 目标矩形参数:左下角(0,0),右上角(350,250) RECT_X_MIN, RECT_X_MAX = 0, 350 RECT_Y_MIN, RECT_Y_MAX = 0, 250 # 椭圆面积占比及半轴参数配置 Area_of_quad = (RECT_X_MAX - RECT_X_MIN) * (RECT_Y_MAX - RECT_Y_MIN) Af_ell = 0.4 # 椭圆总面积占矩形面积的比例 Area_of_Ell = Af_ell * Area_of_quad Ell_range_r1 = np.array([20, 12.5, 10]) Ell_range_r2 = np.array([0.6, 0.7, 0.8, 0.9]) # 修正原代码拼写错误 Area_of_ell_each = Area_of_Ell / len(Ell_range_r1) # 生成所有椭圆的半轴参数 rad = [] for i in range(len(Ell_range_r1)): area = Area_of_ell_each while area >= 0.01 * Area_of_ell_each: r1 = Ell_range_r1[i] r2 = random.choice(Ell_range_r2) * r1 Ar_ac = math.pi * r1 * r2 area -= Ar_ac rad.append([r1, r2]) # 轴对齐椭圆重叠检查函数 def is_overlapping(new_ell, existing_ells): new_x, new_y, new_r1, new_r2 = new_ell for ell in existing_ells: x, y, r1, r2 = ell dx = abs(new_x - x) dy = abs(new_y - y) # 保守判断规则:两椭圆外接矩形不重叠则椭圆必不重叠 if dx < (new_r1 + r1) and dy < (new_r2 + r2): return True return False # 随机放置椭圆 placed_ellipses = [] max_attempts_per_ellipse = 1000 # 单个椭圆最大尝试次数 for r1, r2 in rad: attempts = 0 placed = False while attempts < max_attempts_per_ellipse and not placed: # 生成合规中心点,确保椭圆完全在矩形内 x = random.uniform(RECT_X_MIN + r1, RECT_X_MAX - r1) y = random.uniform(RECT_Y_MIN + r2, RECT_Y_MAX - r2) new_ell = (x, y, r1, r2) # 检查重叠 if not is_overlapping(new_ell, placed_ellipses): placed_ellipses.append(new_ell) placed = True attempts += 1 if not placed: print(f"无法放置椭圆(r1={r1}, r2={r2}),已达最大尝试次数") # 提取结果数据 centers = np.array([(ell[0], ell[1]) for ell in placed_ellipses]) radii = np.array([(ell[2], ell[3]) for ell in placed_ellipses]) print("已放置椭圆的中心点:") print(centers) print("\n已放置椭圆的半轴参数(r1, r2):") print(radii)
关键细节说明
- 半轴参数生成:修正原代码拼写错误,按设定的面积占比分批次生成椭圆半轴组合。
- 重叠判断:采用外接矩形快速判断,兼顾效率与实用性;若需更高精度,可替换为基于椭圆距离公式的精确相交计算。
- 边界约束:生成中心点时直接限制范围,确保椭圆边缘不会超出矩形边界。
- 防死循环机制:设置单个椭圆的最大尝试次数,避免因剩余空间不足导致程序无限运行。
内容的提问来源于stack exchange,提问作者Saurabh Agarwal
相关产品推荐
相关产品推荐

