Hamal 指南

簡介

Hamal 是一份 Python 3 腳本,可將點集、無向圖、曲線、矢量場、網格曲面等三維幾何數據轉化爲 POV-Ray 場景文件。也就是說,Hamal 不生產數據,也不負責圖形渲染,它只能算是一個數據格式轉換器,面向對 POV-Ray 有一些瞭解而且但願使用 POV-Ray 對上述三維幾何圖形進行光線追蹤渲染的人。git

安裝

$ git clone https://github.com/liyanrui/hamal.git
$ cd hamal
$ chmod +x hamal
$ sudo install hamal /usr/local/bin

點集

待渲染的三維點集數據應當存儲在 ASCII 編碼的文本文件中,而且文件的每一行文本都是三維點座標的字面值,例如:github

1.2 3.3 5.4
0.1 2.2 8.5
... ... ...

如今假設三維點集數據文件爲 foo.asc,經過如下命令可將其轉換爲 POV-Ray 場景文件 foo.pov 與 foo.inc:segmentfault

$ hamal foo.asc

這條命令會在當前目錄生成 foo.pov 與 foo.inc,前者爲視圖文件,後者爲 POV-Ray 模型文件,使用 povray 命令可基於 foo.pov 與 foo.inc 對點集進行渲染:數組

$ povray foo.pov

渲染結果爲當前目錄下的位圖文件 foo.png。例如:ui

斯坦福兔子

Hamal 默認的點的尺寸是 0.0025,下面這條命令可將其設置爲 0.005:編碼

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

再次使用 povray 處理新生成的 foo.png,結果可得:spa

斯坦福兔子

注:事實上,當點的尺寸設爲 x 時,點在 POV-Ray 中的實際尺寸是 x * r,r 爲點集近似最小外接球的半徑。code

點集是下文所述的無向圖、矢量場以及網格的「實體」。blog

無向圖

對於點集數據文件 foo.asc,假設咱們算出了它對應點集的歐幾里得最小支撐樹(EMST)——EMST 是樹,也是無向圖。假設 EMST 的數據被保存到 foo-graph.asc 文件,該文件的每一行都是 EMST 的一條邊的兩個端點,只不過存儲的不是點座標,而是 foo.asc 文件中對應點座標的行號,只不過 foo.asc 第一行的行號從 0 開始。將 foo.asc 視爲 C 語言中的 n 行 3 列的二維數組可能會更好理解一些。例如:ip

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」與「趴邊去!」。

相關文章
相關標籤/搜索