matlabplot3dcontourvolume-rendering

Apply transformation to faces/vertices from isosurface and plotting the result


If I have a contour in Matlab obtained

 [f, v] = isosurface(x, y, z, v, isovalue)

is there a clean way to apply a transformation to the surfaces and nicely plot the result as a smooth surface? The transformation T is nonlinear.

I tried to apply the transformation T to both f and vert and use patch but couldn't quite get it to work.


Solution

  • The trick is to apply the transformation on your vertices, but keep the same faces data. This way the faces always link the same points, regardless of their new positions.

    Since there are no sample data I took the Matlab example as a starting point. This is coming from the Matlab isosurface page (very slightly modified for this example):

    %// Generate an isosurface
    [x,y,z,v] = flow;
    fv = isosurface(x,y,z,v,-3) ;
    figure(1);cla
    p1 = patch(fv,'FaceColor','red','EdgeColor','none');
    %// refine the view
    grid off ; set(gca,'Color','none') ; daspect([1,1,1]) ; view(3) ; axis tight ; camlight ; lighting gouraud
    

    This output:
    Original isosurface

    Nothing original so far. Just note that I used the single structure output type fv instead of the 2 separate arrays [f,v]. It is not critical, just a choice to ease the next call to the patch object.

    I need to retrieve the vertices coordinates:

    %// Retrieve the vertices coordinates
    X = fv.vertices(:,1) ;
    Y = fv.vertices(:,2) ;
    Z = fv.vertices(:,3) ;
    

    You can then apply your transformation. I choose a simple one in this example, but any transformation function is valid.

    %// Transform
    X = -X.*Y.^2 ;
    Y = Y.*X ;
    Z = Z*2 ;
    

    Then I rebuild a new structure for the patch which will display the transformed object.
    This is the important bit:

    %// create new patch structure
    fvt.vertices = [X Y Z] ;   %// with the new transformed 'vertices'
    fvt.faces = fv.faces ;     %// but we keep the same 'faces'
    

    Then I display it the same way (well with a slightly different angle for a better view):

    %// Plot the transformed isosurface
    figure(2);cla
    pt = patch( fvt ,'FaceColor','red','EdgeColor','none');
    %// refine the view
    grid off ; set(gca,'Color','none') ; daspect([1,1,1]) ; view(-3,4) ; axis tight ; camlight ; lighting gouraud
    

    Which produces the figure:
    Transformed isosurface

    (If you paste all the code snippet in one file it should run and give you the same output.)