【问题标题】:How to plot 3D grid (cube) in Matlab如何在 Matlab 中绘制 3D 网格(立方体)
【发布时间】:2011-09-05 14:04:08
【问题描述】:

您好,我想绘制带有线条的透明立方体形网格。像这样的东西:

但是,我只设法绘制了一个 2D 网格:

[X,Y] = meshgrid(-8:.5:8);
Z = X+1;
surf(X,Y,Z)

我使用 Matlab R2009b。 如果无法在 matlab 中绘制此图,您能否推荐一个我可以使用的软件。

【问题讨论】:

  • 这是一个非常奇怪的观点。那是什么?看法?等距?还有什么?

标签: matlab grid plot cube


【解决方案1】:

考虑这个矢量化解决方案。它具有advantage,它创建了一个图形对象:

%# these don't all have to be the same
x = -8:2:8; y = -8:2:8; z = -8:2:8;

[X1 Y1 Z1] = meshgrid(x([1 end]),y,z);
X1 = permute(X1,[2 1 3]); Y1 = permute(Y1,[2 1 3]); Z1 = permute(Z1,[2 1 3]);
X1(end+1,:,:) = NaN; Y1(end+1,:,:) = NaN; Z1(end+1,:,:) = NaN;
[X2 Y2 Z2] = meshgrid(x,y([1 end]),z);
X2(end+1,:,:) = NaN; Y2(end+1,:,:) = NaN; Z2(end+1,:,:) = NaN;
[X3 Y3 Z3] = meshgrid(x,y,z([1 end]));
X3 = permute(X3,[3 1 2]); Y3 = permute(Y3,[3 1 2]); Z3 = permute(Z3,[3 1 2]);
X3(end+1,:,:) = NaN; Y3(end+1,:,:) = NaN; Z3(end+1,:,:) = NaN;

%#figure('Renderer','opengl')
h = line([X1(:);X2(:);X3(:)], [Y1(:);Y2(:);Y3(:)], [Z1(:);Z2(:);Z3(:)]);
set(h, 'Color',[0.5 0.5 1], 'LineWidth',1, 'LineStyle','-')

%#set(gca, 'Box','on', 'LineWidth',2, 'XTick',x, 'YTick',y, 'ZTick',z, ...
%#  'XLim',[x(1) x(end)], 'YLim',[y(1) y(end)], 'ZLim',[z(1) z(end)])
%#xlabel x, ylabel y, zlabel z
axis off
view(3), axis vis3d
camproj perspective, rotate3d on

【讨论】:

    【解决方案2】:

    如果您不介意一些 for 循环,则可以使用以下方法:

    clf
    figure(1)
    for g = 0:.2:2
    for i = 0:.2:2
    
       plot3([g g], [0 2], [i, i])
       hold on
    end
    end
    
    for g = 0:.2:2
    for i = 0:.2:2
    
       plot3([0 2], [g g], [i, i])
       hold on
    end
    end
    
    for g = 0:.2:2
    for i = 0:.2:2
    
       plot3([i i], [g g], [0 2])
       hold on
    end
    end
    

    您只需要通过可能更改线属性来使网格透明,我认为您不能更改 alpha 值来完成此操作。希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      斯蒂芬的答案更矢量化的版本可能如下:

      i = 0:0.2:2;
      [X Y] = meshgrid(i,i);                         
      x = [X(:) X(:)]';                                
      y = [Y(:) Y(:)]';
      z = [repmat(i(1),1,length(x)); repmat(i(end),1,length(x))];
      col = 'b';
      hold on;
      plot3(x,y,z,col);                                         
      plot3(y,z,x,col);
      plot3(z,x,y,col);
      

      不幸的是,MATLAB 目前不支持透明线(据我所知)。如果你真的需要它们是透明的,我建议使用“补丁”。

      【讨论】:

      • 我正在尝试使用您的代码来绘制一个旋转的立方体(而不是网格)。你愿意解释一下为什么最后 3 行是这样的吗?
      【解决方案4】:

      我知道这是一个迟到的回复,但如果其他人正在考虑做同样的事情,它仍然有效。

      假设您正在绘制立方体(/它们的边缘),已经提供的答案的替代方法是使用 Oliver 的“plotcube”代码: plotcube

      此解决方案的优势在于您可以:

      1. 更改面的透明度 (FaceAlpha),和/或,
      2. 更改边缘的透明度 (EdgeAlpha),和/或,
      3. 更改线条的颜色 (EdgeColor)。

      所有这些都可以是常量或变量。 (例如固定的边缘颜色,或随 Z 值变化的颜色等)

      要添加 2. 和 3.(上)的功能,更改 Olivers 代码中的 'cellfun(@patch...' 部分,添加以下四行额外代码:(替换整个 cellfun部分;包括新的“EdgeAlpha”和“EdgeColor”行):

      cellfun(@patch,XYZ{1},XYZ{2},XYZ{3},...
        repmat({clr},6,1),...
        repmat({'FaceAlpha'},6,1),...
        repmat({alpha},6,1),...
        repmat({'EdgeAlpha'},6,1),...
        repmat({0.2},6,1),...      % Set this value to whatever you want; even a variable / matrix
        repmat({'EdgeColor'},6,1),...  
        repmat({'black'},6,1)...
        );
      

      有关“补丁”的更多信息,请参阅patch 文档。

      重要提示: - 对于大型模型(许多立方体),这运行起来很慢。 例如在 MATLAB 的“for”循环中在数千个块上运行这个“plotcube”函数。我相信这是多次调用“补丁”函数。 更好的解决方案是矢量化;首先将所有点(顶点/面/任何东西)放在一个矩阵中,然后只调用一次@patch 函数(没有“for”循环)。这需要以某种方式更改代码以更新所有 XYZ 数据。

      我希望对某人有所帮助。

      这里是“plotcube”代码,以防 Oliver 的原始代码链接有一天中断:

      function plotcube(varargin)
      % PLOTCUBE - Display a 3D-cube in the current axes
      %
      %   PLOTCUBE(EDGES,ORIGIN,ALPHA,COLOR) displays a 3D-cube in the current axes
      %   with the following properties:
      %   * EDGES : 3-elements vector that defines the length of cube edges
      %   * ORIGIN: 3-elements vector that defines the start point of the cube
      %   * ALPHA : scalar that defines the transparency of the cube faces (from 0
      %             to 1)
      %   * COLOR : 3-elements vector that defines the faces color of the cube
      %
      % Example:
      %   >> plotcube([5 5 5],[ 2  2  2],.8,[1 0 0]);
      %   >> plotcube([5 5 5],[10 10 10],.8,[0 1 0]);
      %   >> plotcube([5 5 5],[20 20 20],.8,[0 0 1]);
      
      % Default input arguments
      inArgs = { ...
        [10 56 100] , ... % Default edge sizes (x,y and z)
        [10 10  10] , ... % Default coordinates of the origin point of the cube
        .7          , ... % Default alpha value for the cube's faces
        [1 0 0]       ... % Default Color for the cube
        };
      
      % Replace default input arguments by input values
      inArgs(1:nargin) = varargin;
      
      % Create all variables
      [edges,origin,alpha,clr] = deal(inArgs{:});
      
      XYZ = { ...
        [0 0 0 0]  [0 0 1 1]  [0 1 1 0] ; ...
        [1 1 1 1]  [0 0 1 1]  [0 1 1 0] ; ...
        [0 1 1 0]  [0 0 0 0]  [0 0 1 1] ; ...
        [0 1 1 0]  [1 1 1 1]  [0 0 1 1] ; ...
        [0 1 1 0]  [0 0 1 1]  [0 0 0 0] ; ...
        [0 1 1 0]  [0 0 1 1]  [1 1 1 1]   ...
        };
      
      XYZ = mat2cell(...
        cellfun( @(x,y,z) x*y+z , ...
          XYZ , ...
          repmat(mat2cell(edges,1,[1 1 1]),6,1) , ...
          repmat(mat2cell(origin,1,[1 1 1]),6,1) , ...
          'UniformOutput',false), ...
        6,[1 1 1]);
      
      
      cellfun(@patch,XYZ{1},XYZ{2},XYZ{3},...
        repmat({clr},6,1),...
        repmat({'FaceAlpha'},6,1),...
        repmat({alpha},6,1)...
        );
      
      view(3);
      

      【讨论】:

        【解决方案5】:

        您可以通过设置 color = [0.65, 0.65, 0.65] 使内线变得透明。您可以将虚线样式用于内部线,将实线样式用于边界,使其更像 3-D 对象。

        在我的软件包中,我编写了一个 mesh3 函数来绘制 3-D 张量积网格。

        【讨论】:

          【解决方案6】:
          clear all 
          close all
          clc
          Nx=11;
          Ny=11;
          Nz=11;
          clf
          hold on
          [i,j]=meshgrid(1:Nx,1:Ny);
          k=zeros(Ny,Nx)+Nz;
          surf(i,j,k)
          [i,k]=meshgrid(1:Nx,1:Nz);
          j=zeros(Nz,Nx)+Ny;
          surf(i,j,k)
          [j,k]=meshgrid(1:Ny,1:Nz);
          i=zeros(Nz,Ny)+Nx;
          surf(i,j,k)
          [i,j]=meshgrid(1:Nx,1:Ny);
          k=zeros(Ny,Nx)+1;
          surf(i,j,k)
          [i,k]=meshgrid(1:Nx,1:Nz);
          j=zeros(Nz,Nx)+1;
          surf(i,j,k)
          [j,k]=meshgrid(1:Ny,1:Nz);
          i=zeros(Nz,Ny)+1;
          surf(i,j,k)
          view(30,30)
          

          【讨论】:

          • 一些解释,除了代码,会让这个答案更有帮助。
          猜你喜欢
          • 2022-11-10
          • 2021-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多