笔者学习VPython的时候曾遇到了不少困难,所以在此撰写系列教程与案例,希望能对学习VPython提供相关借鉴。如有任何错误或疑问,欢迎评论指出!
本案例将实现利用Vpython库绘制点电荷的电场线,本次先考虑单个点电荷的电场线,包括正电荷向外发散的电场线和负电荷向内汇聚的电场线,以下为详细教程:
1.初始准备
导入Vpython库,定义库伦常数k,定义点电荷的电量和位置,设置模拟的画布。
from vpython import *
k = 9*10**9
Q1_charge = 10**(-5)
Q1_postion = vector(0, 0, 0)
scene = canvas(height=800, width=800, background=vector(1, 1, 1))
2.理论基础
电场线是为了直观形象地描述电场分布而在电场中引入的一些假想的曲线。曲线上每一点的切线方向和该点的电场强度方向一致。我们可以让一堆小球从电荷周围出发,按照电场线的方向运动,运动留下的轨迹即可视为电场线。
电场强度E是位置的函数,可以写为:
电荷在电场中会受到电场力的作用,
若试探电荷的电荷量为1,则可写成:
小球的运动轨迹满足以下差分方程:
令v等于此位置的电场力
则可以由类似欧拉法的方法得到了小球运动的轨迹,并且该轨迹的切线即等价于电场强度。
3.点电荷与小球的构建
点电荷是一个体积为0的电荷,为了达到可视化的效果,这里将其半径设为0.1。另外再创建18个小球,这18个小球所留下的轨迹即为电场线。这里18个小球统一存放在一个名为field_ball_1的列表中,方便以后的调用。
size = 0.1
Q1 = sphere(pos=Q1_postion, radius=size, color=color.red)
a_N = 18
field_ball_1 = []
for a_1 in range(0, a_N, 1):
field_ball_1.append(sphere(pos=vector(size*cos(2*pi*a_1/a_N+pi/a_N), size*sin(2*pi*a_1/a_N+pi/a_N), 0) + Q1_postion,
radius=0.01, color=vector(1, 1, 0), v=vector(0, 0, 0)))
4.定义电场力函数
电场力是电荷置于电场中所受到的作用力,或是在电场中对移动自由电荷所施加的作用力。电场力大小可以由库仑定律计算,当有多个电荷同时作用时,其大小及方向遵循矢量运算规则。
库仑定律的表达式如下:
其中k为库伦常数,Q1,Q2分别为两个点电荷的电荷量,r为两个点电荷之间的距离。在本例中,其他小球是视为试探电荷的存在,而点电荷Q1的位置确定,由此可以编写下面代码:
def F_e(r, q):
r0 = r - Q1_postion
return k*q*Q1_charge*r0.norm()/(r0.mag*r0.mag)
5.电场线的绘制
通过下列代码即可实现电场线的绘制,为了使可视化的效果更明显,每隔一段时间还增加了一个箭头,表明电场线的指向。值得注意的是,这里小球的速度,每一次都等于该处电场力的大小,并不符合牛顿运动规律,这样得出的运动轨迹才能代表电场线。
for b_1 in range(0, a_N, 1):
field_ball_1[b_1].trail = curve(color=vector(1, 1, 0))
t = 0
dt = 0.001
frame = 0
while t < 2.49:
t += dt
frame += 1
rate(1/dt)
for i in range(0, a_N, 1):
if frame % 1000 == 0:
arrow(pos=field_ball_1[i].pos, axis=field_ball_1[i].v * 0.1,
headwidth=0.8 * size, headlength=3 * size, color=color.cyan)
field_ball_1[i].v = F_e(field_ball_1[i].pos, 1).norm()
field_ball_1[i].pos += field_ball_1[i].v * dt
field_ball_1[i].trail.append(pos=field_ball_1[i].pos, color=vector(1, 1, 0))
按照以上思路,即可实现点电荷的电场线的案例,以下为源代码:
from vpython import *
k = 9*10**9
Q1_charge = 10**(-5)
Q1_postion = vector(0, 0, 0)
scene = canvas(height=800, width=800, background=vector(1, 1, 1))
size = 0.1
Q1 = sphere(pos=Q1_postion, radius=size, color=color.red)
a_N = 18
field_ball_1 = []
for a_1 in range(0, a_N, 1):
field_ball_1.append(sphere(pos=vector(size*cos(2*pi*a_1/a_N+pi/a_N), size*sin(2*pi*a_1/a_N+pi/a_N), 0) + Q1_postion,
radius=0.01, color=vector(1, 1, 0), v=vector(0, 0, 0)))
def F_e(r, q):
r0 = r - Q1_postion
return k*q*Q1_charge*r0.norm()/(r0.mag*r0.mag)
for b_1 in range(0, a_N, 1):
field_ball_1[b_1].trail = curve(color=vector(1, 1, 0))
t = 0
dt = 0.001
frame = 0
while t < 2.49:
t += dt
frame += 1
rate(1/dt)
for i in range(0, a_N, 1):
if frame % 1000 == 0:
arrow(pos=field_ball_1[i].pos, axis=field_ball_1[i].v * 0.1,
headwidth=0.8 * size, headlength=3 * size, color=color.cyan)
field_ball_1[i].v = F_e(field_ball_1[i].pos, 1).norm()
field_ball_1[i].pos += field_ball_1[i].v * dt
field_ball_1[i].trail.append(pos=field_ball_1[i].pos, color=vector(1, 1, 0))
当然我们可以适当更改代码,使其变成负电荷的电场,这里我们用蓝色负电荷,红色表示正电荷。更改的代码如下所示:
from vpython import *
k = 9*10**9
Q1_charge = -10**(-5)
Q1_postion = vector(0, 0, 0)
scene = canvas(height=800, width=800, background=vector(1, 1, 1))
size = 0.1
Q1 = sphere(pos=Q1_postion, radius=size, color=color.blue)
a_N = 18
field_ball_1 = []
for a_1 in range(0, a_N, 1):
field_ball_1.append(sphere(pos=vector(size*cos(2*pi*a_1/a_N+pi/a_N), size*sin(2*pi*a_1/a_N+pi/a_N), 0) + Q1_postion,
radius=0.01, color=vector(1, 1, 0), v=vector(0, 0, 0)))
def F_e(r, q):
r0 = r - Q1_postion
return k*q*Q1_charge*r0.norm()/(r0.mag*r0.mag)
for b_1 in range(0, a_N, 1):
field_ball_1[b_1].trail = curve(color=vector(1, 1, 0))
t = 0
dt = 0.001
frame = 0
while t < 2.49:
t += dt
frame += 1
rate(1/dt)
for i in range(0, a_N, 1):
if frame % 1000 == 0:
arrow(pos=field_ball_1[i].pos, axis=-field_ball_1[i].v * 0.1,
headwidth=0.8 * size, headlength=3 * size, color=color.cyan)
field_ball_1[i].v = -F_e(field_ball_1[i].pos, 1).norm()
field_ball_1[i].pos += field_ball_1[i].v * dt
field_ball_1[i].trail.append(pos=field_ball_1[i].pos, color=vector(1, 1, 0))