Search code examples
matlabmatlab-figure

Matlab figure problems: half scatter points, black lines inside a red region


Consider the following figure in Matlab (matrices here)

load matrices
%Rb, vertices_deg, vertices_comp

close all
patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal 
axis([0 1 0 1 0 1])
view(120,30)
hold on

T = delaunayTriangulation(Rb.');
K = convexHull(T);
patch('Faces',K,'Vertices',T.Points,'FaceColor','k','edgecolor','k');
hold on

scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3),100,'o','filled','b')
hold on

patch(vertices_comp(:,1), vertices_comp(:,2) , vertices_comp(:,3),'red')
hold off

xlim([0 1])
ylim([0 1])
zlim([0,1])
box on
set(gca, 'ytick',0:0.2:1,'xtick',0:0.2:1,'ztick',0:0.2:1,'FontSize',13)

I would like to save this figure in a way such that:

  • within the red region, I do not get the black lines that I can see in the Matlab output

  • the blu scatter point is a full circle (and not half circle, as it appears in the Matlab output)

I tried two ways of saving the figure

saveas(gcf,'3.jpg')
print(gcf, '3.jpg', '-dpng', '-r300', '-painters') 

None of these two gives me what I want. Could you help?

This is what I get with PRINT enter image description here

This is what I get with SAVEAS enter image description here

And here a screenshot of the Matlab window enter image description here


Solution

  • The problem you are seeing is that the patches are plotted at the exact same plane, which causes this render effect. This is called Z-fighting.

    An easy fix is to add some small offset to some of the planes that are drawn in front of the others. You can tweak this value till the effect is gone, and the error from the indented place is minimal.

    load matrices
    
    close all
    patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
    axis equal 
    axis([0 1 0 1 0 1])
    view(120,30)
    hold on
    
    T = delaunayTriangulation(Rb.');
    K = convexHull(T);
    
    d_patch = 0.001;
    d_z = 0.01;
    
    patch('Faces',K,'Vertices',T.Points + d_patch,'FaceColor','k','edgecolor','k');
    patch(vertices_comp(:,1), vertices_comp(:,2) , vertices_comp(:,3)+d_z,'red')
    
    scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3),100,'o','filled','r')
    scatter3(vertices_deg(:,1), vertices_deg(:,2) , vertices_deg(:,3)+2*d_z,100,'o','filled','b')
    
    xlim([0 1])
    ylim([0 1])
    zlim([0,1])
    box on
    set(gca, 'ytick',0:0.2:1,'xtick',0:0.2:1,'ztick',0:0.2:1,'FontSize',13)
    
    saveas(gcf,'3saveas.png')
    print(gcf, '3print.png', '-dpng', '-r300', '-painters') 
    

    You can do the same for the blue dot, which is partially drawn into the plane. Just give it a little offset, and it appears as a full dot again. I plotted the dot in red and blue, so you can see the offset in location.

    enter image description here