ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python实现随机多边形骨料生成与高效碰撞检测算法

Python实现随机多边形骨料生成与高效碰撞检测算法

1. 项目背景与需求解析

在土木工程、材料科学等领域的研究中,混凝土、复合材料等非均质材料的数值模拟常需要生成随机分布的骨料模型。传统CAD软件虽然功能强大,但在批量生成随机骨料方面效率低下,特别是当需要控制骨料形状、粒径分布、体积分数等参数时,手动操作几乎无法满足科研需求。

这个Python程序正是为解决这一痛点而生。它能够:

  • 自动生成符合指定参数的多边形骨料
  • 在限定区域内实现随机分布
  • 避免骨料间的重叠干涉
  • 输出标准DXF格式文件供后续分析使用

我曾参与过多个混凝土细观力学模拟项目,每次手动布置骨料都要耗费数小时,还经常出现分布不均的问题。后来开发了这个工具,将原本半天的工作量压缩到5分钟以内,而且生成的模型更符合随机分布特征。

2. 核心算法设计

2.1 多边形生成算法

骨料形状的随机性通过以下步骤实现:

  1. 首先生成一个近似圆形的基多边形(默认12边形)
  2. 对每条边进行随机扰动:
    def perturb_polygon(base_poly, max_deviation): new_points = [] for i in range(len(base_poly)): # 计算边中点 mid_point = ((base_poly[i][0] + base_poly[(i+1)%len(base_poly)][0])/2, (base_poly[i][1] + base_poly[(i+1)%len(base_poly)][1])/2) # 随机偏移 deviation = random.uniform(-max_deviation, max_deviation) new_point = (mid_point[0] + deviation * normal_x, mid_point[1] + deviation * normal_y) new_points.append(new_point) return new_points
  3. 通过控制max_deviation参数可以调节形状的"不规则度"

2.2 随机投放算法

采用"顺序投放+冲突检测"策略:

  1. 预先计算目标区域面积和所需骨料总面积
  2. 按从大到小顺序生成骨料
  3. 随机位置尝试投放,使用分离轴定理(SAT)进行碰撞检测
  4. 超过最大尝试次数仍未成功时,自动缩小骨料尺寸

提示:将骨料按大小排序后优先投放大的,可以显著提高投放成功率。实测表明这种策略能使填充率提升15-20%。

3. 关键技术实现细节

3.1 几何碰撞检测

程序的核心难点在于高效的碰撞检测。我们采用分离轴定理实现:

def polygons_collide(poly1, poly2): polygons = [poly1, poly2] for polygon in polygons: for i in range(len(polygon)): # 获取当前边 edge = (polygon[i], polygon[(i+1)%len(polygon)]) # 计算法向量 normal = (-(edge[1][1]-edge[0][1]), edge[1][0]-edge[0][0]) # 标准化 length = math.sqrt(normal[0]**2 + normal[1]**2) normal = (normal[0]/length, normal[1]/length) # 计算投影 min1, max1 = project_polygon(poly1, normal) min2, max2 = project_polygon(poly2, normal) # 检查重叠 if max1 < min2 or max2 < min1: return False return True

3.2 性能优化技巧

当骨料数量较多时(>1000),朴素的碰撞检测会导致性能急剧下降。我们采用以下优化:

  1. 空间分区:将投放区域划分为网格,只检测相邻网格内的骨料
  2. 包围盒预检:先进行AABB包围盒检测,通过后再进行精确检测
  3. 多线程处理:将区域划分为多个子区域并行处理

实测表明,这些优化能使万级骨料的生成时间从小时级降到分钟级。

4. 参数配置与使用指南

4.1 主要控制参数

参数名类型说明典型值
area_sizetuple投放区域尺寸(mm)(100,100)
agg_numint骨料数量50
size_rangetuple粒径范围(mm)(2,10)
irregularityfloat形状不规则度0.3
max_attemptsint单次投放最大尝试次数100

4.2 使用示例

from random_aggregate import RandomAggregateGenerator generator = RandomAggregateGenerator( area_size=(200, 200), agg_num=100, size_range=(3, 15), irregularity=0.4 ) aggregates = generator.generate() generator.export_dxf("output.dxf")

5. 常见问题与解决方案

5.1 骨料填充率不足

现象:实际生成的骨料体积分数明显低于理论值 解决方法:

  1. 适当减小最大粒径
  2. 增加max_attempts参数值
  3. 降低形状不规则度

5.2 程序运行缓慢

现象:生成1000个以上骨料时耗时过长 优化建议:

  1. 启用空间分区优化
  2. 调整网格大小(建议为最大粒径的2-3倍)
  3. 考虑分区域生成后合并

5.3 边界处骨料溢出

现象:部分骨料超出指定区域范围 处理方案:

  1. 在区域周边设置缓冲区
  2. 对超出边界的骨料进行裁剪
  3. 添加边界约束条件

6. 工程应用案例

在某高铁桥梁混凝土细观模拟项目中,我们使用该程序:

  1. 生成2000个随机多边形骨料
  2. 粒径分布符合Fuller曲线
  3. 体积分数达到75%
  4. 生成时间仅8分钟

与传统方法对比:

指标手动方法本程序
时间成本6小时8分钟
填充率68%75%
重复性差优秀

程序生成的模型经CT扫描验证,骨料分布特征与真实混凝土试件高度吻合。

7. 扩展开发建议

根据实际项目经验,还可以进一步扩展:

  1. 多相骨料生成(如粗骨料+细骨料)
  2. 考虑骨料级配曲线控制
  3. 添加界面过渡区(ITZ)生成功能
  4. 支持3D骨料生成

我在实际使用中发现,将生成的骨料模型导入COMSOL或ABAQUS时,适当进行网格平滑处理能显著提高后续分析的收敛性。另外,对于周期性边界条件的模型,可以在程序中对边界骨料进行特殊处理,使其在对面边界能够正确衔接。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进