Hamal 指南

简介

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 的渲染结果:

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,可得:

local emst

点的尺寸与先的宽度似乎太大了一些,可以将它们设置的小一些,可以在使用 hamal 生成 POV-Ray 场景文件时将它们的尺寸设置的小一些,例如:

$ hamal --graph=foo-graph.asc --point-size=0.001 --line-width=0.0005 foo.asc

结果可得:

local emst

曲线

将一条曲线离散化处理,形成一组首尾相连的线段,这样就可以构成无向图,然后利用上一节渲染无向图的方法进行曲线的渲染。

下图是一条 3 次 Bezier 曲线的渲染结果:

clipboard.png

矢量场

矢量场,就是一组矢量,这组矢量的起点即上文所述的点集文件,例如 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」与「趴边去!」。


5.9k 声望
1.9k 粉丝
0 条评论
推荐阅读
《Lua-in-ConTeXt》08:参数列表解析
\foo 接到的参数,并非真正的 Lua 表,而是一段文本 &quot;Hello&quot;, &quot;world&quot;, &quot;!&quot;。

garfileo

Ubuntu20.04 从源代码编译安装 python3.10
Ubuntu 22.04 Release DateUbuntu 22.04 Jammy Jellyfish is scheduled for release on April 21, 2022If you’re ready to use Ubuntu 22.04 Jammy Jellyfish, you can either upgrade your current Ubuntu syste...

ponponon1阅读 4k评论 1

日常Python 代码片段整理
1、简单的 HTTP Web 服务器 {代码...} 2、单行循环List {代码...} 3、更新字典 {代码...} 4、拆分多行字符串 {代码...} 5、跟踪列表中元素的频率 {代码...} 6、不使用 Pandas 读取 CSV 文件 {代码...} 7、将列表...

墨城2阅读 308

Unicode 正则表达式(qbit)
前言本文根据《精通正则表达式》和 Unicode Regular Expressions 整理。本文的示例默认以 Python3 为实现语言,用到 Python3 的 re 模块或 regex 库。基本的 Unicode 属性分类 {代码...} 基本的 Unicode 子属性Le...

qbit阅读 4.4k

Python + Sqlalchemy 对数据库的批量插入或更新(Upsert)
由于不同数据库对这种 upsert 的实现机制不同,Sqlalchemy 也就不再试图做一致性的封装了,而是提供了各自的方言 API,具体到 Mysql,就是给 insert statement ,增加了 on_duplicate_key_update 方法。

songofhawk1阅读 2k评论 4

封面图
打脸了兄弟们,Go1.20 arena 来了!
大家好,我是煎鱼。大概半年前,我写过一篇文章《Go 要违背初心吗?新提案:手动管理内存》。有兴趣了深入解的同学,可以再回顾一下。当时我们还想着 Go 团队应该不会接纳,至少不会那么快:懒得翻也可以看我再次...

煎鱼阅读 3.2k

uwsgi 注意事项
http 和 http-socket 选项是完全不同的。第一个生成一个额外的进程,转发请求到一系列的worker (将它想象为一种形式的盾牌,与apache或者nginx同级),而第二个设置worker为原生使用http协议。

zed2015阅读 2.2k

5.9k 声望
1.9k 粉丝
宣传栏