最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Matlab實現(xiàn)繪制3D足球的示例代碼

 更新時間:2022年11月28日 10:18:03   作者:slandarer  
這篇文章主要為大家詳細介紹了如何利用Matlab實現(xiàn)繪制3D足球,文中的示例代碼講解詳細,對我們學(xué)習(xí)Matlab有一定幫助,需要的可以參考一下

世界杯教你用MATLAB畫個超逼真的足球,

需要準(zhǔn)備Partial Differential Equation Toolbox工具箱,同時因為用到了polyshape類所以至少需要R2017b版本。

繪制講解

數(shù)據(jù)來源及說明

我是真的不想寫注釋了太麻煩了,給大家講一下我的思路希望能夠看懂,首先足球的數(shù)據(jù)點是通過:

[B,XYZ]=bucky;

導(dǎo)入的,但是導(dǎo)入的只有邊鏈接信息,并沒有給出哪幾個點構(gòu)成正五邊形哪幾個邊構(gòu)成正六邊形。

spy(B)

通過spy展示一下稀疏矩陣發(fā)現(xiàn),似乎每5行數(shù)據(jù)代表一個正五邊形,但是正六邊形的邊的編號還是無法獲得:

展示一下部分連接情況:

[B,XYZ]=bucky;
spy(B) 

G = graph(B);
A = adjacency(G);
H = graph(A(1:30,1:30));
h = plot(H);
axis equal

我們發(fā)現(xiàn)很多正六邊形頂點的編號都完全不沾邊,打算硬算。

硬算頂點連接情況

描述一下思路哈,我們知道每個正五邊形的頂點位置,就能計算出每個正五邊形中心的位置,之后距離比較近的三個正五邊形中心點歸為一類計算三個正五邊形中心點的中心點,其計算結(jié)果與原點連線的方向向量會經(jīng)過正六邊形的中心點,找到每個正六邊形中心點的位置,計算離每個中心點最近的六個點位置并排序,大概就是這樣:

  • 計算五邊形頂點
  • 計算五邊形中心
  • 最近三個五邊形歸為一組
  • 計算每組中心
  • 找到離六邊形中心最近的六個點
  • 為六邊形點排序、捋順

以上過程通過這段代碼完成:

C5=reshape(mean(reshape(XYZ,5,[])),12,[]);
distC5=pdist(C5);
distC5=squareform(distC5);
[~,indP5]=sort(distC5,2);
P3=zeros(12,15);
for k=1:12
    K=indP5(k,2:6);
    Kmat=distC5(K,K);
    [m,n]=find(Kmat>.5&Kmat<1);
    Kcomb=[ones(5,1),unique(sort([m,n],2),'rows')+1]';
    P3(k,:)=indP5(k,Kcomb);
end
P3=unique(sort(reshape(P3',3,[])',2),'rows');
C6=zeros(20,3);
for i=1:20
    C6(i,:)=mean(C5(P3(i,:),:));
end
distC6=pdist2(C6,XYZ);
[~,indP6]=sort(distC6,2);
indP6=indP6(:,1:6);
for i=1:20
    tind=indP6(i,:);
    tP6=XYZ(indP6(i,:),:);
    CH6=convhull(tP6(:,1),tP6(:,2),'Simplify',true);
    indP6(i,:)=tind(CH6(1:6));
end

此時我們已經(jīng)能畫出一個有棱有角的足球了:

hold on;axis equal;view(3)
for i=1:20
    XYZ6=XYZ(indP6(i,:),:);
    fill3(XYZ6(:,1),XYZ6(:,2),XYZ6(:,3),[1,1,1]);
end
for i=1:12
    fill3(XYZ((i-1)*5+(1:5),1),XYZ((i-1)*5+(1:5),2),XYZ((i-1)*5+(1:5),3),[0,0,0]);
end

三角剖分

很明顯足球每個面是個球面,我們就想對足球進行曲面插值,這里直接用了工具箱Partial Differential Equation Toolbox的給定輪廓三角剖分的過程,對于每個面進行細密三角化。

但是每個面要分別剖分,但是3-D剖分不支持僅僅對一個面剖分,因此我是先做了平面剖分再將剖分點坐標(biāo)映射到3-D圖形上的:

S6_t=linspace(0,2*pi,7);
S6_X=cos(S6_t(1:6));
S6_Y=sin(S6_t(1:6));
S6_region=polyshape(S6_X,S6_Y);
S6_tri=triangulation(S6_region);
S6_model=createpde;
S6_tnodes=S6_tri.Points';
S6_telements=S6_tri.ConnectivityList';
geometryFromMesh(S6_model,S6_tnodes,S6_telements);
S6_mesh=generateMesh(S6_model,"Hmax",0.1,"GeometricOrder","linear");
pdeplot(S6_model)

S5_t=linspace(0,2*pi,6);
S5_X=cos(S5_t(1:5));
S5_Y=sin(S5_t(1:5));
S5_region=polyshape(S5_X,S5_Y);
S5_tri=triangulation(S5_region);
S5_model=createpde;
S5_tnodes=S5_tri.Points';
S5_telements=S5_tri.ConnectivityList';
geometryFromMesh(S5_model,S5_tnodes,S5_telements);
S5_mesh=generateMesh(S5_model,"Hmax",0.1,"GeometricOrder","linear");
pdeplot(S5_model)

正交變換

反正和半徑建立聯(lián)系前,球的表面還是一個個平面組成的,我們就能很輕松的找到一組正交基,以下展如何尋找正五邊形面上的正交向量。

首先正五邊形的中心與某一頂點做差可獲得一個向量 v1 ? ?同時對于任意一個相鄰頂點,依舊與中心點做差得到 v2 ? 

我們只需要計算:

就能得到在平面內(nèi)且互相垂直的向量 v1 ? , v3 ? 正六邊形也是一樣的將5改為6即可:

這樣我們就能將平面上的點輪流映射到多邊形面:

for i=1:20
    V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
    V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
    V2=V2./norm(V2).*norm(V1);
    V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
    % V6=V6./vecnorm(V6')'.*(1+sin(1-vecnorm(V6')')./4);
    patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','k');
end

for i=1:12
    V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
    V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
    V2=V2./norm(V2).*norm(V1);
    V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
    % V5=V5./vecnorm(V5')'.*(1+sin(1-vecnorm(V5')')./4);
    patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','k');
end

充氣

我們怎樣讓足球鼓起來呢?

一個其中一個想法就是讓每個點到足球球心長度都單位化,例如:

for i=1:20
    V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
    V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
    V2=V2./norm(V2).*norm(V1);
    V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
    V6=V6./vecnorm(V6')';
    patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','k');
end

for i=1:12
    V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
    V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
    V2=V2./norm(V2).*norm(V1);
    V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
    V5=V5./vecnorm(V5')';
    patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','k');
end

但此時足球就是一個正球,我們希望每個多邊形邊緣都凹陷進去,這怎么辦呢,我的想法是借助 sin函數(shù)做個長度映射:

實際上用的映射函數(shù)是:

R=sin(1−r)/4

for i=1:20
    V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
    V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
    V2=V2./norm(V2).*norm(V1);
    V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
    V6=V6./vecnorm(V6')'.*(1+sin(1-vecnorm(V6')')./4);
    patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','k');
end

for i=1:12
    V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
    V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
    V2=V2./norm(V2).*norm(V1);
    V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
    V5=V5./vecnorm(V5')'.*(1+sin(1-vecnorm(V5')')./4);
    patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','k');
end

當(dāng)然如果打個光取消一下邊緣顏色會更好看:

for i=1:20
    V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
    V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
    V2=V2./norm(V2).*norm(V1);
    V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
    V6=V6./vecnorm(V6')'.*(1+sin(1-vecnorm(V6')')./4);
    patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','none');
end

for i=1:12
    V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
    V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
    V2=V2./norm(V2).*norm(V1);
    V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
    V5=V5./vecnorm(V5')'.*(1+sin(1-vecnorm(V5')')./4);
    patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','none');
end
light
material dull

完整代碼

[B,XYZ]=bucky;
% 獲取各個正六邊形序號=======================================================
C5=reshape(mean(reshape(XYZ,5,[])),12,[]);
distC5=pdist(C5);
distC5=squareform(distC5);
[~,indP5]=sort(distC5,2);
P3=zeros(12,15);
for k=1:12
    K=indP5(k,2:6);
    Kmat=distC5(K,K);
    [m,n]=find(Kmat>.5&Kmat<1);
    Kcomb=[ones(5,1),unique(sort([m,n],2),'rows')+1]';
    P3(k,:)=indP5(k,Kcomb);
end
P3=unique(sort(reshape(P3',3,[])',2),'rows');
C6=zeros(20,3);
for i=1:20
    C6(i,:)=mean(C5(P3(i,:),:));
end
distC6=pdist2(C6,XYZ);
[~,indP6]=sort(distC6,2);
indP6=indP6(:,1:6);
for i=1:20
    tind=indP6(i,:);
    tP6=XYZ(indP6(i,:),:);
    CH6=convhull(tP6(:,1),tP6(:,2),'Simplify',true);
    indP6(i,:)=tind(CH6(1:6));
end
% =========================================================================
hold on;axis equal off;view(3)
% for i=1:20
%     XYZ6=XYZ(indP6(i,:),:);
%     fill3(XYZ6(:,1),XYZ6(:,2),XYZ6(:,3),[1,1,1]);
% end
% for i=1:12
%     fill3(XYZ((i-1)*5+(1:5),1),XYZ((i-1)*5+(1:5),2),XYZ((i-1)*5+(1:5),3),[0,0,0]);
% end
% 六邊形插值曲面 ===========================================================
S6_t=linspace(0,2*pi,7);
S6_X=cos(S6_t(1:6));
S6_Y=sin(S6_t(1:6));
S6_region=polyshape(S6_X,S6_Y);
S6_tri=triangulation(S6_region);
S6_model=createpde;
S6_tnodes=S6_tri.Points';
S6_telements=S6_tri.ConnectivityList';
geometryFromMesh(S6_model,S6_tnodes,S6_telements);
eval(char([100,105,115,112,40,39,20316,32773,...
    58,115,108,97,110,100,97,114,101,114,39,41]));
S6_mesh=generateMesh(S6_model,"Hmax",0.1,"GeometricOrder","linear");
S6_V=S6_mesh.Nodes';
S6_F=S6_mesh.Elements';
for i=1:20
    V1=XYZ(indP6(i,1),:)-mean(XYZ(indP6(i,:),:));
    V2=XYZ(indP6(i,2),:)-mean(XYZ(indP6(i,:),:))-sin(pi/2-2*pi/6).*V1;
    V2=V2./norm(V2).*norm(V1);
    V6=S6_V(:,1).*V1+S6_V(:,2).*V2+mean(XYZ(indP6(i,:),:));
    V6=V6./vecnorm(V6')'.*(1+sin(1-vecnorm(V6')')./4);
    patch('Faces',S6_F,'Vertices',V6,'FaceColor',[1,1,1],'EdgeColor','none');
end
% 五邊形插值曲面 ===========================================================
S5_t=linspace(0,2*pi,6);
S5_X=cos(S5_t(1:5));
S5_Y=sin(S5_t(1:5));
S5_region=polyshape(S5_X,S5_Y);
S5_tri=triangulation(S5_region);
S5_model=createpde;
S5_tnodes=S5_tri.Points';
S5_telements=S5_tri.ConnectivityList';
geometryFromMesh(S5_model,S5_tnodes,S5_telements);
S5_mesh=generateMesh(S5_model,"Hmax",0.1,"GeometricOrder","linear");
S5_V=S5_mesh.Nodes';
S5_F=S5_mesh.Elements';
for i=1:12
    V1=XYZ((i-1)*5+1,:)-mean(XYZ((i-1)*5+(1:5),:));
    V2=XYZ((i-1)*5+2,:)-mean(XYZ((i-1)*5+(1:5),:))-sin(pi/2-2*pi/5).*V1;
    V2=V2./norm(V2).*norm(V1);
    V5=S5_V(:,1).*V1+S5_V(:,2).*V2+mean(XYZ((i-1)*5+(1:5),:));
    V5=V5./vecnorm(V5')'.*(1+sin(1-vecnorm(V5')')./4);
    patch('Faces',S5_F,'Vertices',V5,'FaceColor',[1,1,1].*.2,'EdgeColor','none');
end
light
material dull

以上就是基于Matlab實現(xiàn)繪制3D足球的示例代碼的詳細內(nèi)容,更多關(guān)于Matlab繪制3D足球的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++ lambda 捕獲模式與右值引用的使用

    C++ lambda 捕獲模式與右值引用的使用

    這篇文章主要介紹了C++ lambda 捕獲模式與右值引用的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • C++ 11 nullptr 空指針示例詳解

    C++ 11 nullptr 空指針示例詳解

    C++11標(biāo)準(zhǔn)引入了nullptr來替代傳統(tǒng)的NULL,解決了NULL可能導(dǎo)致的類型混淆問題,nullptr是nullptr_t類型的實例,專用于初始化空類型指針,與整型不會發(fā)生隱式轉(zhuǎn)換,從而使代碼更健壯,它可以被隱式轉(zhuǎn)換為任意類型的指針,提高了代碼的安全性和可讀性
    2024-10-10
  • C語言實現(xiàn)冒泡排序算法的示例詳解

    C語言實現(xiàn)冒泡排序算法的示例詳解

    這篇文章主要介紹了C語言如何實現(xiàn)冒泡排序算法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • C++中的最小生成樹算法超詳細教程

    C++中的最小生成樹算法超詳細教程

    這篇文章主要介紹了C++中的最小生成樹算法超詳細教程,最小生成樹的最著名的算法有兩個, 一個是Prim算法, 另一個當(dāng)然就是Kruskal算法, 接下來, 我將盡我所能的介紹這兩個算法, 也算是對自己學(xué)習(xí)的一個回顧吧,需要的朋友可以參考下
    2023-08-08
  • C++內(nèi)存分布及用法

    C++內(nèi)存分布及用法

    這篇文章主要介紹了C++內(nèi)存分布及用法,從內(nèi)存的基礎(chǔ)概念到內(nèi)存分配進行了講解,內(nèi)存是我們開發(fā)中最重要的一部分,往往邏輯上的錯誤就會造成內(nèi)存泄漏,導(dǎo)致程序無法運行,下面我們就來了解文章對該內(nèi)容的詳細介紹
    2021-12-12
  • c語言:金幣陣列的問題

    c語言:金幣陣列的問題

    本文介紹了關(guān)于c語言:金幣陣列的問題,需要的朋友可以參考一下
    2013-03-03
  • C/C++舉例講解關(guān)鍵字的用法

    C/C++舉例講解關(guān)鍵字的用法

    相對于其他語言來說,C語言的關(guān)鍵字算是少的了。在C98中關(guān)鍵子總共只有32個,我們來分析一下部分關(guān)鍵字在C/C++中它獨特的作用
    2022-05-05
  • c語言通過棧判斷括號匹配是否配對

    c語言通過棧判斷括號匹配是否配對

    前面實現(xiàn)了棧的基本數(shù)據(jù)結(jié)構(gòu),這里來做一個聯(lián)系,用棧來解決一道比較常見的算法題,就是括號配對是否滿足規(guī)則,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2023-09-09
  • 在C++中加載TorchScript模型的方法

    在C++中加載TorchScript模型的方法

    這篇文章主要介紹了在C++中加載TorchScript模型的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • C++將音頻PCM數(shù)據(jù)封裝成wav文件的方法

    C++將音頻PCM數(shù)據(jù)封裝成wav文件的方法

    這篇文章主要為大家詳細介紹了C++將音頻PCM數(shù)據(jù)封裝成wav文件的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

宿迁市| 新邵县| 晋城| 大方县| 黎平县| 柞水县| 商南县| 大英县| 泸西县| 哈密市| 丹江口市| 琼海市| 弋阳县| 沧州市| 鹤山市| 武乡县| 浠水县| 辽中县| 新和县| 宿松县| 平利县| 东港市| 三台县| 高阳县| 石台县| 丹凤县| 平谷区| 含山县| 渝中区| 丹凤县| 彭水| 柳河县| 宜黄县| 宜章县| 合川市| 循化| 福州市| 资溪县| 义马市| 武山县| 伊宁市|