How to animate 2 surfaces in Matlab?
I wrote this code which creates an animation from 2 ellipsoids.
The k1 parameter of these ellipsoids should be time dependent (so they will move asynchronously), but I need to animate them in the same figure.Can I use a loop for it or is it better to use a timer and some kind of callback functions?
The second problem is I need to move the inner ellipsoid so they have one side in common. How can i do this?
a source to share
You must use a loop. Most of your time will be spent on graphics and with the "getFrame" command. you can use
profile
to check it out. The for loop will not add significant overhead and is easiest to code and understand
Regarding your second question, I'm not sure what you are asking, but if you want to keep the common point, you must parameterize your surface in terms of radii, tilt angle, etc., and the common point, then just move the point around. You might want to consider the "drawEllipsoid" function, which will simplify and refine your code.
a source to share
The loop seems perfect for the job. The timer will also work.
I'm not sure what you mean when you say there is one side in common. It looks like you are close to adding 5 to X2, but you need the scaling term as they don't have the same shape. Could you clarify?
One sentence. I think you'll be much happier if you move the object creation out of the loop like this:
a=5; b=a; c=10; u = (0:0.05*pi:2*pi)'; %' v = [0:0.05*pi:2*pi]; X = a*sin(u)*cos(v); Y = a*sin(u)*sin(v); Z = c*cos(u)*ones(size(v)); Z(Z>0)=0; % cut upper V1=4/3*pi*a*b*c; d=1/2; e=2^d; a2=a/e; b2=a/e; c2=c; V2=4/3*pi*a2*b2*c2; X2 = a2*sin(u)*cos(v);%-2.5; Y2 = b2*sin(u)*sin(v); Z2 = c2*cos(u)*ones(size(v));%+0.25; Z2(Z2>0)=0; % cut h=1/3; hS1=surf(X,Y,Z); alpha(.11) hold on hS2=surf(X2,Y2,Z2); hold off axis([-20 20 -20 20 -20 20]); for j = 1:20 k1=(sin(pi*j/20)+0.5)^h; a=a*k1; c=c*k1; X = a*sin(u)*cos(v); Y = a*sin(u)*sin(v); Z = c*cos(u)*ones(size(v)); Z(Z>0)=0; a2=a2*k1; b2=a2*k1; c2=c2*k1; X2 = a2*sin(u)*cos(v)+5;%-2.5; Y2 = b2*sin(u)*sin(v); Z2 = c2*cos(u)*ones(size(v));%+0.25; Z2(Z2>0)=0; set(hS1,'XData',X,'YData',Y,'ZData',Z); set(hS2,'XData',X2,'YData',Y2,'ZData',Z2); drawnow; F(j) = getframe; end movie(F,4)
Pulling in here isn't necessary because getframe contains one, but it's good to embed it so you can see what happens if you remove getframe.
a source to share
OK, here's the shortcut for creating a clipped surface that I mentioned in my previous comment. What you are going to do is inject NaNs into coordinates wherever the surface is outside the domain. Then any squares that touch these coordinates will drop out on the surface object. It doesn't give you a nice clean edge, but it's very simple.
a=5; b=a; c=10; u = (0:0.05*pi:pi)'; %' v = [0:0.05*pi:2*pi]; X = a*sin(u)*cos(v); Y = a*sin(u)*sin(v); Z = c*cos(u)*ones(size(v)); Z(Z>0)=0; % cut upper V1=4/3*pi*a*b*c; d=1/2; e=2^d; a2=a/e; b2=a/e; c2=c; V2=4/3*pi*a2*b2*c2; X2 = a2*sin(u)*cos(v);%-2.5; Y2 = b2*sin(u)*sin(v); Z2 = c2*cos(u)*ones(size(v));%+0.25; Z2(Z2>0)=0; % cut h=1/3; hS1=surf(X,Y,Z); alpha(.11) hold on hS2=surf(X2,Y2,Z2); hold off axis([-20 20 -20 20 -20 20]); for j = 1:20 k1=(sin(pi*j/20)+0.5)^h; a=a*k1; c=c*k1; X = a*sin(u)*cos(v); Y = a*sin(u)*sin(v); Z = c*cos(u)*ones(size(v)); Z(Z>0)=0; a2=a2*k1; b2=a2*k1; c2=c2*k1; X2 = a2*sin(u)*cos(v)+5;%-2.5; Y2 = b2*sin(u)*sin(v); Z2 = c2*cos(u)*ones(size(v));%+0.25; Z2(Z2>0)=0; set(hS1,'XData',X,'YData',Y,'ZData',Z); % substitute into implicit form of 1st ellipsoid d = (X2.^2) / a^2 + (Y2.^2) / a^2 + (Z2.^2) / c^2; % and zap any that are outside [0 1] X2(d>1) = nan; Y2(d>1) = nan; Z2(d>1) = nan; set(hS2,'XData',X2,'YData',Y2,'ZData',Z2); drawnow; F(j) = getframe; end movie(F,4)
Note that I also changed the u range. This is because you are actually drawing 2 copies of the surface. This caused some problems with how the transparency was done.
a source to share