matlabplotmatlab-figure

How to slice a 3D cylinder in MATLAB?


I'm trying to create a function that plots a cylinder with slices at a given angle where:

l - length of a cylinder
d - diameter
a - angle
n - number of slices

Here is what I have so far:

function baguett(l, d, a, n)
  r = d/2;
  [X,Y,Z] = cylinder(r);
  Z = Z*l;
  obj = surf(Z,Y,X);
  hold on
  patch(Z(1,:), Y(1,:), X(1,:), Z(1,:))
  patch(Z(end,:), Y(end,:), X(end,:), Z(end,:))
  axis equal

  [x,y,z] = meshgrid(-l:.2:l,-l:.25:l,-l:.16:l);
  v = x.*exp(-x.^2-y.^2-z.^2);
  xslice = [1];
  yslice = [];
  zslice = [];
  slice(x,y,z,v,xslice,yslice,zslice);

It returns this plot:

plot

However what I would like to get is something like this (for 90 angle I guess):

desired_result

Could somebody please help?


Solution

  • If you need control over individual slices, as you seem to indicate in your comment, my recommendation would be:

    It goes like this:

    %% Initial model cylinder
    % Generate a model cylinder, unitary length, assigned radius
    D = 5 ; R = D/2;
    [X,Y,Z] = cylinder(R);
    
    %% Now work out how many copies you need
    L = 12 ;   % Total length of stacked cylinders
    n = 9 ;     % Number of base cylinders/slices to stack
    
    Lu = L / n ;    % Length of a base cylinder/slice
    Z = Z * Lu ;    % Scale base cylinder
    
    %% and stack them up
    
    colCyl = [.8 .8 .8] ;   % light grey
    colEnds = [.7 .7 .7] ;  % darker gray
    
    hold on
    % we run the loop in reverse (from n to 1) to let MATLAB automatically
    % preallocate the graphic handle arrays (without complaining)
    for k=n:-1:1
        % Generate the "Zc" coordinate for each base cylinder
        Zc = Z + (k-1)*Lu ;
        % generate base cylinder, with its end caps, and group graphic handles
        % into one hg object
        hg(k) = hggroup ;
        hs(k) = surf(Zc,X,Y, 'FaceColor',colCyl, 'EdgeColor','none','Parent',hg(k)) ;
        hp(2,n) = patch( Zc(end,:), Y(1,:), X(1,:), Zc(end,:) , 'FaceColor',colEnds, 'Parent',hg(k) ) ;
        hp(1,n) = patch( Zc(1,:)  , Y(1,:), X(1,:), Zc(1,:)   , 'FaceColor',colEnds, 'Parent',hg(k) ) ;
    end
    axis equal ; view(-10,40) ; grid on
    

    This will produce 9 cylinder slices, stacked together to form a cylinder with length L:

    9 cylinder slices

    Now each of your hggroup contains the graphic handle of a base cylinder/slice (s surf object) and its two end caps (2x patch objects). These hggroup are useful to change properties to all the graphic object contained, and even more convenient if you need transformations (rotations or translations).


    A few example of individual slice manipulations:

    %% Now each cylinder can be acted on its own by operating on its hggroup
    % ex1: translate the middle cylinder (#5) upward
    
    hax = gca ;
    t1 = hgtransform('Parent',hax);
    Tz = makehgtform('translate',[0 0 2]);
    
    set( hg(5), 'Parent',t1) ;
    set(t1,'Matrix',Tz) ;
    

    will move the middle slice slightly upward: middle slice up


    %% ex2: make every second slice invisible:
    for k=2:2:n
        set(hg(k),'Visible','off')
    end
    

    slice invisible


    %% ex3: change color of one specific slice
    set(hg(3).Children,'FaceColor','r')
    

    colored slice