I have a rational function $\phi: [0,1]^3 \to \mathbb R^3$ (A NURBS, to be precise) and I want to visualize the image of $\partial [0,1]^3$ using a surface plot (patch, for example). To do this I have chosen equidistant discretisation along each dimension and formed a meshgrid from this:

Nx = 50;
Ny = 2;
Nz = 20;

tx = linspace(0, 1, Nx);
ty = linspace(0, 1, Ny);
tz = linspace(0, 1, Nz);

[mx, my, mz] = meshgrid(tx,ty,tz);

Now I have implemented a function wich gives me a $3\times (Nx\cdot Ny\cdot Nz)$-matrix $M$ with the values $M_{:, i} = \phi(mx_i, my_i, mz_i)$ using linear indexing. Plotting this as a point cloud gives me a good gist of the figure:

enter image description here

Now I'd rather like to have a "solid" plot of the shape by plotting a patch for each of the six sides of the deformed cube. Is there a nice way to do this without having to manually think through the indexing?

  • $\begingroup$ If you have an equation, (or maybe even if not) you could try an isosurface. $\endgroup$ – David Feb 11 '15 at 4:41
  • $\begingroup$ @David Thanks but the problem is I have a transformation while isosurface seems to be for a volume function. I've accomplished my needs with six surf plots above each other, one for each face of the cube. I'll post an answer later when home. $\endgroup$ – AlexR Feb 11 '15 at 8:10
  • $\begingroup$ surf plots was going to be my next suggestion, I'll be interested to see how you handled it. $\endgroup$ – David Feb 11 '15 at 8:54
  • $\begingroup$ @David I've posted my solution as an answer now. Feel free to post any improvements as an answer! I'll be sure to look at it. $\endgroup$ – AlexR Feb 11 '15 at 9:38

Finally, I've accomplished my goal by individually surf-plotting each face of the transformed cube:
After looking at the docs of surf I found sphere(n) to produce an input for surf which would render the unit sphere and looked into it: surf(X,Y,Z) where all are matrices of the same size produces the surface with these points preserving the rectangular topology. This leads to the following code:

[e1x, e1y] = meshgrid(tx,ty);
[e2x, e2z] = meshgrid(tx,tz);
[e3y, e3z] = meshgrid(ty,tz);
% These are the three different grids needed for the cube faces

e1x = e1x(:);
% Make all of them columns

e1z = ones(size(e1x));
% The respective third dimensions will be constant 0 or 1

bottom = [  e1x   e1y 0*e1z]';
top    = [  e1x   e1y 1*e1z]';
front  = [  e2x 0*e2y   e2z]';
back   = [  e2x 1*e2y   e2z]';
left   = [0*e3x   e3y   e3z]';
right  = [1*e3x   e3y   e3z]';
% Create the faces:  
% surf(bottom(1,:), bottom(2,:), bottom(3,:)) with appropriate reshape
% would plot the bottom face of the unit cube

x = [bottom top front back left right];
Kstart = cumsum([1 size(bottom, 2) size(top, 2) size(front, 2) size(back, 2) size(left, 2)]);
Kend   = [Kstart(2:end)-1 size(x,2)];
% Concatenate and save the start- and end-indices of each face
Ndim = [Ny Nx;Ny Nx;Nz Nx; Nz Nx; Nz Ny; Nz Ny];
% Dimensions for each face

And then after evaluation of x into the variables Px, Py and Pz:

hold on
for k=1:length(Kstart)
    Kcurr = Kstart(k):Kend(k);
    % Index range of the points for the k-th face
    surf(reshape(Px(Kcurr), Ndim(k,:)), ...
         reshape(Py(Kcurr), Ndim(k,:)), ...
         reshape(Pz(Kcurr), Ndim(k,:)), ...
         k*ones(Ndim(k,:)), 'EdgeColor', 'none');
    % surf each face assigning color k to face k for distinction

This produces the following image:

enter image description here
Note that the red line is where two faces meet inside the figure.

  • $\begingroup$ That's very nice, using Kstart like that was very clever! $\endgroup$ – David Feb 11 '15 at 21:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.