From 4276bf1fb49b6acef0fb0b3e28f9d4b3bdfc2dc4 Mon Sep 17 00:00:00 2001 From: march3 Date: Sun, 23 Mar 2025 21:05:04 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simulators/mpl/mpl_2d_simulator.py | 5 +- simulators/mpl/mpl_2d_simulator_arrow.py | 75 +++++++++++++++--------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/simulators/mpl/mpl_2d_simulator.py b/simulators/mpl/mpl_2d_simulator.py index fd2f3f3..42ebdc7 100644 --- a/simulators/mpl/mpl_2d_simulator.py +++ b/simulators/mpl/mpl_2d_simulator.py @@ -65,8 +65,11 @@ class 星球: for 星球 in 星球列表: if 星球 is not self: 距离向量 = 星球.位置 - self.位置 - 距离 = np.linalg.norm(距离向量) + # 距离指的是两个物体之间的长度,是一个标量,仅具有大小 + 距离 = np.linalg.norm(距离向量) # 距离向量:[30,40] 距离:50 # 计算万有引力,力的单位:N(kg m s^-2) + # 万有引力是一个矢量,它的方向是沿着两个物体质心的连线方向。 + # 所以,要得到万有引力的矢量形式,就需要在大小的基础上乘以一个单位向量,该单位向量的方向与距离向量的方向相同。 力 = 万有引力常量 * self.质量 * 星球.质量 * 距离向量 / 距离 ** 3 总力 += 力 # 计算加速度,单位:m s^-2 diff --git a/simulators/mpl/mpl_2d_simulator_arrow.py b/simulators/mpl/mpl_2d_simulator_arrow.py index 6bd6dd5..205756d 100644 --- a/simulators/mpl/mpl_2d_simulator_arrow.py +++ b/simulators/mpl/mpl_2d_simulator_arrow.py @@ -65,9 +65,12 @@ class 星球: for 星球 in 星球列表: if 星球 is not self: 距离向量 = 星球.位置 - self.位置 - 距离 = np.linalg.norm(距离向量) + # 距离指的是两个物体之间的长度,是一个标量,仅具有大小 + 距离 = np.linalg.norm(距离向量) # 距离向量:[30,40] 距离:50 # 计算万有引力,力的单位:N(kg m s^-2) - 力 = 万有引力常量 * self.质量 * 星球.质量 * 距离向量 / 距离 ** 3 + # 万有引力是一个矢量,它的方向是沿着两个物体质心的连线方向。 + # 所以,要得到万有引力的矢量形式,就需要在大小的基础上乘以一个单位向量,该单位向量的方向与距离向量的方向相同。 + 力 = 万有引力常量 * self.质量 * 星球.质量 * 距离向量 / (距离 ** 3) 总力 += 力 # 计算加速度,单位:m s^-2 加速度 = 总力 / self.质量 @@ -93,12 +96,12 @@ def 场景1(): 时间步长 = 0.01 # 创建星球列表 星球列表 = [ - 星球(质量=2e12, 位置=[0, 0], 速度=[0, 0.1], 颜色='red', 名称偏移=[1, 0]), - 星球(质量=5e10, 位置=[20, 0], 速度=[0, 1], 颜色='blue'), - 星球(质量=5e10, 位置=[-20, 0], 速度=[0, -1], 颜色='green') + 星球(质量=5e12, 位置=[0, 0], 速度=[0, 0.1], 颜色='red', 名称偏移=[1, 0]), + 星球(质量=5e10, 位置=[20, 0], 速度=[0, 2], 颜色='blue'), + 星球(质量=5e10, 位置=[-20, 0], 速度=[0, -2], 颜色='green') ] 坐标轴.set_xlim(-50, 50) - 坐标轴.set_ylim(-20, 80) + 坐标轴.set_ylim(-50, 50) def 场景2(): @@ -128,15 +131,15 @@ def 场景2(): 坐标轴.set_ylim(-10, 50) -场景1() -# 场景2() +# 场景1() +场景2() # 设置纵横比为固定值,使得 X、Y 刻度比例不变 坐标轴.set_aspect('equal') # 调整边距 plt.subplots_adjust(left=0.05, bottom=0.04, right=0.97, top=0.97, wspace=0.4, hspace=0.4) 点列表 = [坐标轴.plot([], [], 'o', color=星球.颜色, markersize=星球.大小)[0] for 星球 in 星球列表] -轨迹列表 = [坐标轴.plot([], [], '-', color=星球.颜色)[0] for 星球 in 星球列表] +轨迹列表 = [坐标轴.plot([], [], '--', color=星球.颜色)[0] for 星球 in 星球列表] 名称列表 = [坐标轴.text(0, 0, 星球.名称, color="white", size=30, fontname='SimHei') for 星球 in 星球列表] 速度线列表 = [plt.Arrow(0, 0, 0, 0, color=星球.颜色) for 星球 in 星球列表] 加速度线列表 = [plt.Arrow(0, 0, 0, 0, color=星球.颜色) for 星球 in 星球列表] @@ -192,16 +195,34 @@ def 更新(帧): 轨迹列表[i].set_data(轨迹[:, 0], 轨迹[:, 1]) 偏移量_x, 偏移量_y = 0, 0 # 星球.名称偏移 星球.位置[0] + 偏移量_x + 0.5, 星球.位置[1] + 偏移量_y 名称列表[i].set_position((x - 0.8, y - 1)) - + min_length, max_length = 4, 100 # 更新速度箭头 速度线列表[i].remove() - 速度线 = plt.arrow(x, y, 星球.速度[0] * 速度线长率, 星球.速度[1] * 速度线长率, width=0.05, head_width=1, color=星球.颜色) + dx, dy = 星球.速度[0] * 速度线长率, 星球.速度[1] * 速度线长率 + distance = (dx ** 2 + dy ** 2) ** 0.5 + if distance > max_length: + # 重新设置 dx,dy ,使得 (dx ** 2 + dy ** 2) ** 0.5 = 50 + dx, dy = dx / distance * max_length, dy / distance * max_length + elif distance < min_length: + # 重新设置 dx,dy ,使得 (dx ** 2 + dy ** 2) ** 0.5 = 5 + dx, dy = dx / distance * min_length, dy / distance * min_length + + 速度线 = plt.arrow(x, y, dx, dy, width=0.05, head_width=1, color=星球.颜色) 速度线列表[i] = 速度线 坐标轴.add_patch(速度线) # 更新加速度箭头 加速度线列表[i].remove() - 加速度线 = plt.arrow(x, y, 星球.加速度[0] * 加速度线长率, 星球.加速度[1] * 加速度线长率, width=0.05, head_width=1, color="black") + dx, dy = 星球.加速度[0] * 加速度线长率, 星球.加速度[1] * 加速度线长率 + distance = (dx ** 2 + dy ** 2) ** 0.5 + if distance > max_length: + # 重新设置 dx,dy ,使得 (dx ** 2 + dy ** 2) ** 0.5 = 50 + dx, dy = dx / distance * max_length, dy / distance * max_length + elif distance < min_length: + # 重新设置 dx,dy ,使得 (dx ** 2 + dy ** 2) ** 0.5 = 5 + dx, dy = dx / distance * min_length, dy / distance * min_length + + 加速度线 = plt.arrow(x, y, dx, dy, width=0.05, head_width=1, color="black") 加速度线列表[i] = 加速度线 坐标轴.add_patch(加速度线) @@ -215,21 +236,21 @@ def 更新(帧): return 点列表 + 轨迹列表 + 名称列表 + 速度线列表 + 加速度线列表 + 速度文本列表 + 加速度文本列表 - -# 设置窗口大小(单位:英寸) -width = 9 -height = 11 -图形.set_size_inches(width, height) - -# 设置窗口位置(x, y, width, height) -x_pos = 1020 -y_pos = 0 -try: - manager = plt.get_current_fig_manager() - if hasattr(manager, 'window'): - manager.window.setGeometry(x_pos, y_pos, int(width * 100), int(height * 100)) -except AttributeError: - print("无法设置窗口位置,可能是因为使用的后端不支持此操作。") +def 设置窗口(): + # 设置窗口大小(单位:英寸) + width = 9 + height = 11 + 图形.set_size_inches(width, height) + + # 设置窗口位置(x, y, width, height) + x_pos = 1020 + y_pos = 0 + try: + manager = plt.get_current_fig_manager() + if hasattr(manager, 'window'): + manager.window.setGeometry(x_pos, y_pos, int(width * 100), int(height * 100)) + except AttributeError: + print("无法设置窗口位置,可能是因为使用的后端不支持此操作。") # 创建动画 动画 = FuncAnimation(图形, 更新, frames=range(1000), init_func=初始化, blit=True, interval=2) -- GitLab