基于轨道模型计算地木轨道点最短距离及可视化的技术求助
地球与木星轨道最短距离计算及可视化方案
实现思路
- 距离计算:用三维欧几里得距离公式计算每帧地球与木星的位置差,转换成千米单位(原坐标为米,除以1000完成转换)。
- 追踪最短距离:在模拟过程中实时计算并记录最小距离及其对应的帧索引。
- 可视化展示:在动画中添加地球与木星的实时连线并标注当前距离;额外生成静态图专门展示最短距离的连线及数值。
修改后的完整代码
# -*- coding: utf-8 -*- """Earth-Jupiter Orbit Distance Calculator""" # 导入依赖库 import matplotlib.pyplot as plt from matplotlib import animation import matplotlib matplotlib.rcParams['animation.embed_limit'] = 2**128 from IPython.display import HTML import matplotlib as mpl mpl.rcParams.update(mpl.rcParamsDefault) # 定义常量 G = 6.67e-11 Ms = 1.988e30 # 太阳质量 Me = 5.972e24 # 地球质量 Mj = 1.898e27 # 木星质量 AU = 1.5e11 # 天文单位(米) daysec = 24.0*60*60 # 一天的秒数 KM_PER_M = 1e-3 # 米转千米系数 e_ap_v = 29780 # 地球远日点速度(m/s) j_ap_v = 13060 # 木星远日点速度(m/s) gravconst_e = G*Me*Ms gravconst_j = G*Mj*Ms # 初始化位置与速度 # 地球 xe,ye,ze = 0,(1*AU),0 xve,yve,zve = -e_ap_v,0,0 # 木星 xj,yj,zj = 0,(5.2*AU),0 xvj,yvj,zvj = -j_ap_v,0,0 # 太阳 xs,ys,zs = 0,0,0 xvs,yvs,zvs = 0,0,0 t = 0.0 dt = 1*daysec # 每帧时间步长 # 存储轨道数据的列表 xelist,yelist,zelist = [],[],[] xslist,yslist,zslist = [],[],[] xjlist,yjlist,zjlist = [],[],[] # 存储每帧距离的列表 distance_list = [] # 开始轨道模拟 while t < 1*365*daysec: ################ 地球轨道计算 ############# rx,ry,rz = xe - xs, ye - ys, ze - zs modr3_e = (rx**2+ry**2+rz**2)**1.5 fx_e = -gravconst_e*rx/modr3_e fy_e = -gravconst_e*ry/modr3_e fz_e = -gravconst_e*rz/modr3_e # 更新速度 xve += fx_e*dt/Me yve += fy_e*dt/Me zve += fz_e*dt/Me # 更新位置 xe += xve*dt ye += yve*dt ze += zve*dt # 保存位置 xelist.append(xe) yelist.append(ye) zelist.append(ze) ################ 木星轨道计算 ############## rx_j,ry_j,rz_j = xj - xs, yj - ys, zj - zs modr3_j = (rx_j**2+ry_j**2+rz_j**2)**1.5 fx_j = -gravconst_j*rx_j/modr3_j fy_j = -gravconst_j*ry_j/modr3_j fz_j = -gravconst_j*rz_j/modr3_j # 更新速度 xvj += fx_j*dt/Mj yvj += fy_j*dt/Mj zvj += fz_j*dt/Mj # 更新位置 xj += xvj*dt yj += yvj*dt zj += zvj*dt # 保存位置 xjlist.append(xj) yjlist.append(yj) zjlist.append(zj) ################ 太阳轨道计算 ########### # 更新速度(受地球和木星引力影响) xvs += -(fx_e+fx_j)*dt/Ms yvs += -(fy_e+fy_j)*dt/Ms zvs += -(fz_e+fz_j)*dt/Ms # 更新位置 xs += xvs*dt ys += yvs*dt zs += zvs*dt xslist.append(xs) yslist.append(ys) zslist.append(zs) ################ 计算当前地球与木星距离 ########### dx = xe - xj dy = ye - yj dz = ze - zj distance_m = (dx**2 + dy**2 + dz**2)**0.5 distance_km = distance_m * KM_PER_M distance_list.append(distance_km) # 更新时间 t += dt # 找到最短距离及其对应帧 min_distance = min(distance_list) min_frame_idx = distance_list.index(min_distance) print(f"最短距离:{min_distance:.2f} 千米,对应第 {min_frame_idx+1} 天") # 可视化设置 fig, ax = plt.subplots(figsize=(5.8,5.8)) ax.set_aspect('equal') # 轨道与天体样式定义 line_e, = ax.plot([],[],'b',lw=1, alpha=0.5) # 地球轨道(淡蓝色) point_e, = ax.plot([], [], marker="o", markersize=5, markeredgecolor="green", markerfacecolor="blue") text_e = ax.text(0,0,'Earth') line_j, = ax.plot([],[],'r',lw=1, alpha=0.5) # 木星轨道(淡红色) point_j, = ax.plot([], [], marker="o", markersize=7, markeredgecolor="red", markerfacecolor="brown") text_j = ax.text(0,0,'Jupiter') point_s, = ax.plot([], [], marker="o", markersize=10, markeredgecolor="orange", markerfacecolor="yellow") text_s = ax.text(0,0,'Sun') # 地球与木星连线及距离文本 connection_line, = ax.plot([], [], 'g--', lw=1) # 虚线连接 distance_text = ax.text(0, 0, '', fontsize=9) # 轨道数据缓存 exdata,eydata = [],[] jxdata,jydata = [],[] def update(i): # 更新轨道轨迹 exdata.append(xelist[i]) eydata.append(yelist[i]) jxdata.append(xjlist[i]) jydata.append(yjlist[i]) line_e.set_data(exdata,eydata) line_j.set_data(jxdata,jydata) # 更新天体位置与标签 point_e.set_data(xelist[i],yelist[i]) text_e.set_position((xelist[i]+0.1*AU, yelist[i])) point_j.set_data(xjlist[i],yjlist[i]) text_j.set_position((xjlist[i]+0.1*AU, yjlist[i])) point_s.set_data(xslist[i],yslist[i]) text_s.set_position((xslist[i]+0.1*AU, yslist[i])) # 更新连线与距离显示 connection_line.set_data([xelist[i], xjlist[i]], [yelist[i], yjlist[i]]) distance_text.set_text(f"距离:{distance_list[i]:.0f} km") # 把距离文本放在连线中间位置 mid_x = (xelist[i] + xjlist[i])/2 mid_y = (yelist[i] + yjlist[i])/2 distance_text.set_position((mid_x, mid_y)) ax.set_xlim(-5.8*AU,5.8*AU) ax.set_ylim(-5.8*AU,5.8*AU) return line_e, point_e, text_e, line_j, point_j, text_j, point_s, text_s, connection_line, distance_text # 创建动画 anim = animation.FuncAnimation(fig, func=update, frames=len(xelist), interval=20, blit=True) # 显示动画 HTML(anim.to_jshtml()) # 单独绘制最短距离的静态图 plt.figure(figsize=(5.8,5.8)) plt.gca().set_aspect('equal') # 绘制轨道 plt.plot(xelist, yelist, 'b', lw=1, alpha=0.5, label='Earth Orbit') plt.plot(xjlist, yjlist, 'r', lw=1, alpha=0.5, label='Jupiter Orbit') # 绘制天体 plt.scatter(xslist[min_frame_idx], yslist[min_frame_idx], s=200, c='yellow', edgecolor='orange', label='Sun') plt.scatter(xelist[min_frame_idx], yelist[min_frame_idx], s=100, c='blue', edgecolor='green', label='Earth') plt.scatter(xjlist[min_frame_idx], yjlist[min_frame_idx], s=140, c='brown', edgecolor='red', label='Jupiter') # 绘制最短连线 plt.plot([xelist[min_frame_idx], xjlist[min_frame_idx]], [yelist[min_frame_idx], yjlist[min_frame_idx]], 'g--', lw=2) # 标注最短距离 mid_x = (xelist[min_frame_idx] + xjlist[min_frame_idx])/2 mid_y = (yelist[min_frame_idx] + yjlist[min_frame_idx])/2 plt.text(mid_x, mid_y, f"最短距离:{min_distance:.2f} km", fontsize=10) plt.xlim(-5.8*AU,5.8*AU) plt.ylim(-5.8*AU,5.8*AU) plt.legend() plt.title("Earth-Jupiter Minimum Distance") plt.show()
关键修改说明
- 距离计算模块:在模拟循环中加入三维距离计算,转换为千米单位并存储到列表中。
- 最短距离追踪:用
min()函数找到最小距离,index()获取对应帧位置,在控制台输出结果。 - 可视化增强:
- 动画中添加绿色虚线连接地球与木星,实时显示当前距离。
- 生成静态图专门展示最短距离的状态,标注清晰。
- 调整轨道线条透明度,避免遮挡连线和天体。
内容的提问来源于stack exchange,提问作者Orla
相关产品推荐
相关产品推荐

