Reputation: 7943
I don't understand why the following code throws a warning:
% mesh of a plane at z=0 for x,y in [0,5] with 20 vertices per side
n = 20;
[x,y] = ndgrid( linspace(0,5,n) );
x = x(:); y = y(:); z = zeros(n^2,1);
% triangulation to obtain faces, and draw a patch with random color for each face
F = delaunay(x,y);
V = [x,y,z];
patch( 'Vertices', V, 'Faces', F, 'FaceVertexCData', rand( size(F,1), 1 ) );
axis tight; grid on; box off;
% faceted shading works fine, but interp doesn't seem to work
shading('faceted'); % works fine
shading('interp'); % throws a warning
Warning: Error creating or updating Patch
Error in value of property FaceVertexCData
Number of colors must equal number of vertices
Hopefully the comments are enough explanation to understand the issue -- but briefly, it seems that interpolation of face color does not work when the property FaceVertexCData
specifies the colors of faces and not vertices.
Upvotes: 1
Views: 3513
Reputation: 7943
FYI, if you want to convert a vector of colors for each face to a vector of colors for each vertex, you can use the following function:
function cdata = face2vertex(cdata,faces,nvert)
fmax = max(faces(:));
if nargin < 3, nvert=fmax; end
if size(faces,1)~=3, faces=faces'; end
assert( size(faces,1)==3, 'Bad faces size.' );
assert( size(faces,2)==numel(cdata), 'Input size mismatch.' );
assert( nvert >= fmax, 'Number of vertices too small.' );
faces = faces(:);
cdata = repelem( cdata(:), 3 ); % triplicate face colors
nfpv = accumarray( faces, 1, [nvert,1] ); % #of faces per vertex
cdata = accumarray( faces, cdata, [nvert,1] ) ./ max(1,nfpv);
end
This function takes in input:
Nfaces x 1
column vector of colors cdata
, Nfaces x 3
array of vertex indices (one triangle per row),and returns a Nvertices x 1
column vector of colors such that for each vertex, the color is averaged across the faces that contain it.
Upvotes: 1
Reputation: 65430
As the warning message states, if you want to use the 'interp'
shading method, you need to have your FaceVertexCData
have an entry for each vertex. Currently, you have an entry for each face.
patch( 'Vertices', V, 'Faces', F, 'FaceVertexCData', rand( size(V,1), 1 ) );
shading('interp')
This is not an issue or a bug, because shading
sets the FaceColor
property of the patch object to 'interp'
which explicitly requires that there be an entry in FaceVertexCData
for each vertex.
'interp'
— Interpolate the color across each face. First, specifyCData
orFaceVertexCData
as an array containing one value per vertex. Determine the face colors by using a bilinear interpolation of the values at each vertex.
Upvotes: 2