Can I use interpolated shading on a patch constructed using face data?

11 visualizzazioni (ultimi 30 giorni)
I have a 2D triangular mesh for which I am plotting some variables defined at the vertices, and other variables defined on the faces (technically, at their centroids). I’m using patch as my plotting function in both cases. I’ve noticed that in the former case, I can set the ‘FaceColor’ property to ‘interp’ to achieve a smoother-looking field. In the latter case, however, I get an error when I try that. I presume that this is because there is no clear point from which to interpolate (and in general, interpolation from centroids is more complicated than from vertices).
Still, is there a simple way to achieve a smoother-looking field when the variable is defined on the faces? Code skeleton below:
patch('Faces', f, 'Vertices', v, 'CData', data, 'FaceColor', 'interp', 'EdgeColor', 'none'); % fine
patch('Faces', f, 'Vertices', v, 'FaceVertexCData', data, 'FaceColor', 'interp', 'EdgeColor', 'none'); % produces error:
Warning: Error creating or updating Patch
Error in value of property FaceVertexCData
Number of colors must equal number of vertices

Risposte (1)

Riya
Riya il 19 Gen 2024
Hello David,
When you are defining variables at the centroids of faces and trying to use the patch function to plot them with interpolated colors, you run into the issue because the patch function is designed to interpolate colors across the vertices of the faces, not the centroids.
The FaceVertexCData property is expecting a color value for each vertex, not each face. That's why you are getting an error saying "Number of colors must equal number of vertices." Face and vertex colors, specified as a single color for the entire patch, one color per face, or one color per vertex for interpolated face color.
Following Code describes the usage of ‘patch’ function and ‘FaceVertexCData’:
% Initialize vertex color data with NaNs
vertexCData = nan(size(v, 1), 1);
% Loop over each face
for i = 1:size(f, 1)
% Get the vertices of the current face
faceVertices = f(i, :);
% Calculate the color for this face based on your data
% For example, if 'data' is face-based:
color = data(i);
% Assign or accumulate the color to the vertices
for j = 1:length(faceVertices)
vertexIndex = faceVertices(j);
if isnan(vertexCData(vertexIndex))
vertexCData(vertexIndex) = color;
else
% Average the color if the vertex is shared
vertexCData(vertexIndex) = (vertexCData(vertexIndex) + color) / 2;
end
end
end
% Now plot using the vertex-based color data
patch('Faces', f, 'Vertices', v, 'FaceVertexCData', vertexCData, 'FaceColor', 'interp', 'EdgeColor', 'none');
To achieve a smoother-looking field when the variable is defined on the faces, you can use the 'trisurf' function instead of 'patch'. The 'trisurf' function allows you to specify face-based color data and still achieve a smooth interpolation.
Here is an example of how you can modify your code to use 'trisurf':
trisurf(f, v(:,1), v(:,2), data, 'FaceColor', 'interp', 'EdgeColor', 'none');
Refer following documentation to know more about:
  2 Commenti
David Russell
David Russell il 22 Gen 2024
Hi Riya,
I looked into patch vs. trisurf for this type of plot a while ago, and settled on patch. I’m now trying to reconstruct the reasons, and the first thing I notice is that trisurf produces a 3D plot, while patch can be made to produce a 2D plot (no ‘rotate 3D’ option). Of course, trisurf can be used with zero for all of the z-coordinates, but this seems like overkill. The .fig file size difference between the two methods seems negligible when I do this, but I think 3D plots are more likely to make Matlab freeze on my machine due to a bug in the software (which I have reported).
I will also point out that the default shading for trisurf (at least in my usage) does *not* appear to be smooth, but rather a single color for each face, exactly the problem I was trying to address. With trisurf, I get the same aforementioned error when I input ‘FaceColor’, ‘interp’ as a name-value pair, or when I try to set the ‘FaceColor’ property of the output Patch object.
The kernel of my question is really whether MATLAB has a native method for interpolating from centroids rather than vertices of a triangulation, and if so, how to access it when plotting.
David Russell
David Russell il 22 Gen 2024
By the way, I wouldn't be surprised if MATLAB doesn't have such a method, as it would technically require extrapolation rather than interpolation at the domain boundaries.

Accedi per commentare.

Prodotti


Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by