Create multiple patches from a single X,Y,Z matrix without NaNs

5 views (last 30 days)
Hi
I have a matrix holding the vertices in X,Y,Z of multiple 2D planes in R3. I'd like to create patches based on these values, but the problem is that the matrix does not hold any NaNs to separate the faces from each other:
http://www.mathworks.nl/help/matlab/ref/patch.html ".. To define a patch with faces that do not close, add one or more NaNs to the row in the Vertices matrix that defines the vertex you do not want connected."
They are double values representing X,Y and Z cartesian coordinates of 2D polygons, starting and ending at the same point, although this point is only given once. The faces can be distinguished by the fact that the coordinates of the faces are stored in 'blocks' of successive rows and its points lie in the same 2D plane in 3D space. Faces do not consist of the same number of points, they are not of equal sizes and they might even intersect. However, 2 faces cannot lie on the exact same 2D plane (or at least this is extremely unlikely).
I could probably write a distance based function to test each new vertex, but it seems to me that somebody has encountered this problem before. So, is there a function to supply my matrix with the missing NaNs, so I can create the patches?
Thank you very much!

Answers (1)

Kelly Kearney
Kelly Kearney on 24 Sep 2013
What is the format of the x, y, and z data? What distinguishes one face from another within that dataset? E.g. does each face consist of the same number of points? Or each face starts and ends at the same point?
  2 Comments
Lise Nielsen
Lise Nielsen on 24 Sep 2013
They are double values representing X,Y and Z cartesian coordinates of 2D polygons, starting and ending at the same point, although this point is only given once. The faces can be distinguished by the fact that the coordinates of the faces are stored in 'blocks' of successive rows and its points lie in the same 2D plane in 3D space. Faces do not consist of the same number of points, they are not of equal sizes and they might even intersect. However, 2 faces cannot lie on the exact same 2D plane (or at least this is extremely unlikely).
Kelly Kearney
Kelly Kearney on 24 Sep 2013
In that case, I'd just loop over the matrix, using the matching start/end point as the indicator to break the data apart.
Once broken apart, if you're only interested in displaying the outlines of each polygon, then you could just concatenate the data using NaNs. However, patch won't fill in any polygons that contain NaNs, even if they're only used for padding (a very annoying trait, in my opinion). So instead, I usually just pad unequally-sized polygons with the start/end point.
% Create some fake data
x{1} = [0 0 1 1 0];
y{1} = [0 1 1 0 0];
z{1} = [0 0 0 0 0];
th = linspace(0, 2*pi, 10);
th = [th(1:end-1) th(1)];
x{2} = cos(th);
y{2} = sin(th);
z{2} = ones(size(th));
xyz = [cat(2, x{:}); cat(2, y{:}); cat(2, z{:})]';
% Break apart
xyzcell = cell(0);
start = xyz(1,:);
idx = 1;
count = 2;
while count <= size(xyz,1)
if isequal(start, xyz(count,:))
xyzcell = [xyzcell; xyz(idx:count,:)];
if count < size(xyz,1)
start = xyz(count+1,:);
end
idx = count + 1;
count = count + 2;
else
count = count + 1;
end
end
% Create new patch matrices
npt = cellfun(@(x) size(x,1), xyzcell);
npoly = length(xyzcell);
[xp,yp,zp] = deal(nan(max(npt), npoly));
for ii = 1:npoly
xp(1:npt(ii),ii) = xyzcell{ii}(:,1); % Polygon data
yp(1:npt(ii),ii) = xyzcell{ii}(:,2);
zp(1:npt(ii),ii) = xyzcell{ii}(:,3);
xp(npt(ii)+1:end,ii) = xp(npt(ii),ii); % Padding
yp(npt(ii)+1:end,ii) = yp(npt(ii),ii);
zp(npt(ii)+1:end,ii) = zp(npt(ii),ii);
end
% Plot
patch(xp, yp, zp, 1:npoly);
view(3)

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!