2

我已经编写了这段代码,它制作了 2 个椭圆体的动画。

这些椭球的参数 k1 必须取决于时间(因此它们会异步移动),但我需要在一个图中为它们设置动画。我可以使用循环还是使用计时器和某种回调函数更好?

第二个问题 - 我需要移动内椭球,这样它们就有一个共同的一面。我怎样才能做到这一点?

4

3 回答 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 回答