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 的渲染結果:
結果彷佛與上文所示的點集模型的渲染結果差很少,這其實是由於點集很是密集所致。若修改 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」與「趴邊去!」。