在matlab中旋转3d网格模型

时间:2015-10-17 17:22:17

标签: matlab 3d transformation

我想旋转并对齐以面顶点形式表示的3d网格模型。如果我的模型是点云形式,则三维矩阵的转换将起作用。我找不到将面 - 顶点信息转换为[x y z]点云信息的函数。

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 个答案:

答案 0 :(得分: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中的颜色信息。

这是围绕Z轴旋转60度的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