日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

De Casteljau算法

發(fā)布時(shí)間:2023/12/9 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 De Casteljau算法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目 在Bezier曲線上找到點(diǎn):De Casteljau算法

翻譯文章來(lái)自http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html

在貝塞爾曲線繪制完成后,下一個(gè)重要的任務(wù)是選定特定u的情況下在曲線上找到點(diǎn)C(u)。一個(gè)簡(jiǎn)單的方法是把u插到每一個(gè)基函數(shù)上,計(jì)算每個(gè)其與基函數(shù)的乘積以及其相應(yīng)的控制頂點(diǎn),最后將其相加。雖然這種方法很好,但是缺乏數(shù)值穩(wěn)定性(例如在計(jì)算Bernstein多項(xiàng)式的時(shí)候可能引進(jìn)數(shù)值(numerical errors)誤差)。

在下文中,我們僅僅記下控制點(diǎn)的數(shù)字。例如00對(duì)應(yīng)控制點(diǎn)P0,01對(duì)應(yīng)P1,...,0i對(duì)應(yīng)Pi,...,0n對(duì)應(yīng)Pn。因此在這些數(shù)字中0s表示初始的或者是第0次迭代。在之后,0被其他數(shù)字1,2,3代替表示第1,2,3次迭代,等等。

De Casteljau算法的基本觀點(diǎn)是選擇在AB中的一個(gè)點(diǎn)C,C將AB分為u:1-u(A到C的距離與AB之間的距離之比是u),讓我們找到?jīng)Q定C在哪里的方法


從A到B的向量是B-A。因?yàn)閡是在0和1之間的比率,點(diǎn)C位于u(B-A)。將A的位置加以考慮,點(diǎn)C為A+u(B-A)=(1-u)A+uB。因此,對(duì)于給定的u,(1-u)A+uB是在A和B之間的點(diǎn)C,將AB分為u:1-u的兩段

De Casteljau算法的想法如下。假設(shè)我們想要找到C(u),u在[0,1]中。由第一個(gè)多段線00-01-02-03...-0n開(kāi)始,利用上面的法則找到在線段上的點(diǎn)1i,1i在0i到0(i+1)的連線上并且將這段線分為u:1-u的兩部分。依次地,我們可以得到n個(gè)點(diǎn)10,11,12,...,1(n-1),他們定義了一個(gè)新的多段線(polyline),一共有n-1段


在上圖中,u是0.4,10是在00和01的線段(leg),11是在01和02的線段,...,并且14是在04到05的線段,所有的新點(diǎn)都由藍(lán)色的表示。

新點(diǎn)由1i進(jìn)行標(biāo)記,再次利用上面的規(guī)則我們可以得到第二個(gè)多段線,具有n-1個(gè)點(diǎn)(20,21,...,2(n-2))和n-2條邊。從這個(gè)多段線開(kāi)始,進(jìn)行第三次,得到新的多段線,由n-2個(gè)點(diǎn)30,31,...,3(n-3)和n-3條邊組成。重復(fù)這個(gè)過(guò)程n次得到一個(gè)點(diǎn)n0,Casteljau已經(jīng)證明在曲線上的點(diǎn)C(u)對(duì)應(yīng)u

以上圖舉例,20是在10和11上將這段線分為u:1-u的點(diǎn),類(lèi)似地選取21在11和12上,22在12和13上,23在13和14上.第三個(gè)多段線是20,21,22,23.第三個(gè)多段線有四個(gè)點(diǎn)和三條邊。繼續(xù)做得到30,31,32組成的多段線,這是第四個(gè)多段線。繼續(xù)得到有40和41組成的線段,再做一次得到50,為點(diǎn)C(0.4)。

這是de Casteljau算法的幾何解釋,是在曲線設(shè)計(jì)中最漂亮(elegant)的結(jié)果之一。


實(shí)際計(jì)算

給定了de Casteljau的幾何解釋之后,我們現(xiàn)在展示一個(gè)計(jì)算方法,由下圖


首先,在如圖中的最左邊一列是給定的控制點(diǎn)。對(duì)于每一對(duì)臨近的控制點(diǎn),可以畫(huà)出一條右上方和右下方的箭頭,并且在兩個(gè)箭頭的交點(diǎn)處寫(xiě)下一個(gè)新點(diǎn)。例如相鄰的兩個(gè)點(diǎn)分別為ij 和i(j+1),新點(diǎn)是(i+1)j,右下方(相對(duì)應(yīng)的左下方)的箭頭表示將其尾數(shù)ij(相對(duì)應(yīng)的為i(j+1))乘以1-u(相對(duì)應(yīng)的乘以u(píng)),新的點(diǎn)是兩個(gè)的和。

因此,從初始的第0列開(kāi)始,我們計(jì)算第1列。之后從第1列得到第2列。最終,在n次計(jì)算之后我們最終到達(dá)了一個(gè)單個(gè)的點(diǎn)n0并且這個(gè)點(diǎn)就是在曲線上的點(diǎn)。下面的算法總結(jié)了上面我們討論的內(nèi)容,輸入的是具有n+1個(gè)點(diǎn)的數(shù)列P和在0到1之間的u,最終得到在Bezier曲線上的點(diǎn)C(u)

Input: array P[0:n] of n+1 points and real number u in [0,1] Output: point on curve, C(u) Working: point array Q[0:n] for i := 0 to n do Q[i] := P[i]; // save input for k := 1 to n do for i := 0 to n - k do Q[i] := (1 - u)Q[i] + u Q[i + 1]; return Q[0];

一個(gè)遞歸關(guān)系

上面的計(jì)算過(guò)程可以用遞歸的方法表示,對(duì)于j=0,1,...,n用P0,j表示Pj,也就是P0,j是第0列的第j項(xiàng)元素,在第i列計(jì)算第j項(xiàng)如下


元素Pi,j是(1-u)Pi-1,j(左上方元素和 uPi-1,j+1(左下方元素)的和,最終的結(jié)果(在曲線上的點(diǎn))是Pn,0.在這種想法的基礎(chǔ)上,我們可以快速得到以下過(guò)程

function deCasteljau(i,j) begin if i = 0 then return P0,j else return (1-u)* deCasteljau(i-1,j) + u* deCasteljau(i-1,j+1) end


這個(gè)過(guò)程看起來(lái)簡(jiǎn)單,表達(dá)上也很簡(jiǎn)練,但是效率卻不高。因?yàn)槲覀兿胍獙?duì)于Pn,0計(jì)算deCasteljau(n,0) ,我們要分別對(duì)Pn-1,0計(jì)算deCasteljau(n-1,0),0,對(duì)Pn-1,1計(jì)算deCasteljau(n-1,1)


再考慮計(jì)算deCasteljau(n-1,0)。分為對(duì)于Pn-2,0計(jì)算deCasteljau(n-2,0),和對(duì)于Pn-2,1計(jì)算deCasteljau(n-2,1)。對(duì)于deCasteljau(n-1,1)也是分為兩部分如上圖所示。因此deCasteljau(n-2,1)被計(jì)算了兩遍,如果我們擴(kuò)展這些函數(shù)計(jì)算,我們會(huì)發(fā)現(xiàn)對(duì)于Pi,j的計(jì)算重復(fù)了很多遍,而不是僅僅計(jì)算了一遍。事實(shí)上,上面的計(jì)算和計(jì)算Fibonacci數(shù)列的第n項(xiàng)是類(lèi)似的

function Fibonacci(n) begin if n = 0 or n = 1 then return 1 elsereturn Fibonacci (n-1) + Fibonacci (n-2) end

為了計(jì)算 Fibonacci( n)函數(shù)被調(diào)用了指數(shù)次,因此上面的de Casteljau算法對(duì)于直接的實(shí)現(xiàn)來(lái)說(shuō)是不合適的,雖說(shuō)代碼看上去比較簡(jiǎn)潔。


一個(gè)有趣的觀察

de Casteljau算法的三角形計(jì)算方法提供了一種有趣的現(xiàn)象,舉一個(gè)例子,八個(gè)控制點(diǎn)00,01,...,07組成的7階Bezier曲線。選擇控制點(diǎn)列中的連續(xù)序列,對(duì)于給定的u,怎樣計(jì)算其在Bezier曲線上對(duì)應(yīng)的點(diǎn)呢?事實(shí)上,如果利用de Casteljau算法,發(fā)現(xiàn)在曲線上的點(diǎn)就是等邊三角形的頂點(diǎn)!其底是選擇的連續(xù)點(diǎn)列。


舉例來(lái)說(shuō),如果我們選擇02,03,04,05,其對(duì)應(yīng)于u這四個(gè)控制頂點(diǎn)的曲線上的點(diǎn)就是32,就是上圖中的藍(lán)色三角形,如果選擇11,12,13,在曲線上的點(diǎn)就是31,如黃色三角形。如果選擇30,31,32,33和34,那么在曲線上的點(diǎn)就是70.

也是同樣的原因,70在由60和61組成的Bezier曲線上。同樣地,也是50,51和52上的點(diǎn),也是40,41,42,43.一般地,如果我們選擇一個(gè)點(diǎn)并且如上所示畫(huà)一個(gè)等邊三角形,其底上的控制點(diǎn)就是被選擇用來(lái)計(jì)算的點(diǎn)。


總結(jié)

以上是生活随笔為你收集整理的De Casteljau算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。