我正试图创建一个太阳系模拟,并希望行星以不同的速度移动,但当我尝试这样做时,行星会单独绘制并导致故障。(我的代码包含所有行星(我怎样才能让这次跑步更顺利?
close all
%Set broadly used variables
t =-pi:0.01:pi;
y0 = 0;
d = linspace(0,2*pi,629);
%Data for planets
%Mercury
x0_mu = 1.17;
a_mu = 3;
b_mu = 2.95;
x_mu = x0_mu+a_mu*cos(t);
y_mu = y0+b_mu*sin(t);
%Venus
x0_v = 0.0689;
a_v = 5;
b_v = 4.97;
x_v = x0_v+a_v*cos(t);
y_v = y0+b_v*sin(t);
%Creating animation
for k=1:length(d)
clf
dk = d(k);
%Sun
plot(0,0,'yo','LineWidth', 1, 'Markersize', 20, 'MarkerFaceColor', [0.9290 0.6940 0.1250])
hold on
for k=1:length(d)
%Mercury
xmuk = x_mu(k);
ymuk = y_mu(k);
plot(xmuk,ymuk,'ro', 'Markersize', 4, 'MarkerFaceColor', [0.8500 0.3250 0.0980]);
hold on
plot(x_mu,y_mu, 'k');
hold on
pause(0.01)
end
for k=1:length(d)
%Venus
xvk = x_v(k);
yvk = y_v(k);
plot(xvk,yvk,'yo', 'Markersize', 7, 'MarkerFaceColor', [0.9290 0.6940 0.1250]);
hold on
plot(x_v,y_v, 'k');
hold on
pause(0.05)
end
end
在k
上有一个循环,而在k
上有一个子循环,这毫无意义。您需要在k
上进行一个循环,并在其中更新该时间步长的每个行星的位置。
在这里,我修改了您的代码(我也更改了一些变量名,使其更可读(:
close all
% Set broadly used variables
phi = linspace(0,2*pi,1000);
y0 = 0;
t_e = 365.256; % Earth period, in Earth days
% Data for planets
% Mercury
x0_mu = 1.17;
a_mu = 3;
b_mu = 2.95;
t_mu = 87.9691; % period, in Earth days
x_mu = x0_mu + a_mu * cos(phi);
y_mu = y0 + b_mu * sin(phi);
sz_mu = 4;
% Venus
x0_v = 0.0689;
a_v = 5;
b_v = 4.97;
t_v = 224.701;
x_v = x0_v + a_v * cos(phi);
y_v = y0 + b_v * sin(phi);
sz_v = 7;
% Creating animation
for t = 1:t_e % simulate one earth year (t is in Earth days)
clf
hold on
% Sun
plot(0,0,'yo','LineWidth', 1, 'Markersize', 20, 'MarkerFaceColor', [0.9290 0.6940 0.1250])
% Mercury
xmuk = interp1(phi, x_mu, mod(t / t_mu, 1) * 2 * pi);
ymuk = interp1(phi, y_mu, mod(t / t_mu, 1) * 2 * pi);
plot(xmuk,ymuk,'ro', 'Markersize', sz_mu, 'MarkerFaceColor', [0.8500 0.3250 0.0980]);
plot(x_mu,y_mu, 'k');
% Venus
xvk = interp1(phi, x_v, mod(t / t_v, 1) * 2 * pi);
yvk = interp1(phi, y_v, mod(t / t_v, 1) * 2 * pi);
plot(xvk,yvk,'yo', 'Markersize', sz_v, 'MarkerFaceColor', [0.9290 0.6940 0.1250]);
plot(x_v,y_v, 'k');
pause(0.05)
end
我们在变量t
中以天(地球日(为单位计算时间。在每个时间点(每天一次(,我们计算每个行星绕轨道的位置,并在该位置绘制行星。新变量t_mu
和t_v
是每颗行星的周期(以天为单位(。
但是,为了使动画真正平滑,最好不要每次迭代都删除绘图,而是移动绘制的元素。这要简单得多:
close all
% Set broadly used variables
phi = linspace(0,2*pi,1000);
y0 = 0;
t_e = 365.256; % Earth period, in Earth days
clf
hold on
% Sun
plot(0,0,'yo','LineWidth', 1, 'Markersize', 20, 'MarkerFaceColor', [0.9290 0.6940 0.1250])
% Mercury
x0_mu = 1.17;
a_mu = 3;
b_mu = 2.95;
t_mu = 87.9691; % period, in Earth days
x_mu = x0_mu + a_mu * cos(phi);
y_mu = y0 + b_mu * sin(phi);
sz_mu = 4;
plot(x_mu, y_mu, 'k');
mu = plot(x_mu(1), y_mu(1), 'ro', 'Markersize', sz_mu, 'MarkerFaceColor', [0.8500 0.3250 0.0980]);
% Venus
x0_v = 0.0689;
a_v = 5;
b_v = 4.97;
t_v = 224.701;
x_v = x0_v + a_v * cos(phi);
y_v = y0 + b_v * sin(phi);
sz_v = 7;
plot(x_v ,y_v, 'k');
v = plot(xvk(1), yvk(1), 'yo', 'Markersize', sz_v, 'MarkerFaceColor', [0.9290 0.6940 0.1250]);
% Creating animation
for t = 1:t_e % simulate one earth year (t is in Earth days)
pause(0.05)
% Mercury
xmuk = interp1(phi, x_mu, mod(t / t_mu, 1) * 2 * pi);
ymuk = interp1(phi, y_mu, mod(t / t_mu, 1) * 2 * pi);
set(mu, 'xdata', xmuk, 'ydata', ymuk);
% Venus
xvk = interp1(phi, x_v, mod(t / t_v, 1) * 2 * pi);
yvk = interp1(phi, y_v, mod(t / t_v, 1) * 2 * pi);
set(v, 'xdata', xvk, 'ydata', yvk);
end
下一个扩展是创建一个包含行星信息的数组,并在行星上循环,这样就没有变量mu
、v
、e
等,而是p(1)
、p(2)
、p(3)
等。这将避免大量重复代码:
phi = linspace(0,2*pi,1000);
y0 = 0;
t_e = 365.256; % Earth period, in Earth days
p = [];
% Mercury
p(1).x0 = 1.17;
p(1).a = 3;
p(1).b = 2.95;
p(1).period = 87.9691;
p(1).size = 4;
p(1).color = [0.8500 0.3250 0.0980];
% Venus
p(2).x0 = 0.0689;
p(2).a = 5;
p(2).b = 4.97;
p(2).period = 224.701;
p(2).size = 7;
p(2).color = [0.9290 0.6940 0.1250];
% etc.
nplanets = numel(p);
% Plot orbits and planets
close all
clf
hold on
plot(0,0,'yo','LineWidth', 1, 'Markersize', 20, 'MarkerFaceColor', [0.9290 0.6940 0.1250])
for ii=1:nplanets
p(ii).x = p(ii).x0 + p(ii).a * cos(phi);
p(ii).y = y0 + p(ii).b * sin(phi);
plot(p(ii).x, p(ii).y, 'k');
p(ii).h = plot(p(ii).x(1), p(ii).y(1), 'ro', 'Markersize', p(ii). size, 'MarkerFaceColor', p(ii).color);
end
% Animate planets
for t = 1:t_e % simulate one earth year (t is in Earth days)
pause(0.05)
for ii=1:nplanets
a = mod(t / p(ii).period, 1) * 2 * pi;
x = interp1(phi, p(ii).x, a);
y = interp1(phi, p(ii).y, a);
set(p(ii).h, 'xdata', x, 'ydata', y);
end
end