简介
Hamal 是一份 Python 3 脚本,可将点集、无向图、曲线、矢量场、网格曲面等三维几何数据转化为 POV-Ray 场景文件。也就是说,Hamal 不生产数据,也不负责图形渲染,它只能算是一个数据格式转换器,面向对 POV-Ray 有一些了解并且希望使用 POV-Ray 对上述三维几何图形进行光线追踪渲染的人。
安装
$ git clone https://github.com/liyanrui/hamal.git
$ cd hamal
$ chmod +x hamal
$ sudo install hamal /usr/local/bin
点集
待渲染的三维点集数据应当存储在 ASCII 编码的文本文件中,并且文件的每一行文本都是三维点坐标的字面值,例如:
1.2 3.3 5.4
0.1 2.2 8.5
... ... ...
现在假设三维点集数据文件为 foo.asc,通过以下命令可将其转换为 POV-Ray 场景文件 foo.pov 与 foo.inc:
$ hamal foo.asc
这条命令会在当前目录生成 foo.pov 与 foo.inc,前者为视图文件,后者为 POV-Ray 模型文件,使用 povray 命令可基于 foo.pov 与 foo.inc 对点集进行渲染:
$ povray foo.pov
渲染结果为当前目录下的位图文件 foo.png。例如:
Hamal 默认的点的尺寸是 0.0025,下面这条命令可将其设置为 0.005:
$ hamal --point-size=0.005 foo.asc
再次使用 povray 处理新生成的 foo.png,结果可得:
注:事实上,当点的尺寸设为 x 时,点在 POV-Ray 中的实际尺寸是 x * r,r 为点集近似最小外接球的半径。
点集是下文所述的无向图、矢量场以及网格的「实体」。
无向图
对于点集数据文件 foo.asc,假设我们算出了它对应点集的欧几里得最小支撑树(EMST)——EMST 是树,也是无向图。假设 EMST 的数据被保存到 foo-graph.asc 文件,该文件的每一行都是 EMST 的一条边的两个端点,只不过存储的不是点坐标,而是 foo.asc 文件中对应点坐标的行号,只不过 foo.asc 第一行的行号从 0 开始。将 foo.asc 视为 C 语言中的 n 行 3 列的二维数组可能会更好理解一些。例如:
0 1
1 15677
15677 12881
12881 12849
... ...
要绘制无向图,在将无向图数据转换为 POV-Ray 的过程中,需要载入点集数据文件与无向图数据文件:
$ hamal --graph=foo-graph.asc foo.asc
然后使用 povray 对新的 foo.pov 进行处理,便可得到 EMST 的渲染结果:
结果似乎与上文所示的点集模型的渲染结果差不多,这实际上是因为点集非常密集所致。若修改 foo.pov,让相机距离点集更近一些,便可以看清 EMST 的局部分支。
打开 foo.pov,将
camera {
location <0, 0, -2 * model_radius> + model_center * z
look_at <0, 0, 0>
translate view_center
}
修改为:
camera {
location model_center * z
look_at <0, 0, 0>
translate view_center
}
上述修改,意味着将相机沿 z 轴正方向移动了 2 * model_radius 个单位,即让相机重复靠近 EMST。重新用 povray 处理 foo.pov,可得:
点的尺寸与先的宽度似乎太大了一些,可以将它们设置的小一些,可以在使用 hamal 生成 POV-Ray 场景文件时将它们的尺寸设置的小一些,例如:
$ hamal --graph=foo-graph.asc --point-size=0.001 --line-width=0.0005 foo.asc
结果可得:
曲线
将一条曲线离散化处理,形成一组首尾相连的线段,这样就可以构成无向图,然后利用上一节渲染无向图的方法进行曲线的渲染。
下图是一条 3 次 Bezier 曲线的渲染结果:
矢量场
矢量场,就是一组矢量,这组矢量的起点即上文所述的点集文件,例如 foo.asc,而它们的终点存储在矢量场文件中,例如 foo-vector-field.asc。矢量场文件的格式与点集文件相同。
下面的命令可以将矢量场转化为 POV-Ray 场景文件:
$ hamal --vector-field=foo-vector-field.asc --point-size=0.001 --line-width=0.0005 foo.asc
像上一节那样修改 foo.pov 文件,拉近相机与模型之间的距离,结果可得:
网格
为了便于演示,下面的命令使用了 qhull 为一组随机点集构建了凸包,然后将凸包数据(三角网格文件)转换为 POV-Ray 场景文件并交由 povray 进行渲染:
$ rbox 100 W0 > points.asc
$ qhull QJ i < points.asc TO hull.asc
$ sed -i '1,2d' points.asc
$ sed -i '1d' hull.asc
$ hamal --object=hull --mesh=hull.asc --point-size=0.03 points.asc
$ povray +P hull.pov
hamal 的 --object
选项用于设定 POV-Ray 模型的文件名(不包含扩展名)。
结果可得到如下图所示的渲染结果:
内幕
见「Python 邂逅 POV-Ray」与「趴边去!」。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。