MATLAB Answers

Make white portions of slice of flow data transparent

조회 수: 5(최근 30일)
Nathaniel H Werner
Nathaniel H Werner 6 Apr 2020
편집: darova 6 Apr 2020
I have created this figure (one of five) with the code (I have edited it for the question) below.
I would like to make the white [1 1 1] portions of the cylinder sections transparent. I know that MatLab cannot work with RGBa in the colormap, so is there some other way to do that? I do not want the entire cylinder surface to be transparent, just the white part. I found this question here which seems to work for png images, but that is not what I am looking for. I'm pretty sure something like what I am asking can be done since I've seen it before but I don't have the source code to work with.
Here is an image from a recent paper Li, C., Dong, H., & Cheng, B. (2020). Tip vortices formation and evolution of rotating wings at low Reynolds numbers. Physics of Fluids, 32(2), 021905.
Correction: I do not know if this figure was made in MatLab.
I cannot load the variables X, Y, Z, or V since they are too large. You can use the flow data built into MatLab.
Please let me know if you have any questions or if there are issues with the code, I will make any necessary edits if I forgot something.
Ny = 1000;
[X,Y,Z,V] = flow(10);
% these variables are needed, I forgot them in the previous version
y = [-0.7344,0.7031];
AoAd = 45;
delta = 1/2*cosd(AoAd);
dt = 0.0258; % Size of time step
dtheta = 7.5; % Differential angle size [deg]
theta = 180 + dtheta;
iso = -3;
for q=1:2
for i=1:3
if ~and(q==2,i==1)
if i==1
AR = 3;
elseif i==2
AR = 5;
elseif i==3
AR = 7;
end
RoLoc = (0.2:0.1:0.9)*AR;
% don't bother to draw the rectangular patch in the image
figure(sub2ind([2,3],q,i))
xlabel('x'), ylabel('y'), zlabel('z')
hold on
fh = gcf();
axh = findall(fh, 'Type', 'Axes');
for r=1:length(RoLoc)
sweep = floor(2.1*Ny*RoLoc(r));
[Xc,Yc,Zc] = cylinder2(RoLoc(r)*ones(1,Ny),[0,1,0],sweep); % you can find this here https://www.mathworks.com/matlabcentral/fileexchange/64007-generate-cylinder-with-custom-axis
H = [1 0 0 0;
0 1 0 min(y); % vertical translation
0 0 1 0;
0 0 0 1]*...
[1 0 0 0;
0 peak2peak(y) 0 0; % vertical stretching
0 0 1 0;
0 0 0 1]*...
[ones(1,Ny);Yc(:,1)';ones(1,Ny);ones(1,Ny)];
Yc = repmat(H(2,1:Ny)',1,sweep+1);
clear H
% angle for part of the cylinder
Phi_prime = atand(delta/RoLoc(r));
theta_prime = linspace(360,0,sweep+1)';
if r==1
T = 3;
elseif r==2
T = 4;
elseif r==3
T = 5;
elseif r>3 && r<6
T = 6;
else
T = 9;
end
theta_q = theta - T*Phi_prime;
clear T
theta_p = theta + 2*Phi_prime;
[~,l] = min(abs(theta_prime - theta_p));
[~,m] = min(abs(theta_prime - theta_q));
Vsli{q,i,r} = slice(axh,X,Y,Z,V,Xc(:,l:m),Yc(:,l:m),Zc(:,l:m),'linear');
Vsli{q,i,r}.EdgeColor = 'none';
% Setup color axis range
V_min(q,i,r) = sign(min(caxis))*ceil(abs(min(caxis))); % min value in flow
V_max(q,i,r) = ceil(max(caxis)); % max value in flow
end
end
end
end
% this portion changes the colors of the cylinder sections
n = 1000;
for q = 1:2
for i = 1:3
if ~and(q==2, i==1)
figure(sub2ind([2,3],q,i))
colorbar
fh = gcf();
axh = findall(fh, 'Type','Axes');
cbh = findall(fh, 'Type', 'ColorBar');
% these numbers are tuned to my data
M1 = nanmin(V_min,[],'all');
M2 = nanmax(V_max,[],'all');
vPmin = 1/3;
vPmax = 1/2;
M1prime = sign(M1)*ceil(abs(vPmin*M1)/5)*5;
M2prime = floor(vPmax*M2/5)*5;
caxis([M1prime,M2prime])
% I have adapted the code for making your own interpolated colormap here https://stackoverflow.com/questions/30851050/how-to-create-an-interpolated-colormap-or-color-palette-from-two-colors
% Set white to be zero with blue as negative and red as positive
n0 = floor(interp1([M1prime,M2prime],[1,n],0)); % interpolate color index to zero
nN2 = floor(interp1([M1prime,M2prime],[1,n],iso-1)); % blue to cyan
nN1 = floor(interp1([M1prime,M2prime],[1,n],iso)); % cyan to white
nP1 = floor(interp1([M1prime,M2prime],[1,n],-iso)); % white to yellow
nP2 = floor(interp1([M1prime,M2prime],[1,n],-(iso-1))); % yellow to red
cmap = zeros(5,3);
cmap(1,:) = [0 0 1]; %// color first row - blue
cmap(2,:) = [0 1 1]; % cyan
cmap(3,:) = [1 1 1]; %// color 1/2*nth row - white
cmap(4,:) = [1 1 0]; % yellow
cmap(5,:) = [1 0 0]; %// color nth row - red
[xcs,ycs] = meshgrid(1:3,1:n); %// mesh of indices
cmapN = interp2(xcs([1,nN2,nN1],:),ycs([1,nN2,nN1],:),[cmap(1:2,:);cmap(2,:)],xcs,ycs); %// interpolate blue to cyan
cmapN(nN1+1:end,:) = [];
cmapZ1 = interp2(xcs([nN1+1,nN1+1+floor((n0-(nN1+1))/2),n0],:),ycs([nN1+1,nN1+1+floor((n0-(nN1+1))/2),n0],:),[cmap(2:3,:);cmap(3,:)],xcs,ycs); %// interpolate cyan to white
cmapZ1(1:nN1,:) = []; Lz1 = length(cmapZ1);
cmapZ1(Lz1-(n-n0)+1:Lz1,:) = [];
cmapZ2 = interp2(xcs([n0+1,n0+1+floor((nP1-(n0+1))/2),nP1],:),ycs([n0+1,n0+1+floor((nP1-(n0+1))/2),nP1],:),[cmap(3,:);cmap(3:4,:)],xcs,ycs); %// interpolate white to yellow
cmapZ2(1:n0,:) = []; Lz2 = length(cmapZ2);
cmapZ2(Lz2-(n-nP1)+1:Lz2,:) = [];
cmapP = interp2(xcs([nP1+1,nP2,n],:),ycs([nP1+1,nP2,n],:),[cmap(4,:);cmap(4:5,:)],xcs,ycs); %// interpolate yellow to red
cmapP(1:nP1,:) = [];
cmapNtot = [cmapN;cmapZ1];
cmapPtot = [cmapZ2;cmapP];
cmap = [cmapNtot;cmapPtot];
colormap(cmap) %// set color map
% I found this pause helps to make sure the colorbar changes, sometimes MatLab doesn't change it without being in debug mode
pause(3)
end
end
end

  댓글 수: 8

표시 이전 댓글 수: 5
Nathaniel H Werner
Nathaniel H Werner 6 Apr 2020
darova, iso = -3. I will include that in the code, I'm very sorry for having to continually make updates. I tried to make a shorter version of the code and things inevitably get left out.
darova
darova 6 Apr 2020
isn't that too much for surface?
my computer couldn't handle it
Nathaniel H Werner
Nathaniel H Werner 6 Apr 2020
No not really. You need high numbers for the grid to make the contours look smooth enough. But feel free to lower them if you have some ideas.

로그인 to comment.

채택된 답변

darova
darova 6 Apr 2020
An example of how to make some faces transparent
[X,Y] = meshgrid(-10:10); % generate mesh
Z = -X.^2-Y.^2; % Z values (paraboloid)
alpha1 = Z*0+1; % alphadata (all '1')
ix = -20 > Z & Z > -60; % find Z values between -20 and -60
alpha1(ix) = 0.5; % assign alpha 0.5 (transparency
h = surf(X,Y,Z,...
'alphadata',alpha1,... % assign alphadata
'facealpha','interp',... % interpolate transparency
'alphadatamapping','none'); % don't know what is this
axis vis3d
Result
See alphadata: LINK

  댓글 수: 3

Nathaniel H Werner
Nathaniel H Werner 6 Apr 2020
unfortunately I have a feeling this will not work, I already tried using something to this effect in R2018b and when I tried changing 'facealpha' to 'interp' it gave me an error.
Nathaniel H Werner
Nathaniel H Werner 6 Apr 2020
Also you can use [X,Y,Z,V] = flow, this would make what you're attempting closer to my original. What release are you using?
darova
darova 6 Apr 2020
Here is an example with using slice
clc,clear
opengl software
[X,Y,Z,V] = flow(20);
xx = linspace(min(X(:)),max(X(:)),50);
yy = linspace(min(Y(:)),max(Y(:)),50);
[X1,Y1] = meshgrid(xx,yy);
Z1 = Y1;
V1 = interp3(X,Y,Z,V,X1,Y1,Z1); % values of flow on plane
h = slice(X,Y,Z,V,X1,Y1,Z1);
alpha1 = Z1*0+1; % alphadata (all '1')
ix = -2 > V1 & V1 > -4; % find V1 values between -2 and -4
alpha1(ix) = 0.5; % assign alpha 0.5 (transparency
set(h,...
'edgecolor','none',...
'alphadata',alpha1,... % assign alphadata
'facealpha','interp',... % interpolate transparency
'alphadatamapping','none'); % don't know what is this
axis vis3d
colorbar

로그인 to comment.

추가 답변(0개)

이 질문에 답변하려면 로그인을(를) 수행하십시오.

제품


릴리스

R2018b

Translated by