我已经编写了这段代码,它制作了 2 个椭圆体的动画。
这些椭球的参数 k1 必须取决于时间(因此它们会异步移动),但我需要在一个图中为它们设置动画。我可以使用循环还是使用计时器和某种回调函数更好?
第二个问题 - 我需要移动内椭球,这样它们就有一个共同的一面。我怎样才能做到这一点?
问问题
1671 次
3 回答
1
您应该使用循环。您的大部分时间将花在绘图和使用“getFrame”命令上。您可以使用
轮廓验证这一点。for 循环不会增加大量开销,并且最容易编码和理解
至于你的第二个问题,我不确定你到底在问什么,但如果你想保持一个共同点,你应该根据半径、倾斜角等参数化你的表面和共同点,然后只是移动点。您可能需要考虑编写一个“drawEllipsoid”函数,它可以简化和阐明您的代码。
于 2010-05-04T12:49:53.717 回答
0
好的,这是我在之前的评论中提到的修整表面的捷径。您要做的是将 NaN 放入域外表面的所有坐标中。然后表面对象将丢弃任何接触这些坐标的四边形。这不会给你一个很好的干净的边缘,但它真的很容易。
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)
请注意,我还更改了 u 的范围。那是因为您实际上绘制了 2 个曲面副本。这导致了透明度如何呈现的一些问题。
于 2010-05-10T14:38:08.957 回答
0
对于这项工作,循环似乎很好。计时器也可以。
当你说“有一个共同的方面”时,我不太清楚你的意思。看起来您已经接近将 5 添加到 X2,但您需要一个缩放项,因为它们的形状不同。你能详细说明一下吗?
不过有一个建议。我认为,如果您将对象创建移出这样的循环,您会更快乐:
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)
drawow 在这里并不是绝对必要的,因为 getframe 包含一个,但最好插入一个,这样您可以在删除 getframe 时看到发生了什么。
于 2010-05-04T14:29:06.830 回答