Search code examples
matlabplottriangulation

Coloring Triangulation from Set of Points


I have a matrix with n rows and 4 columns. The first 3 columns indicate the x,y,z position of a point. The last column indicates a colour value, 'p', for that point.

Is there any way to plot the triangulation of these points with the colour of the surface of each triangle defined by 'p'? Or perhaps the colour defined by the average of the 'p' values that went into creating that particular triangular surface?

I've tried a few of the options from the documentation, to no avail.

My attempt:

interiorPoints = [matrix(:,1),matrix(:,2),matrix(:,3)];
DT = DelaunayTri(interiorPoints); 
hullFacets = convexHull(DT);
c=matrix(:,4);
trisurf(hullFacets,DT.X(:,1),DT.X(:,2),DT.X(:,3),c)

But I get an error:

Warning: Error creating or updating Patch

Error in value of property FaceVertexCData

Number of colors must equal number of vertices or faces


Solution

  • Why the trisurf(x,y,z,c) approach isn't working

    You can't use the trisurf(x,y,z,c) approach because c has to be the same length as your Triangulation matrix, which it won't be. This is because you won't generate the same number of triangular faces from your matrix as you have points in your matrix.

    It's worth mention that it's not recommended (says so in the documentation) that you use MATLAB DelaunayTri() function. Instead, you should use MATLAB's delaunayTriangulation() function.

    A Working Approach to Coloring Triangular Surfaces

    Below, I have detailed / commented a block of code that will color the triangular surfaces drawn from your interiorPoints variable according to the color values stored in the 4th column of your matrix variable.

    In this code, I have mapped the color values to varying shades of blue and I have mapped the color values to MATLAB's jet color map. If you would like, you could create 5th and 6th columns in your matrix variable so that you can specify the R, G, and B color components for more vibrant color mappings:

    interiorPoints = [matrix(:,1),matrix(:,2),matrix(:,3)];
    c=matrix(:,4);
    
    % MATLAB recommends that you use delaunayTriangle...
    % DT = DelaunayTri(interiorPoints); 
    
    DT = delaunayTriangulation(x,y,z)
    hullFacets = convexHull(DT)
    
    % Create an empty RGB colormap
    custom_cm = zeros(length(c),3);
    % Or, instead of creating an empty color map, you could modify one of MATLAB's available color maps
    modify_cm = colormap(jet) % Replace 'jet' with any other of MATLAB's available color maps 
    
    % "B" is the 3rd component of this RGB color map
    custom_cm(:,3) = ((c-min(c))/(max(c)-min(c))*length(c)) / length(c)
    
    % Expand the scaled custom_cm column for multiplication with the original color matrix
    cm_multiplier = repmat(custom_cm(:,3), 1, 3);
    % Multiply element-wise the expanded custom_cm with the original color matrix
    modify_cm = cm_multiplier.*modify_cm;
    
    trisurf(hullFacets, DT.Points(:,1), DT.Points(:,2), DT.Points(:,3))
    
    % Use the entirely custom color mapping
    colormap(custom_cm)
    
    % Or, use the modified color mapping
    colormap(modify_cm)
    

    I don't have the data stored in your matrix variable, so I triangulated some sample data and colored it according to a random set of data I generated as a 4th column. Here's how it came out looking using the entirely custom color map:

    Sample plot of Delaunay triangulation, colored according to custom color map

    Here's how it came out looking using the modified jet color map: Sample plot of Delaunay triangulation, colored according to modified <code>jet</code> color map

    I hope this helps, happy coding!