quiver3Dpatch
Below is a demonstration of the features of the quiver3Dpatch function
Contents
- Plotting a vector
- Defining vector lengths and colours
- Example visualising coordinate system base vectors
- Example visualising face normals of patch data
- Example for multidimensional image data 1: colormap driven vectors combined with RGB driven iso-surfaces
- Example for multidimensional image data 2: RGB driven vectors combined with colormap driven iso-surfaces
clear; close all; clc;
Plot settings
cMap=jet(250); faceAlpha1=1; faceAlpha2=1; edgeColor1='none'; edgeColor2='none'; cMap1=gjet(250); cMap2=gray(250); fontSize=8;
Plotting a vector
Below is a visualisation of the basec vector style
%Defining a single vector colinear with the Z-axis with length 2 X=0; Y=0; Z=0; %Vector origin (position vector components) u=0; v=0; w=2; %Vector components G=sqrt(u.^2+v.^2+w.^2); %Vector magnitude cLim=[0 max(G(:))]; Cv=[]; %If empty then vector magnitude based scaling is used a=[min(G(:)) max(G(:))]; %Arrow length scaling to magnitude range [F1,V1,C1]=quiver3Dpatch(X,Y,Z,u,v,w,Cv,a); cFigure; title('Basic vector style using 7 vertices and 6 faces'); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); patch('Faces',F1,'Vertices',V1,'EdgeColor','k', 'CData',C1,'FaceColor','flat','FaceAlpha',0.5,'Marker','.','MarkerSize',25); colormap(cMap1); colorbar; caxis(cLim); view(3); grid on; axis equal; axis tight; axis vis3d; set(gca,'FontSize',fontSize);

Defining vector lengths and colours
a=[min(G(:)) max(G(:))]; %Arrow length scaling to magnitude range [F1,V1,C1]=quiver3Dpatch(X,Y,Z,u,v,w,Cv,a); a=[1 1]; %Arrow length scaling min=1, max=1 [F2,V2,C2]=quiver3Dpatch(X,Y,Z,u,v,w,Cv,a); a=[min(G(:)) max(G(:))]; %Arrow length scaling to magnitude range Cv=zeros(size(X)); [F3,V3,C3]=quiver3Dpatch(X,Y,Z,u,v,w,Cv,a); C4=gray2RGBColorMap(C3,cMap2,cLim); cFigure; subplot(2,2,1); title('Vector with length and color according to magnitude'); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); patch('Faces',F1,'Vertices',V1,'EdgeColor','k', 'CData',C1,'FaceColor','flat','FaceAlpha',1); colormap(cMap1); colorbar; caxis(cLim); view(3); grid on; axis equal; axis tight; axis vis3d; set(gca,'FontSize',fontSize); subplot(2,2,2); title('Vector with a scaled length but color according to magnitude'); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); patch('Faces',F2,'Vertices',V2,'EdgeColor','k', 'CData',C2,'FaceColor','flat','FaceAlpha',1); colormap(cMap1); colorbar; caxis(cLim); view(3); grid on; axis equal; axis tight; axis vis3d; set(gca,'FontSize',fontSize); subplot(2,2,3); title('Vector with length according to magnitude a user specified colormapo driven color'); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); patch('Faces',F3,'Vertices',V3,'EdgeColor','k', 'CData',C3,'FaceColor','flat','FaceAlpha',1); colormap(cMap1); colorbar; caxis(cLim); view(3); grid on; axis equal; axis tight; axis vis3d; set(gca,'FontSize',fontSize); subplot(2,2,4); title('Vector with length according to magnitude and user specified RGB driven color'); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); patch('Faces',F3,'Vertices',V3,'EdgeColor','k', 'FaceVertexCData',C4,'FaceColor','flat','FaceAlpha',1); view(3); grid on; axis equal; axis tight; axis vis3d; set(gca,'FontSize',fontSize); camlight headlight; lighting phong drawnow;

Example visualising coordinate system base vectors
originBasis1=[0 0 0]; E1=eye(3,3); C1=[2 1 0]; originBasis2=[0 0 0]; E2=[2/3 -1/3 2/3; 2/3 2/3 -1/3; -1/3 2/3 2/3]; C2=[5 4 3]; [Fc1,Vc1,Cc1]=quiver3Dpatch(originBasis1(1)*ones(1,3), originBasis1(2)*ones(1,3), originBasis1(3)*ones(1,3),E1(:,1),E1(:,2),E1(:,3),C1',[1 1]); [Fc2,Vc2,Cc2]=quiver3Dpatch(originBasis2(1)*ones(1,3), originBasis2(2)*ones(1,3), originBasis2(3)*ones(1,3),E2(:,1),E2(:,2),E2(:,3),C2',[1 1]); cFigure; xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); title('Visualizing base vectors','FontSize',fontSize); hp1=patch('Faces',Fc1,'Vertices',Vc1,'EdgeColor','k','FaceColor','flat','FaceVertexCData',Cc1,'FaceAlpha',1); hold on; hp1=patch('Faces',Fc2,'Vertices',Vc2,'EdgeColor','k','FaceColor','flat','FaceVertexCData',Cc2,'FaceAlpha',0.5); hold on; view(3); grid on; axis equal; axis vis3d; view([137.5,24]); set(gca,'FontSize',fontSize); colormap jet; drawnow;

Example visualising face normals of patch data
cFigure; [Fs,Vs,~]=geoSphere(2,1); title('Displaying face normals','FontSize',fontSize); hp=patch('Faces',Fs,'Vertices',Vs,'FaceColor','g'); %Plotting face normals [hn]=patchNormPlot(Fs,Vs,0.3); set(gca,'FontSize',fontSize); view(3); axis tight; axis equal; axis vis3d; axis off; camlight('headlight'); lighting flat;

Example for multidimensional image data 1: colormap driven vectors combined with RGB driven iso-surfaces
Simulating 3D volume and vector data
n=27; [X,Y,Z]=meshgrid(linspace(-4.77,4.77,n)); phi=(1+sqrt(5))/2; M=2 - (cos(X + phi*Y) + cos(X - phi*Y) + cos(Y + phi*Z) + cos(Y - phi*Z) + cos(Z - phi*X) + cos(Z + phi*X));
Simulating vector data
%Vector data here based on the gradient of the image [u,v,w] = gradient(M); G=hypot(hypot(u,v),w); %Vector lenghts %Iso-surface patch data to illustrate joint plotting c_iso1=0; c_iso2=5; [Fi1,Vi1,Ci1] = isosurface(X,Y,Z,M,c_iso1,M); [Fi2,Vi2,Ci2] = isosurface(X,Y,Z,M,c_iso2,M); a=[min(G(:)) max(G(:))]; %Arrow length scaling L=G>0.9; %Logic indices for arrows [Fv,Vv,Cv]=quiver3Dpatch(X(L),Y(L),Z(L),u(L),v(L),w(L),G(L),a); cLim=[min(M(:)) max(M(:))]; %Colorbar limits [Ci1n]=gray2RGBColorMap(Ci1,cMap2,cLim); [Ci2n]=gray2RGBColorMap(Ci2,cMap2,cLim); cFigure; xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); title('Colormap driven vector colors and RGB driven isosurfaces','FontSize',fontSize); patch('Faces',Fv,'Vertices',Vv,'EdgeColor',edgeColor1, 'CData',Cv,'FaceColor','flat','FaceAlpha',1); patch('Faces',Fi1,'Vertices',Vi1,'FaceColor','flat','FaceVertexCData',Ci1n,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha2); hold on; patch('Faces',Fi2,'Vertices',Vi2,'FaceColor','flat','FaceVertexCData',Ci2n,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha2); hold on; colormap(cMap1); colorbar; caxis([min(Cv(:)) max(Cv(:))]); view(3); grid on; axis equal; axis vis3d; set(gca,'FontSize',fontSize); camlight headlight; lighting flat drawnow;

Example for multidimensional image data 2: RGB driven vectors combined with colormap driven iso-surfaces
Angle driven color can also be specified e.g. RGB values indicating vector angle
%Specifying angle dependant RGB type color Xc=repmat(u(L),[6,1]); Yc=repmat(v(L),[6,1]); Zc=repmat(w(L),[6,1]); Crgb=[Xc(:) Yc(:) Zc(:)]; M=sqrt(Crgb(:,1).^2+Crgb(:,2).^2+Crgb(:,3).^2); Crgb=abs(Crgb./(M*ones(1,3))); %Normalising color
Defining a sphere to show the color mapping
[F,V,~]=geoSphere(4,1);
Xs=V(:,1); Ys=V(:,2); Zs=V(:,3);
C=[mean(Xs(F),2) mean(Ys(F),2) mean(Zs(F),2)]; %color for angles
The figure now demonstrates isosurfaces for the image data with overlain the gradient vectors coloured according to their direction
cFigure; subplot(1,2,1); xlabel('X','FontSize',fontSize);ylabel('Y','FontSize',fontSize);zlabel('Z','FontSize',fontSize); title('RGB driven vector colors and colormap driven isosurfaces','FontSize',fontSize); Cv=vecnormalize(Vv); patch('Faces',Fv,'Vertices',Vv,'EdgeColor','none', 'FaceVertexCData',Crgb,'FaceColor','flat','FaceAlpha',1); patch('Faces',Fi1,'Vertices',Vi1,'FaceColor','flat','CData',Ci1,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha2); hold on; patch('Faces',Fi2,'Vertices',Vi2,'FaceColor','flat','CData',Ci2,'EdgeColor',edgeColor2,'FaceAlpha',faceAlpha2); hold on; view(3); grid on; axis equal; axis vis3d; set(gca,'FontSize',fontSize); colormap(cMap2); colorbar; camlight headlight; lighting flat subplot(1,2,2); hp=patch('Faces',F,'Vertices',V); set(hp,'FaceColor','flat','FaceVertexCData',abs(C),'EdgeColor','none','FaceAlpha',1); DCM=eye(3,3); origin=[0 0 0]; [Fa,Va,Ca]=quiver3Dpatch(origin(1)*ones(1,3), origin(2)*ones(1,3), origin(3)*ones(1,3),-DCM(:,1),-DCM(:,2),DCM(:,3),[],[3,3]); hp2=patch('Faces',Fa,'Vertices',Va,'EdgeColor','k','FaceColor','flat','FaceVertexCData',repmat(eye(3,3),6,1),'FaceAlpha',1); hold on; view(3); axis tight; axis square; axis vis3d; view(-45,30); set(gca,'FontSize',fontSize); drawnow; axis off; drawnow;

GIBBON www.gibboncode.org
Kevin Mattheus Moerman, [email protected]
GIBBON footer text
License: https://github.com/gibbonCode/GIBBON/blob/master/LICENSE
GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for image segmentation, image-based modeling, meshing, and finite element analysis.
Copyright (C) 2019 Kevin Mattheus Moerman
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.