Python双电子库仑力模拟问题:共线运动变为平行轨迹排查
两个电子库仑力模拟轨迹异常问题排查
问题描述
编写Python程序模拟仅受库仑力作用的两个电子相互作用,预期轨迹应彼此共线,但实际模拟中电子沿平行路径运动,代码如下:
# -*- coding: utf-8 -*- """ Created on Wed Sep 20 10:01:24 2023 @author: sanat """ import pygame import sys import math # Constants WIDTH, HEIGHT = 2000, 1000 BACKGROUND_COLOR = (255, 255, 255) ELECTRON_RADIUS = 5 TIME_STEP = 0.01 # Time step for simulation # Electron properties electron1 = { "pos": [400, 500], "velocity": [0, 0], "charge": - 1.0, "mass": 1.0 } electron2 = { "pos": [900, 600], "velocity": [0, 0], "charge": -1.0, "mass": 1.0 } # Initialize Pygame pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Electron Motion Simulation") def calculate_force(e1, e2): k = 8.988e9 # Coulomb's constant r = math.sqrt((e1["pos"][0] - e2["pos"][0]) ** 2 + (e1["pos"][1] - e2["pos"][1]) ** 2) force = (k * e1["charge"] * e2["charge"]) / (r ** 2) return force def update_velocity(electron, force): acceleration = force / electron["mass"] electron["velocity"][0] += acceleration * TIME_STEP electron["velocity"][1] += acceleration * TIME_STEP def update_position(electron): electron["pos"][0] += electron["velocity"][0] * TIME_STEP electron["pos"][1] += electron["velocity"][1] * TIME_STEP def draw_electrons(): for electron in [electron1, electron2]: pygame.draw.circle(screen, (0, 0, 0), (int(electron["pos"][0]), int(electron["pos"][1])), ELECTRON_RADIUS) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # Calculate force between electrons force = calculate_force(electron1, electron2) # Update velocities and positions update_velocity(electron1, force) update_velocity(electron2, -force) # Opposite force on electron2 update_position(electron1) update_position(electron2) # Clear the screen screen.fill(BACKGROUND_COLOR) # Draw electrons draw_electrons() pygame.display.flip() pygame.time.delay(1000) pygame.quit() sys.exit()
错误原因分析
- 忽略库仑力的矢量特性:库仑力是有方向的矢量,当前代码仅计算了力的大小,未根据两电子的相对位置分解为x、y方向的分量。直接将相同大小的加速度施加到x和y方向,导致两电子的速度变化方向完全一致,最终沿平行路径运动。
- 加速度更新逻辑错误:
update_velocity函数中,将标量加速度同时加到x、y速度分量上,这完全不符合力的实际方向,只有当力沿45度对角线时才成立,显然不适用于任意相对位置的情况。 - 参数数值失衡:使用真实库仑常数
8.988e9,但将电子质量、电荷简化为1,会导致加速度数值极大,运动瞬间失控,也干扰了对轨迹问题的正常观察。
修正后的代码
# -*- coding: utf-8 -*- """ Corrected Electron Motion Simulation """ import pygame import sys import math # Constants WIDTH, HEIGHT = 2000, 1000 BACKGROUND_COLOR = (255, 255, 255) ELECTRON_RADIUS = 5 TIME_STEP = 0.01 # 调整参数,避免加速度过大 K = 1000 # 缩小库仑常数,适配简化的质量电荷 ELECTRON_CHARGE = -1.0 ELECTRON_MASS = 10.0 # Electron properties electron1 = { "pos": [400.0, 500.0], "velocity": [0.0, 0.0], "charge": ELECTRON_CHARGE, "mass": ELECTRON_MASS } electron2 = { "pos": [900.0, 600.0], "velocity": [0.0, 0.0], "charge": ELECTRON_CHARGE, "mass": ELECTRON_MASS } # Initialize Pygame pygame.init() screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Electron Motion Simulation") def calculate_force_vector(e1, e2): """计算库仑力的矢量分量(x和y方向)""" dx = e2["pos"][0] - e1["pos"][0] dy = e2["pos"][1] - e1["pos"][1] r_squared = dx**2 + dy**2 r = math.sqrt(r_squared) if r < 10: # 避免距离过近导致力过大 return (0, 0) # 库仑力大小 force_magnitude = (K * e1["charge"] * e2["charge"]) / r_squared # 分解为x、y方向分量 fx = force_magnitude * (dx / r) fy = force_magnitude * (dy / r) return (fx, fy) def update_velocity(electron, fx, fy): """根据x、y方向的力分量更新速度""" ax = fx / electron["mass"] ay = fy / electron["mass"] electron["velocity"][0] += ax * TIME_STEP electron["velocity"][1] += ay * TIME_STEP def update_position(electron): electron["pos"][0] += electron["velocity"][0] * TIME_STEP electron["pos"][1] += electron["velocity"][1] * TIME_STEP def draw_electrons(): for electron in [electron1, electron2]: pygame.draw.circle(screen, (0, 0, 0), (int(electron["pos"][0]), int(electron["pos"][1])), ELECTRON_RADIUS) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 计算力矢量 fx, fy = calculate_force_vector(electron1, electron2) # 电子1受到的力是(fx, fy),电子2受到相反的力 update_velocity(electron1, fx, fy) update_velocity(electron2, -fx, -fy) update_position(electron1) update_position(electron2) screen.fill(BACKGROUND_COLOR) draw_electrons() pygame.display.flip() pygame.time.delay(50) # 缩短延迟,让运动更流畅 pygame.quit() sys.exit()
修正说明
- 添加力的矢量分解:
calculate_force_vector函数计算两电子的相对位置差,将库仑力分解为x、y方向的分量,确保力的方向符合两电子的相对位置。 - 修正速度更新逻辑:
update_velocity函数根据x、y方向的加速度分量分别更新对应方向的速度,保证运动方向与力的方向一致。 - 调整参数数值:缩小库仑常数、增大电子质量,避免加速度过大导致运动失控,同时缩短帧延迟,让轨迹变化更易观察。
- 添加距离保护:当两电子距离过近时,返回0力,避免数值溢出。
内容的提问来源于stack exchange,提问作者Sanat S Kumar
相关产品推荐
相关产品推荐

