用 Python + POV-Ray 重現 Dimensions 視頻中的效果
在上一篇文章中,我介紹了如何使用 Python 製作演示各種圖演算法的 GIF 動圖,本文將介紹同一個項目下的另一個子項目:Todd-Coxeter 演算法和 4d 正多胞體。這個子項目還遠沒有完成,但是已經可以做出很棒的效果。本文將演示如何用這個子項目重現精彩的數學視頻
Dimensions中的效果。下圖是我從 Dimensions 官網上扒下來的封面:
大家可以比較一下本文的題圖的效果是否可以與這個封面的效果相媲美。下面的視頻是我用同樣的代碼生成的:
https://www.zhihu.com/video/983022263603404800接下來進入數學的部分。
1. 視頻中演示的是個什麼東西?
視頻里展示的是一個 4 維空間中的正多胞體,叫做 120-cell。4 維正多胞體是 3 維空間中正多面體在 4 維空間中的類比,這個 120-cell 有 600 個頂點,1200 條邊,720 個面,120 個胞腔。所有的邊,面,胞腔在 4 維空間中都是同樣大小的,視頻中看起來不一樣大,是因為在投影到 3 維空間中時發生了形變:我們這裡用的是球極投影,而球極投影不是保距的。
為什麼要投影呢?因為我們生活在 3 維空間中,對 4 維空間中的事物只能用數學的角度分析,腦海中很難生成直觀的圖像。
在劉慈欣的 三體 一書中,關於四維空間有如下的描述:
首次從四維空間看三維世界的人,首先領悟到一點:以前身處三維世界時,他其實根本沒看見過自己的世界,如果把三維世界也比做一張畫,他看到的只是那張畫與他的臉平面垂直放置時的樣子,看到的只是畫的側面,一條線;只有從四維看,畫才對他平放了。他會這樣描述:任何東內都不可能擋住它後面的東西,任何封閉體的內部也都是能看到的。這只是一個簡單獨規則,但如果世界真按這個規則呈現,視覺上是極其震撼的。當所有的遮檔和封閉都不存在,一切都暴露在外時,目擊者首先面對的是相當於三維世界中億萬倍的信息量,對於湧進視覺的海量信息,大腦一時無法把握。
評註:如果有人能從 4 維空間看這個三維的投影,則所有的 120 個 cell 都在他面前完全展現,不像視頻中顯示的那樣,有些胞腔會被遮擋住。
2. 這個圖是怎麼畫出來的?
當然是計算出每個頂點在 4 維空間中的坐標,它和哪些頂點構成邊,和哪些頂點構成面,然後投影到 3 維,然後就可以用任何 3D 畫圖工具畫出來啦!這裡我用的是 POV-Ray (我也只會這一個)。投影的公式如下:設 是一個 4 維空間中的點,首先將其單位化,變成 4 維空間中單位球面上的點 ,然後投影為
這就是所要的 3 維空間中的點。這裡極點選的是 ,理論上球面上任何一點都是可以的,這裡選這個點主要是為了避免投影到無窮。
3. 那你是怎麼計算出坐標來的?
這個地方正是麻煩之處,需要用到抽象代數中群的知識,這是本科數學專業課程的內容。
抽象代數課程中一般都會講到群在集合上的作用,其中有一個軌道-穩定化子定理:
設群 傳遞地作用在集合 上,對任一 , 設 是 s 的穩定化子群 (即 H 中每個元素保持 s 不動),則 所在的軌道 (在這個傳遞的情形軌道就是全部 ) 與 中的陪集一一對應。
所以如果我們能夠計算出 120-cell 的對稱群 (你暫時理解為空間中的一些等距變換組成的集合),並且對一個頂點 v, 計算出其穩定化子群 H,則把 G/H 作用在 v 上就得到了 120-cell 全部的頂點。
同理對一個面 f, 我們計算出其穩定化子群 K , 把 G/K 作用在 f 上就得到了全部的面。
對邊的計算也是類似的。
那麼怎麼計算 120-cell 的對稱群呢?這裡的關鍵在於它是一個有限 Coxeter 群,可以由 4 個鏡面反射生成,其 Coxeter 圖為 o --- 5 --- o --- 3 --- o --- 3 --- o,通常簡寫為 5-3-3。意思是說,它的表現為
根據這個表現,我們就可以利用 Todd-Coxeter 計算出整個群 G 的乘法表來。而其頂點穩定化子群不過是 生成的子 Coxeter 群(橢圓子群),邊穩定化子群不過是 生成的橢圓子群,面穩定化子群是 生成的橢圓子群。利用 Todd-Coxeter 演算法我們同樣可以計算出每個子群的陪集的乘法表來。
4. 那 Todd-Coxeter 演算法是什麼,很難實現嗎?
Todd-Coxeter 演算法在抽象代數課裡面一般是不講的,但是如果你細心點的話就會發現在國外的大多數本科水平的抽象代數教材裡面都會介紹,這是因為它不是一個可以直接導出各種推論定理的理論結果,而是一個幫你計算某個群結構(而且還要這個群前提是有限的)的演算法,它的地位在計算群論裡面是基石性的。
Python 的包 sympy 裡面有這個演算法,可惜它的實現是錯誤的,對 Mathieu 單群 M12 計算失效,見我提的 issue。於是我自己寫了一個簡單的基於 HLT 方法的實現。
如果要詳細鋪開講 Todd-Coxeter 演算法那就太長了,大致上它相當於做一個數獨遊戲,但是填的是一個動態擴張的表,它不停的根據已知的信息填表的空位,直到把整個表填滿為止(錶停止增長)。
5. POV-Ray 是什麼?
POV-Ray 是一個很古老的光線追蹤器,它開源且免費,在各種平台下都有對應的版本。它有一個自己內置的場景描述語言,可以方便你渲染各種 3D 場景。但是在它的語言下做各種計算太恐怖了,非常難用。所以我這裡是在 Python 中做好計算以後,導出數據到 POV-Ray中,但是還是避免不了在 POV-Ray 下面做一些計算來渲染。
6. TODO
還有各種截斷的正多胞體需要實現。
注意這個項目目前可以製作任何 3 維和 4 維的正多面/胞體,比如 3 維空間的正十二面體:
還有 4 維空間的 8-cell:
等等。
如果你喜歡的話,就去github 上點個贊吧!
推薦閱讀:
※《粒子物理學中的李代數》讀書筆記2
※【抄書筆記】李群的基本定義
※語言背後的代數學(七):數學結構
※基礎群論(七): 次正規列 下
※群論的基本概念