Hamal 指南

逻辑撷星使
• 阅读 4219

简介

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 指南

Hamal 默认的点的尺寸是 0.0025,下面这条命令可将其设置为 0.005:

$ hamal --point-size=0.005 foo.asc

再次使用 povray 处理新生成的 foo.png,结果可得:

Hamal 指南

注:事实上,当点的尺寸设为 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 的渲染结果:

Hamal 指南

结果似乎与上文所示的点集模型的渲染结果差不多,这实际上是因为点集非常密集所致。若修改 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 指南

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

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

结果可得:

Hamal 指南

曲线

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

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

Hamal 指南

矢量场

矢量场,就是一组矢量,这组矢量的起点即上文所述的点集文件,例如 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 文件,拉近相机与模型之间的距离,结果可得:

Hamal 指南

网格

为了便于演示,下面的命令使用了 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 模型的文件名(不包含扩展名)。

结果可得到如下图所示的渲染结果:

Hamal 指南

内幕

见「Python 邂逅 POV-Ray」与「趴边去!」。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Easter79 Easter79
3年前
SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
首先在shiro配置类中注入rememberMe管理器!复制代码(https://oscimg.oschina.net/oscnet/675f5689159acfa2c39c91f4df40a00ce0f.gif)/cookie对象;rememberMeCookie()方法是设置Cookie的生成模
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(