阴影不适用于指定面部颜色的补丁?
Shading does not work with patches specifying face colors?
我不明白为什么下面的代码会抛出警告:
% 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
希望评论足以解释问题——但简而言之,当 属性 FaceVertexCData
指定面的颜色而不是顶点的颜色时,面颜色的插值似乎不起作用.
如警告消息所述,如果您想使用 'interp'
着色方法,您需要让您的 FaceVertexCData
为每个 顶点.目前,每张脸都有一个条目。
patch( 'Vertices', V, 'Faces', F, 'FaceVertexCData', rand( size(V,1), 1 ) );
shading('interp')
这不是问题或错误,因为 shading
将补丁对象的 FaceColor
property 设置为 'interp'
,这明确要求 [=12= 中有一个条目] 对于每个顶点。
'interp'
— Interpolate the color across each face. First, specify CData
or FaceVertexCData
as an array containing one value per vertex. Determine the face colors by using a bilinear interpolation of the values at each vertex.
仅供参考,如果要将每个面的颜色向量转换为每个顶点的颜色向量,可以使用以下函数:
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
这个函数接受输入:
- 一个
Nfaces x 1
颜色列向量 cdata
,
- 一个
Nfaces x 3
顶点索引数组(每行一个三角形),
- 可选的顶点数量,它将覆盖输出的大小(否则从面索引推断)。
和 returns Nvertices x 1
颜色列向量,这样对于每个顶点,颜色在包含它的面上平均。
我不明白为什么下面的代码会抛出警告:
% 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
希望评论足以解释问题——但简而言之,当 属性 FaceVertexCData
指定面的颜色而不是顶点的颜色时,面颜色的插值似乎不起作用.
如警告消息所述,如果您想使用 'interp'
着色方法,您需要让您的 FaceVertexCData
为每个 顶点.目前,每张脸都有一个条目。
patch( 'Vertices', V, 'Faces', F, 'FaceVertexCData', rand( size(V,1), 1 ) );
shading('interp')
这不是问题或错误,因为 shading
将补丁对象的 FaceColor
property 设置为 'interp'
,这明确要求 [=12= 中有一个条目] 对于每个顶点。
'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.
仅供参考,如果要将每个面的颜色向量转换为每个顶点的颜色向量,可以使用以下函数:
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
这个函数接受输入:
- 一个
Nfaces x 1
颜色列向量cdata
, - 一个
Nfaces x 3
顶点索引数组(每行一个三角形), - 可选的顶点数量,它将覆盖输出的大小(否则从面索引推断)。
和 returns Nvertices x 1
颜色列向量,这样对于每个顶点,颜色在包含它的面上平均。