透視中 n 等分點和倍增線段的直接畫法
之前學習了任意 n 等分點的畫法,該方法雖能繪制任意等分點,但對程序作圖不太適合,最近研究發(fā)現(xiàn),其實有一些更直接的方式來找 n 等分點,其不需要做任何輔助線,只需要做測量即可。
n 等分點,倍增線段
直入主題,有這樣的結論:
任意指向某消失點的線段,它的 n 等分點的位置僅和線段在畫布上的長度,以及線段和消失點在畫布上的距離相關。
假設該線段離消失點較遠的點和消失點的距離為 a,離消失點較近的點和消失點的距離為 b,則該線段的第 i 個 n 等分點和消失點的距離是:
d(n, i, a, b) = nab / (ia + (n - i)b)
比如,當a = 6
,b = 2
時,它的 2 等分點距離消失點的距離是 2 * 6 * 2 / (6 + 2) = 3
,如下圖:

比如,當a = 6
,b = 2
時,它的三等分點距離消失點的距離分別為 3 * 6 * 2 / (6 + 2 * 2) = 3.6
, 3 * 6 * 2 / (2 * 6 + 2) = 2.57
,如下圖:

倍增線段,假設該線段離消失點較遠的點和消失點的距離為 a,離消失點較近的點和消失點的距離為 b,則它的倍增點距離該線段離消失點較遠的點的距離為:
d(a, b) = (2a^2 - 2ab) / (2a - b)
比如,當a = 5
, b = 3
時,它的倍增線段距離離消失點較遠的點的距離是 (2 * 5 * 5 - 2 * 5 * 3) / (2 * 5 - 3) = 2.85
,如下圖:

n 等分點代碼實現(xiàn)如下:
一個交互式示例
下面是一個利用 p5.js 來展示該算法的交互式示例,可以拖動 A,C 點和兩個消失點,代碼實現(xiàn)就在 html 文件中:
https://v-yop.github.io/file/nsplit.html


證明
因為畫圖麻煩所以這里不畫圖了 w
n 等分點
考慮一個左手坐標系中的三個點 P0,P1,P2,其中P0 = (x, y, z, P1 = (x, y, z + l), P2 = (x, y, z + 2)
,相機在原點,viewport 為z=d
。
顯然,P0,P1,P2 是同一個線段上 3 個點,P1 為 P0P2 的中點。這三個點向相機方向投影,在 viewport 上分別為P0' = (x * d / z, y * d / z, d), P1' = (x * d / (z + l), y * d / (z + l), d), P2' = (x * d / (z + 2l), y * d / (z + 2l), d)
。
現(xiàn)在只看 viewport 這個平面,我們要知道二等分點和線段、消失點的關系,就是要看 |P0’O|,|P1’O|,和 |P2’O| 的關系,其中 |P0’O| 和 |P2’O| 對我們是可知的。這三個點顯然都在一條斜率等于 y / x 的線性函數(shù)上,其中 P0’距原點最遠,P2’最近。
我們能得到|P0'O| = (d / z) * sqrt(x^2 + y^2)
,|P1'O| = (d / (z + l)) * sqrt(x^2 + y^2)
,|P2'O| = (d / (z + 2l)) * sqrt(x^2 + y^2)
,不太容易得到的是,|P1'O| = 2 * |P0'O| * |P2'O| / (|P0'O| + |P2'O|)
。
再研究三等分點,增加一個點 P3,使用上面相同的方式,研究|P0'O|, |P1'O|, |P3'O|
和|P0'O|, |P2'O|, |P3'O|
的關系,其中|P0'O|
和 |P3'O|
對我們是可知的,后面的以此類推。
倍增線段
仍舊是像二等分點一樣,先三個點 P0,P1,P2,但這次可知的是|P0'O|
和 |P1'O|
,需要求得 |P2'O|
,這里只需要對上面得到的關系 |P1'O| = 2 * |P0'O| * |P2'O| / (|P0'O| + |P2'O|)
化簡一下就能得到結果。