web-dev-qa-db-fra.com

Comment tracer une grille 3D (cube) dans Matlab

Bonjour, j'aimerais tracer une grille transparente en forme de cube avec des lignes. Quelque chose comme ça:enter image description here

Cependant, j'ai seulement réussi à dessiner une grille 2D:

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

J'utilise Matlab R2009b . S'il est impossible de tracer cela dans matlab, pourriez-vous me recommander un logiciel que je pourrais utiliser.

16
Func

Si quelques boucles d’attente ne vous dérangent pas, cela fonctionnera:

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

Vous aurez juste besoin de rendre la grille transparente en modifiant probablement les propriétés de la ligne, je ne pense pas que vous puissiez modifier les valeurs alpha pour accomplir cela. J'espère que c'est utile.

12
St-Ste-Ste-Stephen

Considérons cette solution vectorisée. Il présente le avantage qu'il crée un seul objet graphique:

%# 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

screenshot

18
Amro

Une version plus vectorisée de la réponse de Stephen pourrait être la suivante:

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);

Malheureusement, MATLAB ne supporte pas actuellement les lignes transparentes (à ma connaissance). Si vous avez vraiment besoin qu'ils soient transparents, je vous suggère d'utiliser «patch».

8
Raf

Je comprends que c’est une réponse tardive, mais elle reste valable au cas où quelqu'un d’autre voudrait faire la même chose.

En supposant que vous traçiez des cubes (/ leurs bords), une solution alternative aux réponses déjà fournies consiste à utiliser le code "plotcube" de Oliver: plotcube

L'avantage de cette solution est que vous pouvez:

  1. Changer la transparence des faces (FaceAlpha), et/ou,
  2. Changer la transparence des bords (EdgeAlpha), et/ou,
  3. Changer la couleur des lignes (EdgeColor).

Tous ces éléments peuvent être des constantes ou des variables ..__ (par exemple, une couleur d'arête fixe ou une couleur qui change avec la valeur Z, etc.)

Pour ajouter les fonctionnalités de 2. et 3. (ci-dessus), changez la section 'cellfun (@patch ...') dans le code Olivers, en ajoutant les quatre lignes de code supplémentaires comme suit: (remplacez la section entière cellfun par celle-ci; y compris les nouvelles lignes 'EdgeAlpha' et '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)...
  );

Pour plus d'informations sur 'patch', veuillez consulter patch documentation.

Une remarque importante: - pour les grands modèles (beaucoup de cubes), son exécution est très lente. exécuter cette fonction 'plotcube' dans une boucle 'for' dans MATLAB sur des milliers de blocs. Je pense que cela consiste à appeler la fonction 'patch' plusieurs fois ... Une meilleure solution serait de vectoriser; pour rassembler tous vos points (sommets/faces/peu importe) dans une seule matrice, puis appelez la fonction @patch une seule fois (pas de boucle 'for'). Cela nécessiterait de modifier le code pour mettre à jour toutes les données XYZ.

J'espère que cela aide quelqu'un.

Voici le code 'plotcube' au cas où le lien au code original par Oliver se briserait un jour:

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);
1
Mike

vous pouvez rendre le type de ligne intérieure transparent en définissant color = [0.65, 0.65, 0.65]. Et vous pouvez utiliser le style de trait pointillé pour les lignes intérieures et les traits pleins pour les limites afin de le rendre plus semblable à un objet à trois dimensions. 

Dans mon progiciel, je code une fonction mesh3 pour tracer les mailles de produit tenseur 3D. 

0
Long Chen
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)
0
user7344151