首页/文章/ 详情

随机形状,一条命令造一箱碎石

1天前浏览9

先说结论:把"碎石形状"做成三个旋钮——圆度、棱角、长宽比。拧一下,一条命令生成一箱石头:2D 出多边形,3D 出三角网格,产物是纯 ASCII 的 .dat,跑一次 PFC 就得到 gravel_1..N 这一组 geometry set。文末有命令。

1. PFC 里的颗粒,凭什么都是圆的

PFC 自带的成样命令,生出来的是圆盘(2D)和球(3D)。

用圆盘做砂土、做堆石,最大的问题是滚动性太强——颗粒之间没有咬合,抗剪强度全靠摩擦系数硬撑,剪胀也出不来。

真实碎石不是圆的。棱角会互相卡住;长条形的会定向排列;扁平的在压力下会翻面。这些都会改变配位数、剪胀量和峰值强度。

那手搓形状行不行?画 20 个不重样的石头轮廓,画完还得算面积、算球度、检查有没有自交、确保能塞进模具。画完一批,参数一改又得重来。

所以要参数化生成。

2. 先看货

alt  

图1 2D 成品:24 颗碎石多边形,一条命令生成。颗粒大小是随机的(半径 0.35–0.65),形状也是随机的,但整体风格由参数统一控制。

alt  

图2 3D 成品:12 颗碎石三角网格,每颗 320 个面。它和图1 是同一套形貌参数——2D 与 3D 是同一个抽象的两个载体。

产物是一个纯 ASCII 的 .dat 文件,每个形状的顶点/面片坐标都已经算好、烘进去了。丢给 PFC 控制台跑一遍,模型里就多出 gravel_1 到 gravel_N 一组 geometry set。

拿来干什么:形状库、墙体的几何来源、DFN 的母体、clump 模板的底座,或者纯粹当个底图。

3. 2D 是怎么做出来的

原理一句话:圆的半径处处相等,那就让半径随角度变一变。


  1. 数学写法:r(θ) = R · (1 + Σ a_k · cos(k·θ + φ_k))
  2. 白话版:把半径按角度画成一条波浪线,再让这条线绕一圈描出轮廓。

公式里的 k 是"这层波浪有几个波峰"。k=2 把圆拉成椭圆,k=3 出三角状起伏,k 越大越细碎。

alt  

图3 2D 原理:同一组系数,从只有 k=2 一路加到 k=6,轮廓从椭圆变成碎石。虚线是原始基圆。

实际生成时,每一阶的幅值 a_k 和相位 φ_k 都是随机抽的。相位决定"鼓包鼓在哪一边",所以每颗石头的朝向和凹凸位置都不一样。

抽的规则决定了手感:


  • 圆度控制波浪的"总高度预算"。圆度低,预算大,石头不规则。
  • 棱角控制这些预算怎么分给高低频。棱角高,预算往高频倾斜,出来就是尖角。
  • 长宽比是硬拉伸:先把单位圆按长轴拉长,再叠波浪。

4. 3D 是怎么做出来的

3D 的思路一模一样,只是"角度"从一个变成球面上的两个,"波浪"换成球谐函数。

但有个细节值得单说:球面网格怎么铺。

最直觉的做法是经纬网格,像地球仪。问题是两极会挤成一堆退化的三角形,顶点分布极不均匀,球谐采样会出现方向偏差——南北极附近的形状容易失真。

所以用的是细分二十面体:从一个正二十面体起步,每个三角面切成四个,重复几轮。

alt  

图4 3D 原理:正二十面体(20 面)→ 细分一次(80 面)→ 细分两次(320 面,默认)→ 再把每个顶点的半径按球谐函数揉乱,就成了碎石。

好处是顶点在球面上分布均匀,没有极点问题。PFC 自带的 geometry generate sphere 也是这么干的。

alt  

图5 生成器自带一个零依赖的 HTML 预览器:拖拽旋转、滚轮缩放、切线框,双击就能开,不用装任何东西。批量生成前先看一眼形状对不对,比跑完 PFC 再发现问题省事。

5. 三个旋钮

alt  

图6 三个形貌旋钮,每个扫四个取值。注意一件事:每一行的四个形状是同一颗石头——参数变了,石头没换。这个性质为什么成立,后面单独讲。

怎么选:


  • 想要碎石感:圆度 0.3、棱角 0.7(3D 用 1.0)、长宽比 1.5
  • 想要河卵石:圆度 0.8、棱角 0.2、长宽比 1.2

3D 的默认值(圆度 0.4 / 棱角 0.6)是个"安全默认",球度高达 0.94,看着像打磨过的卵石。要碎石感就把棱角和谐波阶数都拉上去。

6. 拧了到底会怎样

下面三条是固定 seed、单因子扫描的实测,2D 与 3D 用同一套参数。球度是"离正球有多远"的量化指标,1.0 就是正球。

alt  

图7 圆度是总开关:2D 球度 0.93→0.96,3D 0.94→0.98,两边单调变圆。

alt  

图8 棱角几乎不动球度:3D 从 0.949 到 0.943,基本是一条平线。这不是"没效果"——棱角把细节塞进高频,总幅值预算没变,所以球度不动,但形状明显更方更尖(对比图6第二行)。

alt  

图9 长宽比才是球度的真正主控。上图:从 1.0 拉到 2.0,2D 球度从 0.98 掉到 0.83。下图:拧多少出来多少,2D 基本是 1:1 ——输入 1.6,实测 1.62。

下图中 3D 那条线系统性低于 1:1,这是口径差异不是形状差异:3D 量的是任意方向的三轴包围盒,不是旋转对齐后的主轴。同样的形状换把尺子,数就低了。

7. 一个意外好用的性质

这一条是最近测试才确认的,我觉得比上面所有参数都值钱。

固定 seed 之后,改圆度 / 棱角 / 长宽比,形状不会被重新抽签。

alt  

图10 同一个 seed,圆度从 0.2 调到 0.4、0.8。变的只是"平滑度",这三组轮廓和网格是同一颗石头。

换句话说是:参数动的是"化妆",不是"换人"。

为什么?随机数只在决定每一阶谐波的幅值和相位时消耗。而圆度只改总幅值预算、棱角只改高频权重、长宽比只改 k=2 那一阶的幅值——三个都作用在系数上,不碰随机数流。

这件事的意义是可以做配对试验。以前扫参只能比统计量(平均球度、平均长宽比),因为每一档的形状都是新抽的,两组之间的差异里混着随机噪声,样本量不够就看不出小效应。现在固定 seed 逐颗对比,同一颗石头的"前后照"摆在一起看。

有个例外:改 --count 会洗牌。因为布局和形状生成共用同一条随机流,而布局先跑。想连 count 也不洗牌,用 --layout grid 布局。

8. 一个不报警的坑

生成形状时要往域里摆位置。摆不下怎么办?

grid 布局是等距排,间距按最大半径算,但长宽比会把颗粒沿长轴拉出去,两者不联动;random 布局则是尝试若干次之后强行放下去。

结果就是形状会真的叠在一起,而且什么都不报。 生成器不报,PFC 也不报。

alt  

图11 A 是摆得开的:24 颗,最紧的地方还剩 0.033 的缝(约颗粒半径的 7%)。B 是 40 颗硬塞进 4×4 域:158 对真的糊在一起。

拿这种重叠的形状去做 clump 模板或者墙体,问题要到模型里才暴露——而那时候你已经不知道是形状的锅还是接触参数的锅。

所以现在生成器自己会查:算完所有形状两两之间的最短间距,发现接触就打一行 [warn],同时写进 .dat 的头部注释。看到输出里是 placement ok 才算过关。3D 那边用的是顶点到三角面的距离,比包围盒判断准得多。

顺带一提,文档里原来的示例命令(random 布局 + 30 颗 + 长宽比 1.6)本身就产出 2 对重叠,也是这次测试发现的,已经改成 grid 了。

9. 怎么用

bash# 2D:24 颗碎石多边形
python gen_gravel.py \
  --count 24 --r-mean 0.5 \
  --roundness 0.3 --angularity 0.7 --aspect 1.5 \
  --layout grid --domain=-5,5,-4,4 --seed 10001 \
  --out gravels.dat

# 3D:12 颗,每颗 320 个三角面
python gen_gravel3d.py \
  --count 12 --r-mean 0.5 \
  --roundness 0.3 --angularity 1.0 --n-harmonics 8 --aspect 1.5 \
  --domain=-8,8,-8,8,-8,8 --seed 10001 \
  --out gravel3d.dat

# 进 PFC(3D 要加 --3d)
python run_pfc.py gravels.dat
python run_pfc.py gravel3d.dat --3d

跑完看两件事:生成器最后一行是不是 placement ok;PFC 日志里 geometry list 的行数对不对得上 --count。

10. 最后

这些东西不复杂:2D 用傅里叶描述符,3D 用球谐加细分二十面体,都是几十年前就有的数学。

价值在于打包成"三个旋钮加一条命令",让做 DEM 的人不用自己去推公式、写网格、查自交。形状参数化之后,圆度、棱角、长宽比这些能对应到地质描述的量就可以直接扫参了——磨圆度不同的砂、棱角不同的碎石,都能拿同一套流程做出来对比。

VibePFC 社区 · 一起把 AI 玩进 PFC
我成立了一个 VibePFC 社群,专门聊 AI 怎么落地到 PFC / 数值模拟——让大模型读懂模型、自己改脚本、自动排查"看不懂"的问题。收一个 50 元的门槛费。
想进群的同学,加 QQ 763388012,备注"vibePFC"即可。

11. 参考资料


  • 形状生成技能 pfc-gravel-shape:2D 傅里叶描述符 + 3D 球谐与细分二十面体,产物为纯 ASCII 的 geometry 脚本
  • 完整测试报告与全部配图数据:本项目 随机形状技能测试/随机形状技能测试报告.html

来源:超级大的lobby
pythonUMPFC控制试验模具
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-09-30
最近编辑:1天前
lobby
硕士 | 无 擅长颗粒流PFC
获赞 963粉丝 5921文章 88课程 23
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈