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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

非均匀三次B样条曲线插值实现及MATLAB代码

發布時間:2024/3/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 非均匀三次B样条曲线插值实现及MATLAB代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?這篇博客跟我上一篇博客《均勻三次B樣條曲線插值實現及MATLAB代碼》的內容有點像,只是在基函數的計算上不同,造成均勻/非均勻的區別。

參考資料:

[1](這個PPT講得很通俗,但對于多插值點分段曲線的內容漏講了一個知識點)三次周期B樣條曲線的算法 - 百度文庫 (baidu.com)

[2](這個介紹只有兩個插值點的三次B樣條曲線,是B樣條曲線最簡單的形式了吧~)(7條消息) 從B樣條的插值點反求控制點_cofd的專欄-CSDN博客

[3](一本書,里面有講到整體參數和局部參數設置、節點矢量劃分等)《計算機輔助幾何設計與非均勻有理B樣條》

正文:

曲線插值一般指的是給定插值點,得出曲線的方程,曲線會經過所有的插值點。確定三次B樣條曲線的輸入量有兩種,一種是給出控制點和其它邊界條件,曲線一般不經過控制點;一種是給出插值點和其它邊界條件,曲線會經過所有插值點,顯然第二種輸入量使用更為廣泛,這里只介紹第二種情況。

①首先輸入插值點,這些插值點可以是二維(x,y)點,也可以是三維(x,y,z)點,甚至更多維都可以,處理方法都相似,以二維點為例,MATLAB代碼:

pointInput=[1 209.1;1.033 209.525;1.067 209.273;1.1 209.277;1.133 208.734;1.167 208.693;1.2 208.852;1.233 208.722;1.267 208.746;1.3 208.759];

這些點的分布如下圖的紅色拆線所示(不是藍色的*型點,藍色的是我最終擬合的曲線)。

??②計算N、n、k等值

N為插值點的個數,上面共有10個插值點,所以N=10。控制點個數為N+2個。n=N+1。k為次數,這里是三次B樣條曲線,所以k=3。MATLAB代碼:

N=length(pointInput); k=3; n=N-1;

③反算控制點

這里主要參考了資料[1]PPT中的內容,具體的請查看該PPT。三次B樣條曲線的表達式(1)為

?其中是第i段曲線的表達式,是局部參數,是第i個控制點。注意節點、節點矢量、整體參數、局部參數的區別(具體的要看資料[3]或其它相關的資料了,說明這些可能需要長篇大論哦~)。

反算控制點,我用了第三種邊界條件,如下圖

增加了邊界條件后,就能求如下圖的矩陣方程了,其實下面的矩陣方程是由表達式(1)得到的,具體可以參考資料[1]的PPT(注意表達式中的系數6不要看漏了)。

?

?對于二維點,我想對x和y坐標的B樣條曲線都求出來,所以用了兩組矩陣方程求解它們各自的控制點(對于三維點,還能用同樣的方法求z坐標的B樣條曲線)。MATLAB代碼:

%①先求x、y坐標,如果是三維點,還要求z b1=[0;pointInput(:,1);0]*6;%注意系數 px=Chase_method(A1,b1);%用追趕法求得所有控制點 b2=[0;pointInput(:,2);0]*6; py=Chase_method(A1,b2);

其中求三對角陣解用追趕法Chase_method(可以直接用常用的方法求解,但此處用追趕法時間復雜度更低),其MATLAB代碼:

function [ x ] = Chase_method( A, b ) %Chase method 追趕法求三對角矩陣的解 % A為三對角矩陣的系數,b為等式右端的常數項,返回值x即為最終的解 % 注:A盡量為方陣,b一定要為列向量 %% 求追趕法所需L及U T = A; for i = 2 : size(T,1)T(i,i-1) = T(i,i-1)/T(i-1,i-1);T(i,i) = T(i,i) - T(i-1,i) * T(i,i-1); end L = zeros(size(T)); L(logical(eye(size(T)))) = 1; %對角線賦值1 for i = 2:size(T,1)for j = i-1:size(T,1)L(i,j) = T(i,j);break;end end U = zeros(size(T)); U(logical(eye(size(T)))) = T(logical(eye(size(T)))); for i = 1:size(T,1)for j = i+1:size(T,1)U(i,j) = T(i,j);break;end end %% 利用matlab解矩陣方程的遍歷直接求解 y = L\b; x = U\y; end

④確定節點矢量

節點矢量是分段B樣條曲線進行分段的依據(請看下資料[3]或其它相應資料),我用哈德利-賈德方法確定節點矢量(節點矢量共有n+k+2個,注意這里是小寫n而不是大寫的N),即節點矢量中前k+1個節點取值0,后k+1個節點取值為1,重復度為k+1,然后中間的節點由哈德利-賈德方法計算得到。MATLAB代碼(注意MATLAB的數組和矩陣的下標是從1開始的,與公式中的從0開始有區別):

%確定節點矢量 u=zeros(1,N+1+k+2);%0:1/(N+1+k+2-1):1; for i=1:k+1u(length(u)-i+1)=1; end l=zeros(1,N+1);%控制多邊形各邊長 for i=1:N+1%注意如果用到三維點,這里要作修改l(i)=sqrt((px(i+1)-px(i))^2+(py(i+1)-py(i))^2); end sum1=0;%用哈德利-賈德方法決定節點矢量 for g=k+1:N+1+1for j=g-k:g-1sum1=sum1+l(j);end end for i=k+2:N+2u(i)=sum(l(i-k:i-1))/sum1+u(i-1); end

計算得到了所有的控制點以及節點矢量,已經能知道該分段B樣條曲線的表達式了,下面就輸入一個點來測試。其實該分段B樣條曲線用參數方程表示,x、y坐標都以參數u來表示,同時以節點矢量中每個節點作為分段曲線分段的邊界,U中的元素的單調不減小的,后一個元素一不小于一個元素。下面MATLAB代碼使u取值為測試點uTest,然后先找到uTest屬于哪個分段,計算得到uTest屬于score分段:

uTest=0.5; score=find(uTest>=u,1,'last');%確定該參數方程的參數值所屬的分段 if uTest==1 score=find(u==1,1)-1;end score=score-k;%表示第score段樣條曲線

在用表達式(1)求出參數uTest對應的x、y坐標值之間,需要將整體變量uTest轉換為局部變量t。注意uTest在整體樣條曲線中的取值范圍是[0,1],而t在第score分段曲線中的取值范圍是[0,1]。轉換公式為(為節點矢量中第i+1個元素,且滿足,這里的i可由score確定),從而,得到表達式(1)中的矩陣,MATLAB代碼:

uNode=1;%上面的uTest是整體參數,用來確定是哪段曲線,要將整體參數轉化為局部參數t t=(uTest-u(score+k))/(u(score+1+k)-u(score+k)); for i=1:kuNode=[t^i uNode]; end

對比我另一篇博客《均勻三次B樣條曲線插值實現及MATLAB代碼》,本篇博客的樣條曲線是非均勻的,即用的基函數并不是固定的值,而是由德布爾-考克斯遞推公式計算得到。先求出基函數,MATLAB代碼:

Nb=zeros(k+3,k+1); for j=1:k+1for i=1:n+1if j==1if i==score+kNb(i,j)=1; continue;elseNb(i,j)=0; continue;endelse%if u(i+j-1)-u(i)==0||u(i+j+1-1)-u(i+1)==0 continue;endif u(i+j-1)-u(i)==0&&u(i+j+1-1)-u(i+1)==0Nb(i,j)=0;elseif u(i+j-1)-u(i)==0Nb(i,j)=(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);elseif u(i+j+1-1)-u(i+1)==0Nb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1);elseNb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1)+(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);end%Nb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1)+(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);endend end

最后由基函數和控制點計算得到夢寐以求的x、y坐標值,MATLAB代碼:

Qx=0;Qy=0; for i=score:score+k %注意非零基函數的個數Qx=Qx+px(i)*Nb(i,k+1);Qy=Qy+py(i)*Nb(i,k+1); end

附上全部MATLAB程序:

%三次B樣條插值,給定插值點及兩個邊界條件,反算出控制點,由控制點得到分段曲線 %三維點(x,y,z)和二維點(x,y)的插值算法類似,控制多邊形各邊長l要作修改 %pointInput插值點 pointInput=[1 209.1;1.033 209.525;1.067 209.273;1.1 209.277;1.133 208.734;1.167 208.693;1.2 208.852;1.233 208.722;1.267 208.746;1.3 208.759]; %pointInput=[0 10;5 8.66;10 0]; %用第三種邊界條件 https://wenku.baidu.com/view/2482396e011ca300a6c390b3.html N=length(pointInput); k=3; A1=eye(N+2,N+2)*4; A1(1,1)=6;A1(1,2)=-6;A1(N+2,N+1)=6;A1(N+2,N+2)=-6; for i=2:N+1A1(i,i-1)=1;A1(i,i+1)=1; end %①先求x、y坐標,如果是三維點,還要求z b1=[0;pointInput(:,1);0]*6;%注意系數 px=Chase_method(A1,b1);%用追趕法求得所有控制點 b2=[0;pointInput(:,2);0]*6; py=Chase_method(A1,b2); %確定節點矢量 u=zeros(1,N+1+k+2);%0:1/(N+1+k+2-1):1; for i=1:k+1u(length(u)-i+1)=1; end l=zeros(1,N+1);%控制多邊形各邊長 for i=1:N+1%注意如果用到三維點,這里要作修改l(i)=sqrt((px(i+1)-px(i))^2+(py(i+1)-py(i))^2); end sum1=0;%用哈德利-賈德方法決定節點矢量 for g=k+1:N+1+1for j=g-k:g-1sum1=sum1+l(j);end end for i=k+2:N+2u(i)=sum(l(i-k:i-1))/sum1+u(i-1); end %用基函數求值 %uTestArray=0:0.01:1; for uTest=0:0.01:1 %uTest=0.5; %u3Array=[uTest^3 uTest^2 uTest 1];%三次B樣條專屬 score=find(uTest>=u,1,'last');%確定該參數方程的參數值所屬的分段 if uTest==1 score=find(u==1,1)-1;end score=score-k;%表示第score段樣條曲線 %用德布爾-考克斯遞推公式計算基函數 Nb=zeros(k+3,k+1); for j=1:k+1for i=1:n+1if j==1if i==score+kNb(i,j)=1; continue;elseNb(i,j)=0; continue;endelse%if u(i+j-1)-u(i)==0||u(i+j+1-1)-u(i+1)==0 continue;endif u(i+j-1)-u(i)==0&&u(i+j+1-1)-u(i+1)==0Nb(i,j)=0;elseif u(i+j-1)-u(i)==0Nb(i,j)=(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);elseif u(i+j+1-1)-u(i+1)==0Nb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1);elseNb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1)+(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);end%Nb(i,j)=(uTest-u(i))/(u(i+j-1)-u(i))*Nb(i,j-1)+(u(i+j+1-1)-uTest)/(u(i+j+1-1)-u(i+1))*Nb(i+1,j-1);endend end Qx=0;Qy=0; for i=score:score+k %注意非零基函數的個數Qx=Qx+px(i)*Nb(i,k+1);Qy=Qy+py(i)*Nb(i,k+1); end plot(Qx,Qy,'*');hold on; end plot(pointInput(:,1),pointInput(:,2),'r'); function [ x ] = Chase_method( A, b ) %Chase method 追趕法求三對角矩陣的解 % A為三對角矩陣的系數,b為等式右端的常數項,返回值x即為最終的解 % 注:A盡量為方陣,b一定要為列向量 %% 求追趕法所需L及U T = A; for i = 2 : size(T,1)T(i,i-1) = T(i,i-1)/T(i-1,i-1);T(i,i) = T(i,i) - T(i-1,i) * T(i,i-1); end L = zeros(size(T)); L(logical(eye(size(T)))) = 1; %對角線賦值1 for i = 2:size(T,1)for j = i-1:size(T,1)L(i,j) = T(i,j);break;end end U = zeros(size(T)); U(logical(eye(size(T)))) = T(logical(eye(size(T)))); for i = 1:size(T,1)for j = i+1:size(T,1)U(i,j) = T(i,j);break;end end %% 利用matlab解矩陣方程的遍歷直接求解 y = L\b; x = U\y; end

效果圖,藍色點的是曲線擬合的點,紅色拆線是由插值點組成的:

總結

以上是生活随笔為你收集整理的非均匀三次B样条曲线插值实现及MATLAB代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91丨porny丨国产 | aaa特级毛片 | 日本伊人久久 | www.四虎影视| 超碰cc| 天天夜碰日日摸日日澡性色av | 欧美网站在线 | 亚洲综合久久av一区二区三区 | 超碰97久久 | 天堂中文在线资源 | 久久鲁鲁| av黄色在线免费观看 | mm视频在线观看 | 成人在线一区二区 | 3344av| 91自啪| 亚洲熟妇av日韩熟妇在线 | 欧美色国 | 久久艹精品视频 | 99re99| 国产一区二区三区三州 | 日韩不卡视频一区二区 | 男人插入女人下面的视频 | 久热在线 | 自拍偷拍第3页 | 国产精品久久777777毛茸茸 | 91国内揄拍国内精品对白 | 日韩在线看片 | 亚洲视频一区二区三区四区 | 国产成人一级 | 午夜影院在线观看 | 国产精品一品二区三区的使用体验 | 国产精品欧美一区喷水 | wwww在线观看| 国产我不卡 | 少妇高潮一区二区三区99 | 久久天天 | 欧美老肥妇做爰bbww | 久久久久久久9 | 国产精品第72页 | 自拍偷拍色 | 日韩爱爱免费视频 | 狠狠鲁视频 | 亚洲 欧美 另类 综合 偷拍 | av高清在线免费观看 | 欧美无吗 | 久久午夜网站 | 亚洲视频在线免费观看 | 日韩欧美国产一区二区三区在线观看 | 青春草网站 | 欧美福利一区 | 国产视频网站在线观看 | 自拍偷拍麻豆 | √天堂在线 | 狂野少女电影在线观看国语版免费 | 久久精品无码人妻 | 日本韩国欧美一区二区三区 | 麻豆tv在线| www.黄色网址| 国产日韩欧美精品 | 朝桐光av在线一区二区三区 | 丝袜美腿av | 欧美人吸奶水吃奶水 | 亚洲系列中文字幕 | 精品人妻无码一区二区性色 | 国产永久免费观看 | 手机在线中文字幕 | 91天堂视频 | 亚洲国产成人一区二区精品区 | 国产午夜一区 | www黄色片 | 丝袜一区二区三区四区 | 国产在线观 | 日韩精品一区二区三区丰满 | 亚洲 欧美 日韩 综合 | 国产免费一级 | 亚洲精品视频在线看 | 天天插天天操天天干 | 日韩在线观看一区二区 | 日本欧美在线观看 | 黑人操日本女人 | 欧美体内she精高潮 日韩一区免费 | 国产又粗又大又爽视频 | 中文字幕av一区 | www.久草.com| 国产午夜精品一区二区三区视频 | 91成人国产 | 国产欧美视频一区二区 | 一区二区三区视频网站 | 久久怡红院 | 大学生一级片 | 色妹子综合 | 免费毛片看片 | 欧美精品videos | 息与子五十路翔田千里 | 特大黑人娇小亚洲女mp4 | 91亚洲精品乱码久久久久久蜜桃 | 色综合av综合无码综合网站 | 长篇高h肉爽文丝袜 |