問(wèn)題
matlab處理網(wǎng)格時(shí),有時(shí)需要將網(wǎng)格細(xì)分
思路參考:https://hanspond.github.io/2018/11/27/%E7%AE%80%E5%8D%95%E7%BD%91%E6%A0%BC%E7%BB%86%E5%88%86%201to4%20Mesh%20Subdivision/index.html
將每一個(gè)面的每一條邊取中點(diǎn)并連接,形成新的三角形,原來(lái)一個(gè)面細(xì)分成四個(gè)面
原博主的代碼只適合封閉曲面的細(xì)分,如果曲面是不封閉的,則拓?fù)浣Y(jié)構(gòu)會(huì)亂,如:
代碼:
%% created by H_P 20181119: subdivide mesh into 4 smaller meshes in a simple mannerfunction [ Divided_faces, Divided_vertices ] = sub_test( faces, vertices )
%SUB_TEST 此處顯示有關(guān)此函數(shù)的摘要
% 此處顯示詳細(xì)說(shuō)明mesh_length_Large=length(faces);
Divided_faces=1:mesh_length_Large*4*3;
Divided_faces=(reshape(Divided_faces,[3,mesh_length_Large*4]))';
Divided_vertices=repelem(vertices,4,1);for n_for=1:mesh_length_Largev1=faces(n_for,1);v2=faces(n_for,2);v3=faces(n_for,3);new_1=(vertices(v1,:)+vertices(v2,:))/2;new_2=(vertices(v3,:)+vertices(v2,:))/2;new_3=(vertices(v1,:)+vertices(v3,:))/2;Divided_vertices((n_for-1)*12+2,:)= new_1;Divided_vertices((n_for-1)*12+3,:)= new_3;Divided_vertices((n_for-1)*12+4,:)= new_1;Divided_vertices((n_for-1)*12+6,:)= new_2;Divided_vertices((n_for-1)*12+7,:)= new_2;Divided_vertices((n_for-1)*12+8,:)= new_3;Divided_vertices((n_for-1)*12+10,:)= new_1;Divided_vertices((n_for-1)*12+11,:)= new_2;Divided_vertices((n_for-1)*12+12,:)= new_3;
end
end
調(diào)用:
>> [v,f]=read_obj('test.obj');
>> [ Divided_faces, Divided_vertices ] = sub_test( f', v');
>> writeOBJ('test_sub.obj',Divided_vertices,Divided_faces);
結(jié)果:
細(xì)分前:
細(xì)分后:
解決
我將代碼改進(jìn)了一下,將分割條件改為網(wǎng)格面積大于閾值就分割,否則不分割
代碼:
function [ divided_vertices ,divided_faces ] = subdivide_mesh01( vertices,faces ,threshold )
%SUBDIVIDE_MESH 將曲面簡(jiǎn)單細(xì)分為1to4
% 輸入:
% vertices:細(xì)分前的點(diǎn)集n*3
% faces:細(xì)分前的面集m*3
% threshold:網(wǎng)格面積小于這個(gè)就細(xì)分
% 輸出:
% divided_vertices:細(xì)分后的點(diǎn)集
% divided_faces:細(xì)分后的面集
tic%403秒
size_faces=size(faces,1);
delete_flag=[];
for m=1:size_facesinx1=faces(m,1);inx2=faces(m,2);inx3=faces(m,3);v1=vertices(inx1,:);v2=vertices(inx2,:);v3=vertices(inx3,:);s=my_area(v1,v2,v3);if s>thresholddelete_flag=[delete_flag;m];%細(xì)分new1=(v1+v2)/2;new2=(v2+v3)/2;new3=(v3+v1)/2;[inx_new1,vertices]=my_index(new1,vertices);[inx_new2,vertices]=my_index(new2,vertices);[inx_new3,vertices]=my_index(new3,vertices);faces_temp=[inx3,inx_new2,inx_new3;inx_new1,inx_new2,inx_new3;inx_new1,inx_new2,inx2;inx_new3,inx_new1,inx1];faces=[faces;faces_temp];endend
toc
faces(delete_flag,:)=[];%刪除細(xì)分過(guò)后的原始面
divided_vertices=vertices;
divided_faces=faces;endfunction [dist]=my_dist(v1,v2)
%輸入兩個(gè)點(diǎn),得到它們之間的距離
dist=power( (v1-v2)*((v1-v2)'),1/2);
endfunction [area]=my_area(v1,v2,v3)
%輸入三個(gè)點(diǎn),得到由它們構(gòu)成的三角形的面集a=my_dist(v1,v2);b=my_dist(v2,v3);c=my_dist(v1,v3);p=(a+b+c)/2;area=power(p*(p-a)*(p-b)*(p-c),1/2);
endfunction [inx,vertices]=my_index(v,vertices)
%輸入一個(gè)點(diǎn),返回該點(diǎn)在點(diǎn)集中的索引行
%如果該點(diǎn)存在,返回索引行,如果該點(diǎn)不存在,插入該點(diǎn),返回索引行
mem = ismember(vertices,v,'rows');
inx=find(mem==1);
if isempty(inx)%如果inx為空vertices=[vertices;v];inx=size(vertices,1);
end
end
調(diào)用:
>> [ divided_vertices ,divided_faces ] = subdivide_mesh01( v',f' ,0.06 );
時(shí)間已過(guò) 4.625456 秒。
>> writeOBJ('test_sub02.obj',divided_vertices,divided_faces);
結(jié)果:
細(xì)分前:
細(xì)分后:
優(yōu)化
將元素運(yùn)算換成矩陣運(yùn)算,見(jiàn)文章
【matlab教程】21、matlab優(yōu)化一:將對(duì)單個(gè)元素的操作轉(zhuǎn)換成矩陣之間的運(yùn)算
總結(jié)
以上是生活随笔為你收集整理的【matlab教程】20、简单网格细分的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。