2015-10-17 93 views
0

我想旋轉並對齊以面頂點形式表示的三維網格模型。如果我的模型是點雲形式,則3d矩陣的轉換可能會奏效。我找不到將臉部頂點信息轉換爲[x y z]點雲信息的函數。在matlab中旋轉三維網格模型

view(-[0 20]); 

上述命令有助於以期望的角度查看圖像,但不會改變面頂點值。 我的3D對象採用.stl格式,我使用ftread.m函數將其加載到matlab中。

功能來讀取文件·STL

function [fout, vout, cout] = ftread(filename) 
% Reads CAD STL ASCII files, which most CAD programs can export. 
% Used to create Matlab patches of CAD 3D data. 
% Returns a vertex list and face list, for Matlab patch command. 
% 
% filename = 'hook.stl'; % Example file. 
% 
fid=fopen(filename, 'r'); %Open the file, assumes STL ASCII format. 
if fid == -1 
    error('File could not be opened, check name or path.') 
end 
% 
% Render files take the form: 
% 
%solid BLOCK 
% color 1.000 1.000 1.000 
% facet 
%  normal 0.000000e+00 0.000000e+00 -1.000000e+00 
%  normal 0.000000e+00 0.000000e+00 -1.000000e+00 
%  normal 0.000000e+00 0.000000e+00 -1.000000e+00 
% outer loop 
%  vertex 5.000000e-01 -5.000000e-01 -5.000000e-01 
%  vertex -5.000000e-01 -5.000000e-01 -5.000000e-01 
%  vertex -5.000000e-01 5.000000e-01 -5.000000e-01 
% endloop 
% endfacet 
% 
% The first line is object name, then comes multiple facet and vertex lines. 
% A color specifier is next, followed by those faces of that color, until 
% next color line. 
% 
CAD_object_name = sscanf(fgetl(fid), '%*s %s'); %CAD object name, if needed. 
%            %Some STLs have it, some don't. 
vnum=0;  %Vertex number counter. 
report_num=0; %Report the status as we go. 
VColor = 0; 
% 
while feof(fid) == 0     % test for end of file, if not then do stuff 
    tline = fgetl(fid);     % reads a line of data from file. 
    fword = sscanf(tline, '%s ');  % make the line a character string 
% Check for color 
    if strncmpi(fword, 'c',1) == 1; % Checking if a "C"olor line, as "C" is 1st char. 
     VColor = sscanf(tline, '%*s %f %f %f'); % & if a C, get the RGB color data of the face. 
    end        % Keep this color, until the next color is used. 
    if strncmpi(fword, 'v',1) == 1; % Checking if a "V"ertex line, as "V" is 1st char. 
     vnum = vnum + 1;    % If a V we count the # of V's 
     report_num = report_num + 1; % Report a counter, so long files show status 
     if report_num > 249; 
      disp(sprintf('Reading vertix num: %d.',vnum)); 
      report_num = 0; 
     end 
     v(:,vnum) = sscanf(tline, '%*s %f %f %f'); % & if a V, get the XYZ data of it. 
     c(:,vnum) = VColor;    % A color for each vertex, which will color the faces. 
    end         % we "*s" skip the name "color" and get the data.           
end 
% Build face list; The vertices are in order, so just number them. 
% 
fnum = vnum/3;  %Number of faces, vnum is number of vertices. STL is triangles. 
flist = 1:vnum;  %Face list of vertices, all in order. 
F = reshape(flist, 3,fnum); %Make a "3 by fnum" matrix of face list data. 
% 
% Return the faces and vertexs. 
% 
fout = F'; %Orients the array for direct use in patch. 
vout = v'; % " 
cout = c'; 
% 
fclose(fid); 
+1

你能準確地向我們展示如何最終得到面頂點結構嗎?一旦你有了這個數據結構,你應該能夠使用旋轉矩陣簡單地轉換頂點。面通常只是頂點數組中的索引,所以它們不需要轉換。所以,這應該很容易做到,一旦你清楚你的3D網格在導入之後存儲在哪個數據結構中。 – WhiteViking

+0

'MATLAB'可能不是這份工作的最佳工具。您是否考慮過使用CAD程序,例如紮實的作品? –

+0

@WhiteViking感謝您的幫助 順便說一下,我用上面給出的函數(我編輯我的問題)來讀取我的3d對象文件,它給出了頂點和麪。我不知道要現在做轉換,但我會嘗試通過考慮頂點數據作爲點雲信息的轉換 –

回答

2

讓我們嘗試讀取一個簡單的STL文件,轉換適用於它的頂點(例如繞Z軸的旋轉),並對其進行渲染。

下面是一個例子(文本格式)STL用於與面的立方體垂直於座標軸的文件:

solid 
    facet normal 0.000000 1.000000 0.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex 1.000000 1.000000 -1.000000 
     vertex -1.000000 1.000000 -1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 1.000000 0.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex -1.000000 1.000000 -1.000000 
     vertex -1.000000 1.000000 1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 0.000000 1.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex -1.000000 1.000000 1.000000 
     vertex -1.000000 -1.000000 1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 0.000000 1.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex -1.000000 -1.000000 1.000000 
     vertex 1.000000 -1.000000 1.000000 
    endloop 
    endfacet 
    facet normal 1.000000 0.000000 0.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex 1.000000 -1.000000 1.000000 
     vertex 1.000000 -1.000000 -1.000000 
    endloop 
    endfacet 
    facet normal 1.000000 0.000000 0.000000 
    outer loop 
     vertex 1.000000 1.000000 1.000000 
     vertex 1.000000 -1.000000 -1.000000 
     vertex 1.000000 1.000000 -1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 0.000000 -1.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex 1.000000 1.000000 -1.000000 
     vertex 1.000000 -1.000000 -1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 -1.000000 0.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex 1.000000 -1.000000 -1.000000 
     vertex 1.000000 -1.000000 1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 -1.000000 0.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex 1.000000 -1.000000 1.000000 
     vertex -1.000000 -1.000000 1.000000 
    endloop 
    endfacet 
    facet normal -1.000000 0.000000 0.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex -1.000000 -1.000000 1.000000 
     vertex -1.000000 1.000000 1.000000 
    endloop 
    endfacet 
    facet normal -1.000000 0.000000 0.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex -1.000000 1.000000 1.000000 
     vertex -1.000000 1.000000 -1.000000 
    endloop 
    endfacet 
    facet normal 0.000000 0.000000 -1.000000 
    outer loop 
     vertex -1.000000 -1.000000 -1.000000 
     vertex -1.000000 1.000000 -1.000000 
     vertex 1.000000 1.000000 -1.000000 
    endloop 
    endfacet 
endsolid 

保存它cube.stl。然後使用您的ftread代碼導入:

[F, V, C] = ftread('cube.stl'); 

我將在C被忽略的顏色信息在這裏。

這是旋轉60度圍繞Z軸的3D rotation matrix

Rz = [ cos(pi/3), sin(pi/3), 0 ; 
     -sin(pi/3), cos(pi/3), 0 ; 
       0,   0, 1 ]; 

變換所有頂點:

V = V * Rz'; 

使用MATLAB的patch命令繪製立方體爲一組的面的:

patch('Faces', F, 'Vertices', V, 'FaceVertexCData', (1:12)', 'FaceColor', 'flat'); 
view(3) 
axis equal 

它看起來像這樣:

enter image description here

+0

是!這就是我想要的。非常感謝 –