Search code examples
matlabfunction3dcontourimplicit

contours of an implicit function f(x,y,z)=0 in MATLAB


I've already known how to plot a 3d implicit function f(x,y,z)=0 by using the isosurface function. Now I'm curious about how to draw contours of it. Like this one:

f(x,y,z) = sin((x.*z-0.5).^2+2*x.*y.^2-0.1*z) - z.*exp((x-0.5-exp(z-y)).^2+y.^2-0.2*z+3)

enter image description here


Solution

  • You could numerically run over Z and look for when the sign changes, creating a matrix that holds the Z value, it's not elegant, but it works.

    %Create function to evaluate
    eq=eval(['@(x,y,z)',vectorize('sin((x*z-0.5)^2+2*x*y^2-0.1*z) - z*exp((x-0.5-exp(z-y))^2+y^2-0.2*z+3)'),';'])
    
    %Create grid of x and y values
    [x,y]=meshgrid(0:0.01:15,-2:0.01:2);
    
    %Create dummy to hold the zero transitions
    foo=zeros(size(x));
    
    %Run over Z and hold the values where the sign changes
    for i=0:0.001:0.04
        aux=eq(x,y,i)>0;
        foo(aux)=i;
    end
    
    %Contour those values
    contour(foo)
    

    Edit: I found a slightly more elegant solution using the function scatteredInterpolant

    %Create function to evaluate
    eq=eval(['@(x,y,z)',vectorize('sin((x*z-0.5)^2+2*x*y^2-0.1*z) - z*exp((x-0.5-exp(z-y))^2+y^2-0.2*z+3)'),';']);
    
    %Create grid to evaluate volume
    [xm,ym,zm]=meshgrid(0:0.1:15,-2:0.1:2,-0.01:0.001:0.04);
    
    $Find the isosurface
    s=isosurface(xm,ym,zm,eq(xm,ym,zm), 0);
    
    $Use the vertices of the surface to create a interpolated function
    F=scatteredInterpolant(s.vertices(:,1),s.vertices(:,2),s.vertices(:,3));
    
    %Create a grid to plot
    [x,y]=meshgrid(0:0.1:15,-2:0.1:2);
    
    %Contour this function
    contour(x,y, F(x,y),30)