第4章 几何物体建模:标准几何体与布尔运算
好,我们进入非序列光线追迹的实操第一步——建物体。
很多人觉得建模不就是画个球、拉个方块嘛,有什么好讲的?
但我在项目里见过太多人,因为一个圆柱体的方向没搞对,追迹结果差了十万八千里。或者布尔运算切错了顺序,整个系统得重来。
这一章,咱们就把标准几何体和布尔运算彻底讲透。
4.1 标准几何体:球体、立方体、圆柱体
Code V 的非序列模式下,几何体是通过 OBJECT 命令配合 TYPE 参数来定义的。我习惯先把物体类型想清楚,再填参数,这样不容易乱。
4.1.1 球体(Sphere)
球体是最简单的。你只需要一个球心位置和半径。
! 创建一个半径为 10 mm 的球体,球心在 (0,0,0)
OBJECT 1
TYPE SPHERE
RADIUS 10.0
POSITION 0.0 0.0 0.0
END
这里有个坑:球体的表面法线方向默认朝外。如果你想让光线从球内部射向表面(比如模拟气泡),需要把法线反转。我当年做微透镜阵列时,就因为这个搞反了,追迹结果全是全反射,折腾了一下午。
RADIUS 不能为负值。如果需要凹面效果,请使用 TYPE SPHERE 配合 REVERSE 关键字。
4.1.2 立方体(Box)
立方体需要定义三个方向的尺寸:X、Y、Z 方向的半边长。
! 创建一个 20x10x5 mm 的长方体,中心在 (0,0,0)
OBJECT 2
TYPE BOX
X_HALF 10.0
Y_HALF 5.0
Z_HALF 2.5
POSITION 0.0 0.0 0.0
END
注意,这里给的是半边长,不是全长。很多新手直接填全长,结果物体比预期大一倍。我建议你在注释里写清楚「全长=20」,免得回头自己都忘了。
4.1.3 圆柱体(Cylinder)
圆柱体稍微复杂一点。除了半径和长度,你还要指定它的轴向。
! 创建一个半径为 5 mm、长度为 20 mm 的圆柱体,轴向为 Z
OBJECT 3
TYPE CYLINDER
RADIUS 5.0
LENGTH 20.0
DIRECTION 0.0 0.0 1.0
POSITION 0.0 0.0 -10.0
END
DIRECTION 是单位向量,表示圆柱的轴线方向。我习惯把圆柱的起点放在 POSITION,然后沿 DIRECTION 延伸 LENGTH。这样定位比较直观。
TYPE CONE,参数类似,只是多了一个顶部半径。
4.2 参数设置的核心逻辑
其实所有标准几何体的参数设置,都遵循一个共同逻辑:位置 + 形状 + 方向。我整理了一个对照表,方便你快速查阅。
| 几何体 | 位置参数 | 形状参数 | 方向参数 |
|---|---|---|---|
| 球体 | POSITION (x,y,z) | RADIUS | 无(各向同性) |
| 立方体 | POSITION (x,y,z) | X_HALF, Y_HALF, Z_HALF | 无(默认与坐标轴对齐) |
| 圆柱体 | POSITION (x,y,z) | RADIUS, LENGTH | DIRECTION (dx,dy,dz) |
| 圆锥体 | POSITION (x,y,z) | RADIUS1, RADIUS2, LENGTH | DIRECTION (dx,dy,dz) |
你想想看,只要掌握了这个逻辑,任何标准几何体都能快速上手。说白了就是三个问题:放哪?多大?朝哪?
4.3 布尔运算:合并与切割
单个几何体太简单了,实际光学系统里很少有纯粹的球或方块。你需要把多个几何体组合起来——这就是布尔运算。
Code V 的布尔运算通过 COMPOSITE 物体类型来实现。支持三种操作:UNION(合并)、INTERSECTION(交集)、SUBTRACTION(切割)。我们重点讲合并和切割,因为这两个最常用。
4.3.1 合并(UNION)
合并就是把两个或多个物体粘在一起,变成一个整体。光线追迹时,Code V 会把它们当作一个物体来处理。
! 创建一个复合物体:球体 + 圆柱体
OBJECT 10
TYPE COMPOSITE
OPERATION UNION
OBJECT 1 ! 球体
OBJECT 3 ! 圆柱体
END
合并时要注意:两个物体的材料必须相同。如果材料不同,Code V 会报错。我遇到过有人想把玻璃透镜和金属支架合并,结果怎么都跑不通——后来才意识到,不同材料不能合并,得用多个物体分别定义。
4.3.2 切割(SUBTRACTION)
切割是从一个物体中挖掉另一个物体。这个在建模透镜、棱镜、反射镜时特别有用。
! 从立方体中挖掉一个球体,形成一个凹坑
OBJECT 20
TYPE COMPOSITE
OPERATION SUBTRACTION
OBJECT 2 ! 被切割的物体(立方体)
OBJECT 1 ! 切割工具(球体)
END
这里有个顺序问题:第一个物体是被切的,第二个是切刀。搞反了的话,你会得到一个空壳子。我曾经在做一个非球面透镜的挖槽时,顺序写反了,追迹结果全是零,查了半天才发现是布尔运算的顺序错了。
4.4 布尔运算的避坑指南
布尔运算看起来简单,但实际用起来坑不少。我总结了几条经验,你记一下。
- 物体必须相交:如果两个物体没有重叠区域,合并就是两个独立物体,切割则无效。Code V 不会报错,但结果不是你想要的。
- 避免零厚度:切割时,如果切刀刚好与被切物体表面相切,会产生零厚度的边缘。这会导致追迹时出现数值不稳定。我建议让切刀稍微深入一点。
- 嵌套限制:Code V 允许布尔运算嵌套,比如先合并再切割。但嵌套层数太多时,计算会变慢。我一般控制在 3 层以内。
- 调试方法:如果布尔运算结果不对,先用
DRAW命令看看物体形状。可视化是最直接的调试手段。
4.5 知识体系图
下面这张图把本章的核心逻辑串起来了。你可以把它当作一个快速索引。
4.6 实战案例:做一个简单的透镜模型
光说不练假把式。我们用一个实际案例把今天的内容串起来。
假设你要做一个平凸透镜:一面是平面(立方体切出来的),一面是球面。怎么做?
- 创建圆柱体:作为透镜的基底,半径 10 mm,厚度 5 mm。
- 创建球体:半径 20 mm,球心位置在圆柱体上方 15 mm 处(这样球面刚好凸出来)。
- 布尔运算切割:用球体去切圆柱体,得到凸面。
- 再切一次:用另一个平面(大立方体)切掉多余的部分,得到平的面。
! 步骤1:圆柱体基底
OBJECT 1
TYPE CYLINDER
RADIUS 10.0
LENGTH 5.0
DIRECTION 0.0 0.0 1.0
POSITION 0.0 0.0 -2.5
END
! 步骤2:球体(切割工具)
OBJECT 2
TYPE SPHERE
RADIUS 20.0
POSITION 0.0 0.0 15.0
END
! 步骤3:第一次切割,得到凸面
OBJECT 3
TYPE COMPOSITE
OPERATION SUBTRACTION
OBJECT 1
OBJECT 2
END
! 步骤4:平面切割工具(大立方体)
OBJECT 4
TYPE BOX
X_HALF 20.0
Y_HALF 20.0
Z_HALF 10.0
POSITION 0.0 0.0 -12.0
END
! 步骤5:第二次切割,得到平面
OBJECT 5
TYPE COMPOSITE
OPERATION SUBTRACTION
OBJECT 3
OBJECT 4
END
嗯,这里要注意:第二次切割时,OBJECT 3 已经是复合物体了。Code V 允许复合物体作为被切割对象,但不能作为切割工具。所以这个流程是合法的。
DRAW OBJECT 1 看看形状对不对。别等到最后一步才发现中间错了,那时候改起来很麻烦。
好了,这一章的内容就到这里。标准几何体和布尔运算,是 Code V 非序列建模的基石。你把这些练熟了,后面做复杂系统就会顺手很多。