Plotting A Large Number Of Patches

10 visualizaciones (últimos 30 días)
ADSW121365
ADSW121365 el 15 de Oct. de 2020
Editada: ADSW121365 el 19 de Oct. de 2020
There are a few older topics on this, but nothing I could find which is directly relevent I don't think. I'm utilising a modified version of: Olivier (2020). PLOTCUBE ( https://www.mathworks.com/matlabcentral/fileexchange/15161-plotcube ), MATLAB Central File Exchange to plot some images of a cubic discretisation e.g:
function PLOTTER(Coords,objprop)
for index = 1:length(Coords.Lo.X(:))
plotcube([Coords.dX;Coords.dY;Coords.dZ]'...
,[Coords.Lo.X(index);Coords.Lo.Y(index);Coords.Lo.Z(index)]',...
.5,objprop(index)); hold on;
%Object Prop Defines Colormap
end
end
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);
I'm encountering two issues, both which I believe are related to the fact I'm rendering this using many patches.
First, if I have a large number of cubes, I'm no longer able to interact with the figure (but there's no obvious CPU/GPU strain either: 4690K 4.7GHz overclock + GTX 1060).
Secondly, when I'm comparing a large number of algorithms i.e producing many plots, I'm finding MATLAB crashes or encounters low-level graphics errors once I reach around 30 plots (216 cubes per plot).
I think this is likely poor coding/utilisation of MATLAB visualisation abilities rather than a case of MATLAB being unable to achieve my intention. Any thoughts on a more efficient way to render these plots, particularily for larger numbers of cubes would be greatly appreciated, noting the transpancy of the cubes is important to be able to visulise any internal structures.

Respuesta aceptada

Kelly Kearney
Kelly Kearney el 16 de Oct. de 2020
Creating a single multi-faceted patch is much, much more efficient than plotting lots of single-face patches. In the figure you show, you're plotting 216 cubes, with 6 faces each, for a total of 1296 faces. Using the code above, you're creating that many individual patch objects, and each one comes with a lot of graphics overhead.
Instead, plot one patch with 1296 faces:
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] ...
};
% Faces for a single unit cube (6 faces)
xcube = cat(1, XYZ{:,1})';
ycube = cat(1, XYZ{:,2})';
zcube = cat(1, XYZ{:,3})';
% Many cubes
[x0, y0, z0] = ndgrid(1:6); % corner coordinates
col = zeros(size(x0)); % color index
col(:,:,end) = 2;
xall = arrayfun(@(a) a+xcube, x0(:), 'uni', 0);
yall = arrayfun(@(a) a+ycube, y0(:), 'uni', 0);
zall = arrayfun(@(a) a+zcube, z0(:), 'uni', 0);
xall = cat(2, xall{:});
yall = cat(2, yall{:});
zall = cat(2, zall{:});
col = kron(col(:)', ones(1,6)); % expand colors to all 6 faces
% Plot
p = patch(xall, yall, zall, col, 'facealpha', 0.1);
view(3);
  3 comentarios
Kelly Kearney
Kelly Kearney el 19 de Oct. de 2020
Just looking at it quickly (haven't tested the code), I would suggest updating the xall/yall/zall equation to:
xall = arrayfun(@(a,b) a+xcube.*b, x0(:), dx(:), 'uni', 0);
where dx is an array the same size as x0, specifying the length of each cube in the x direction. And repeat the same for the y and z dimensions.
ADSW121365
ADSW121365 el 19 de Oct. de 2020
Editada: ADSW121365 el 19 de Oct. de 2020
Worked like a charm, thanks so much! I can plot 216000 cubes and still manipulate my figure!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Surface and Mesh Plots en Help Center y File Exchange.

Productos


Versión

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by