2016-12-10 3 views
0

Je ne comprends pas pourquoi le code suivant lance un avertissement:L'ombrage ne fonctionne pas avec les correctifs spécifiant les couleurs de la face?

% 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 

Espérons que les commentaires sont suffisamment d'explications pour comprendre la question - mais brièvement, il semble que l'interpolation de couleur du visage ne fonctionne pas lorsque la propriété FaceVertexCData spécifie les couleurs des faces et non des sommets.

Répondre

0

Pour votre information, si vous voulez convertir un vecteur de couleurs pour chaque face à un vecteur de couleurs pour chaque sommet, vous pouvez utiliser la fonction suivante:

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 

Cette fonction prend en entrée:

  • un vecteur colonne Nfaces x 1 de couleurs cdata,
  • un réseau Nfaces x 3 des indices de sommets (un triangle par rangée),
  • éventuellement le nombre de sommets, ce qui écrase la taille de la sortie (autrement déduit des indices de face).

et renvoie un vecteur de couleurs Nvertices x 1 de sorte que pour chaque sommet, la couleur soit moyennée sur les faces qui la contiennent.

1

Comme l'indique le message d'avertissement, si vous souhaitez utiliser la méthode d'ombrage 'interp', vous devez avoir votre FaceVertexCData ont une entrée pour chaque sommet. Actuellement, vous avez une entrée pour chaque visage.

patch('Vertices', V, 'Faces', F, 'FaceVertexCData', rand(size(V,1), 1)); 
shading('interp') 

Ce n'est pas un problème ou un bug, car shading définit la FaceColor property de l'objet de patch pour 'interp' qui exige explicitement qu'il y ait une entrée dans FaceVertexCData pour chaque sommet.

'interp' - Interpole la couleur sur chaque face. D'abord, spécifiez CData ou FaceVertexCData sous la forme d'un tableau contenant une valeur par sommet. Déterminer les couleurs de la face en utilisant une interpolation bilinéaire des valeurs à chaque sommet.

+0

Votre réponse me fait sourire parce que c'est exactement ce que dit l'avertissement; Je peux lire, mais je ne comprends pas pourquoi c'est le cas? Il est "légal" (selon la documentation) de spécifier "FaceVertexCData" pour chaque visage, et la documentation pour "ombrage" ne mentionne aucun problème particulier avec l'option "interp". Pensez-vous que c'est un bug et si non, pourquoi n'y aurait-il aucune mention de ce problème dans la documentation? – Sheljohn

+0

S'il vous plaît ne le prenez pas personnellement, et laissez-moi savoir si ma question n'est pas claire (j'ai ajouté du texte sous l'extrait), mais je vais downvote votre réponse parce que je ne pense pas que ce soit utile. – Sheljohn

+0

@Sheljohn Ce n'est pas un bug. J'ai inclus des liens vers la documentation officielle et ajouté un extrait qui définit explicitement le comportement – Suever