Unsimultan​eously-cha​nging color semi-transparent surfaces

6 views (last 30 days)
Hello, can anyone help me? I'd like to graph two semi-transparent spheres changing periodically, discreetely and simultaneously colors from red to black to blue according to the sign of cos(t), where t is flowing time in a for loop but with my following code the two spheres change coloros not simultaneously if facealpha is not equal to 1 (or very closely to 1 values like 0.999), for example if facealpha = 0.2 (I need it working with facealpha = 0.2).
[x,y,z]=sphere();
facealpha=0.2;
for i=0:1000
psi=cos(i);
hold on
if psi>0
surf(x,y,z,'Facealpha',facealpha,'EdgeColor','none','Facecolor','red')
surf(x,y,z-5,'Facealpha',facealpha,'EdgeColor','none','Facecolor','red')
elseif psi<0
surf(x,y,z,'Facealpha',facealpha,'EdgeColor','none','Facecolor','blue')
surf(x,y,z-5,'Facealpha',facealpha,'EdgeColor','none','Facecolor','blue')
elseif psi==0
surf(x,y,z,'Facealpha',facealpha,'EdgeColor','none','Facecolor','black')
surf(x,y,z-5,'Facealpha',facealpha,'EdgeColor','none','Facecolor','black')
end
view([45 45])
hold off
pause(0.1)
end

Answers (1)

DGM
DGM on 23 Jun 2025
Edited: DGM on 23 Jun 2025
You're trying to create 2002 surface objects. It's not that they're timed wrong; it's just that you've nuked yourself with graphics lag. Create two objects and update them. Don't create new ones each time.
[x,y,z] = sphere();
facealpha = 0.2;
for k = 0:1000
psi = cos(k);
if psi > 0
facecolor = 'red';
elseif psi < 0
facecolor = 'blue';
elseif psi == 0 % this will never be true
facecolor = 'black';
end
if k == 0
% do the figure setup once on the first pass ...
h(1) = surf(x,y,z,'Facealpha',facealpha,'EdgeColor','none','Facecolor',facecolor);
hold on
h(2) = surf(x,y,z-5,'Facealpha',facealpha,'EdgeColor','none','Facecolor',facecolor);
view([45 45])
axis equal
else
% ... and then just update only the things that change
h(1).FaceColor = facecolor;
h(2).FaceColor = facecolor;
end
pause(0.1)
end
Also, you're taking the cosine of an integer, which seems odd. Even if it weren't an integer, the numeric result will never be equal to zero.
psi = cos(pi/2) % not zero
psi = 6.1232e-17
You'd have to take into consideration some tolerance in your conditions if you wanted to do this.
[x,y,z] = sphere();
facealpha = 0.2;
tol = eps(1); % or something
for k = 0:1000
psi = cos(k);
if psi > tol
facecolor = 'red';
elseif psi < -tol
facecolor = 'blue';
else
facecolor = 'black';
end
% ... and so on
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!