Skip to content

Instantly share code, notes, and snippets.

@0xlitf
Created October 20, 2023 14:56
Show Gist options
  • Save 0xlitf/e720b00cb0dc9bde21d2b63d4688ac56 to your computer and use it in GitHub Desktop.
Save 0xlitf/e720b00cb0dc9bde21d2b63d4688ac56 to your computer and use it in GitHub Desktop.
% 作者:IC设计者笔记
% 链接:https://www.zhihu.com/question/301995846/answer/3012429972
% 来源:知乎
% 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
clc;clear;
h1=figure('name','太阳系模型','position',[0 25 2000 1200],'color',[0 0 0]);
xlabel('x');ylabel('y');zlabel('z');
[x,y,z]=sphere;
hold on;
axis equal;
set(gca,'xlim',[-13 13],'ylim',[-13 13],'zlim',[-8 8]);%设置坐标系范围
%设置球体大小
r0=2;r1=0.8;r2=1;r3=0.3;r4=0.1;%设置星球半径
x0=r0*x;y0=r0*y;z0=r0*z;%太阳
x01=r1*x;y01=r1*y;z01=r1*z;%金星
x02=r2*x;y02=r2*y;z02=r2*z;%地球
x03=r3*x;y03=r3*y;z03=r3*z;%月球
x04=r4*x;y04=r4*y;z04=r4*z;%金星一号
w=0:0.01*pi:2*pi;
pausetime=0.002;%暂停时间
t=0;uint64(t);%记录时间的参数
Q=pi/4;%月球旋转平面的倾斜角
step=0;%飞船太空旅行所经阶段
stop_time=0;%飞船停止时间
stop_n=100;%飞船到达金星后在进行表面停留stop_n个时间单位
rad_s=0.01*pi;%发射信号所占用角度
signal_rad=0;%信号传播方向角
signal_n=40;%信号时域压缩比
signal_q=0;%信号发射累积角度
signal_q1=0.02*pi;%信号采样间隔
signal_speed=0.1;%信号传播速度
signal_speed_n=int32(r2/signal_q1);%信号传至地球后消失
signal_long=0;%信号距地球距离
mark_4_m=0;%飞船围绕月球旋转标记
moon_s=1;%飞船飞向月球期间,月球转过的圈数
begin_moon=0;%飞船飞向月球标志
s_x=[];s_y=[];s_z=[];%信号采样点数组
tt=0;
long1=6;%太阳和金星间的距离
long2=10;%太阳和地球间的距离
long3=2;%月亮和地球间距
long4=1.5;%飞船和金星的距离
long4_m=0.6;%%飞船和月亮的距离
ship_long=long2-r2;%飞船起始点距太阳中心的距离
ship_long0=long4+long1;%飞船圆周运动时距太阳中心的距离;
ship_long_temp=long2-long1-r1;%飞船与地球的距离
speed1=0.004*pi;%金星运行速度
speed2=0.002*pi; %地球运行速度
speed3=0.03*pi;%月亮运行角速度
ship_speed1=0.02;%飞船直线飞行速度
ship_speed2=speed2;%飞船运行初始角速度
ship_speed_m=0.08*pi;%飞船围绕月亮运行速度
speed_add=0.0003*pi;%控制飞船的加速系数
ship_speed2_max=0.03*pi;%飞船运行最大角速度
ship_n=5;ship_m=5;%飞船围绕金星旋转 ship_n 周后着陆;在金星表面考察ship_m周后返回;
ship_drop=0.01;%飞船着陆速度
ship_Q=0;%飞船围绕月亮运行时的倾斜角
rad4_3=0;%飞船绕月时转过的角度
lamp=0;lamp_n=8;%灯光标记,时间t每隔n次灯光变化一次
ship_rad=pi/4;%地球转至此弧度处时发射飞船
rad1=0-(speed1-speed2)*(ship_rad/speed2+(ship_long-ship_long0)/ship_speed1);
%金星起始的弧度,使飞船刚好可以围绕金星运动
rad2=0;%地球起始弧度
rad3=0;%月球起始弧度
rad4=0;%飞船起始弧度
rad4_z=0;%飞船z向公转起始弧度
rad4_3=0;%飞船围绕月球旋转过的角度
x1=x01+long1*cos(rad1);
y1=y01+long1*sin(rad1);z1=z01;%金星所在处的坐标
%text(0,long1,1.5,'金星');
x2=x02+long2*cos(rad2);
y2=y02+long2*sin(rad2);z2=z02;%地球所在处的坐标
%text(0,long2,1.5,'地球');
x3=x03+long2*cos(rad2)+long3*cos(rad3)*sin(Q);
y3=y03+long2*sin(rad2)+long3*sin(rad3);
z3=z03+long3*cos(rad3)*sin(Q);%月球所在处的坐标
col0=randn(size(z0));%随机取色
hand2=surf(x2,y2,z2,col0);%显示地球
hand1=surf(x1,y1,z1);%显示金星
set(hand1,'facecolor',[0.3 0.6 0.3],'edgecolor',[0.4 0.5 0.4]);
shading interp;%设置颜色为过渡
%get(hand1)
hand3=surf(x3,y3,z3);%显示月球
set(hand3,'facecolor',[0.2 0.2 0.2],'edgecolor','none','facelighting','none');
hand0=surf(2*x0,2*y0,2*z0);%显示太阳
%text(x0,y0,z0,'太阳');
set(hand0,'facecolor','w','edgecolor','w','facelighting','none','markersize',5,'MarkerFaceColor','w');%设置太阳颜色为红色
light('color','w','style','local','position',[0 0 0]);%在太阳中心添加光源
%绘制月球路径跟随线
line3_sx=long2*cos(rad2)+long3*cos(rad3)*sin(Q);
line3_sy=long2*sin(rad2)+long3*sin(rad3);
line3_sz=long3*cos(rad3)*sin(Q);
line3_hand_s=plot3(line3_sx,line3_sy,line3_sz);
line1_x=long1*cos(w);line1_y=long1*sin(w);line1_z=line1_x*0;
plot3(line1_x,line1_y,line1_z,'linewidth',3,'color',[0.4 0.4 0.4]);%绘制金星轨迹线
line2_x=long2*cos(w);line2_y=long2*sin(w);line2_z=line2_x*0;
plot3(line2_x,line2_y,line2_z,'linewidth',3,'color',[0.4 0.4 0.4]);%绘制地球轨迹线
line3_x=long3*cos(w)*cos(Q);line3_y=long3*sin(w);line3_z=long3*cos(w)*sin(Q);
l3_hand=plot3(line2_x,line2_y,line2_z,'linewidth',1.5,'color','b');%绘制月球轨迹线
axis off;
while 1
if rad2>=ship_rad%判断是否发射飞船
switch step
case 0 %初始:发射飞船
rad4=rad2;
x4=x04+ship_long*cos(rad4);%定位飞船初始坐标
y4=y04+ship_long*sin(rad4 );
z4=z04;
hand4=surf(x4,y4,z4);
set(hand4,'facecolor','g','edgecolor','g','facelighting','none');%设置飞船颜色
ship_rad=rad2;%记录飞船发射时地球转过的角度
step=step+1;
case 1 %第一步:飞向金星
x4=x04+ship_long*cos(rad4);%定位飞船坐标
y4=y04+ship_long*sin(rad4 );
rad4=rad4+speed2;%定位飞船公转角度
ship_long=ship_long-ship_speed1;%接近金星
if ship_long<=ship_long0%到达距金星1.5长度的位置后,进入第三步:环绕金星运动
step=step+1;
end;
case 2 %第二步:围绕金星公转
x4=x04+long1*cos(rad1)+long4*cos(rad4);%定位飞船坐标
y4=y04+long1*sin(rad1)+long4*sin(rad4);
z4=z04;
if (rad4<=(ship_n+ship_m)*2*pi)||(mod(rad4-rad1,2*pi)>=(ship_speed2_max-speed1)*pi)
%当飞船围绕金星运行ship_n+ship_m圈,且背离太阳时停止公转
if (ship_speed2<ship_speed2_max)&&(rad4<=ship_n*2*pi)
ship_speed2=ship_speed2+speed_add;%控制飞船加速,加速系数speed_add
end;
if rad4>=ship_n*2*pi%判断飞船是否开始着陆
if long4>r1+r4;%判断飞船是否到达金星地面,若否,则继续降落
long4=long4-ship_drop;
end;
if ship_speed2>speed_add;
ship_speed2=ship_speed2-speed_add;%控制飞船减速
elseif (long4<=r1+r4)&&(stop_time<=0)
ship_speed2=0;
stop_time=t+stop_n;%飞船在金星停留stop_n个时间单位
end;
if (stop_time>0)&&( t>stop_time)&&(ship_speed2<ship_speed2_max)
ship_speed2=ship_speed2+2*speed_add;%控制飞船加速,加速系数speed_add
end;
end;
rad4=rad4+ship_speed2;
elseif (ship_speed2~=0)&&(rad4_z==0)
ship_speed2=0;
else
if ship_speed2<ship_speed2_max
ship_speed2=ship_speed2+speed_add;
end;
if rad4_z<2*pi*3
rad4_z=rad4_z+ship_speed2;
end;
end;
if rad1-rad2>=2*pi%当金星超越地球一周时,进行第三步
step=step+1;
end;
case 3 %离开金星,并向地球传播信息
rad4=rad4+speed2;%飞船与地球同步
ship_long=long1+r1+r4; %找到此时飞船与太阳的距离
if rad2<5*pi/2
while signal_q<2*pi/signal_n%发射8个周期的正弦波
temp_z=sin(signal_q*signal_n)*0.2;%定位波形点
temp_y=ship_long*sin(rad4);
temp_x=ship_long*cos(rad4);
s_z=[s_z,temp_z];s_y=[s_y,temp_y];s_x=[s_x,temp_x];%扩展数组,显示正弦信号的产生过程
s_x=s_x+signal_q1*cos(rad4);s_y=s_y+signal_q1*sin(rad4);%正弦波向前运动
if (signal_q==0)&&(signal_long<=ship_long);
signal_hand=plot3(s_x,s_y,s_z);signal_rad=rad4;
set(signal_hand,'color',[1 0 0]);
signal_long=ship_long;
else
set(signal_hand,'XData',s_x,'YData',s_y,'ZData',s_z);signal_long=signal_long+signal_q1;
end;
signal_q=signal_q+signal_q1;
end;
signal_q=0;
end;
s_x=s_x+signal_speed*cos(rad4);
s_y=s_y+signal_speed*sin(rad4);
set(signal_hand,'XData',s_x,'YData',s_y,'ZData',s_z);
signal_long=signal_long+signal_speed;
if signal_long>long2
if length(s_x)>signal_speed_n
s_x(1:signal_speed_n)=[];
s_y(1:signal_speed_n)=[];
s_z(1:signal_speed_n)=[];
signal_long=signal_long-r2;
else
set(signal_hand,'color',[0 0 0]);
step=step+1;
end;
end;
x4=x04+ship_long*cos(rad4);y4=y04+ship_long*sin(rad4 );
case 4 %飞向地球
if ship_long<long2
ship_long=ship_long+ship_speed1;
end;
x4=x04+ship_long*cos(rad4);y4=y04+ship_long*sin(rad4 );
rad4=rad4+speed2;
end;
set(hand4,'XData',x4,'YData',y4);
if mod(t,lamp_n)==0%t每隔lamp_n次灯光变化一次
lamp=~lamp;
end;
if lamp
set(hand4,'facecolor','g','edgecolor','g','facelighting','none');
else
set(hand4,'facecolor','r','edgecolor','r','facelighting','none');
end;
end;
rad1=rad1+speed1;
rad2=rad2+speed2;
rad3=rad3+speed3;
x1=x01+long1*cos(rad1);y1=y01+long1*sin(rad1);
set(hand1,'XData',x1,'YData',y1);%移动金星位置
x2=x02+long2*cos(rad2);y2=y02+long2*sin(rad2);%地球所在处的坐标
set(hand2,'XData',x2,'YData',y2);%移动地球位置
x3=x03+long2*cos(rad2)+long3*cos(rad3)*cos(Q);
y3=y03+long2*sin(rad2)+long3*sin(rad3);
z3=z03+long3*cos(rad3)*sin(Q);%月球所在处的坐标
set(hand3,'XData',x3,'YData',y3,'ZData',z3);%移动月球位置
line3_x=long3*cos(w)*cos(Q)+long2*cos(rad2);line3_y=long3*sin(w)+long2*sin(rad2);
set(l3_hand,'XData',line3_x,'YData',line3_y,'ZData',line3_z);%绘制月球轨迹线
%扩充月亮跟随线,当线到达一定长度后停止增长
line3_sx=[line3_sx,long2*cos(rad2)+long3*cos(rad3)*cos(Q)];
line3_sy=[line3_sy,long2*sin(rad2)+long3*sin(rad3)];
line3_sz=[line3_sz,long3*cos(rad3)*sin(Q)];
if (length(line3_sx)>10*pi/speed3)
line3_sx(1)=[];
line3_sy(1)=[];
line3_sz(1)=[];
end;
%set(line3_hand_s,'XData',line3_sx,'YData',line3_sy,'ZData',line3_sz,'color',[1 0 0]);
pause(pausetime);
t=t+1;
drawnow;
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment