静电场线可视化

静电场线可视化
绘制点电荷或带电体周围的电场线分布,体现电场强度的方向与大小。

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.patches import Circle
import mpl_toolkits.mplot3d.art3d as art3d


# 定义带电体类
class ChargedObject:
    def __init__(self, position, charge, shape="sphere", size=0.5):
        self.position = np.array(position)
        self.charge = charge
        self.shape = shape
        self.size = size

    def plot(self, ax):
        if self.shape == "sphere":
            u, v = np.mgrid[0:2 * np.pi:20j, 0:np.pi:10j]
            x = self.position[0] + self.size * np.cos(u) * np.sin(v)
            y = self.position[1] + self.size * np.sin(u) * np.sin(v)
            z = self.position[2] + self.size * np.cos(v)
            ax.plot_wireframe(x, y, z, color='r' if self.charge > 0 else 'b')
        elif self.shape == "box":
            # 定义长方体的顶点
            x = [self.position[0] - self.size / 2, self.position[0] + self.size / 2]
            y = [self.position[1] - self.size / 2, self.position[1] + self.size / 2]
            z = [self.position[2] - self.size / 2, self.position[2] + self.size / 2]
            xx, yy = np.meshgrid(x, y)
            ax.plot_wireframe(xx, yy, np.full_like(xx, z[0]), color='r' if self.charge > 0 else 'b')
            ax.plot_wireframe(xx, yy, np.full_like(xx, z[1]), color='r' if self.charge > 0 else 'b')
            xx, zz = np.meshgrid(x, z)
            ax.plot_wireframe(xx, np.full_like(xx, y[0]), zz, color='r' if self.charge > 0 else 'b')
            ax.plot_wireframe(xx, np.full_like(xx, y[1]), zz, color='r' if self.charge > 0 else 'b')
            yy, zz = np.meshgrid(y, z)
            ax.plot_wireframe(np.full_like(yy, x[0]), yy, zz, color='r' if self.charge > 0 else 'b')
            ax.plot_wireframe(np.full_like(yy, x[1]), yy, zz, color='r' if self.charge > 0 else 'b')


# 计算电场强度
def electric_field(position, charged_objects):
    k = 9e9  # 库仑常数
    E = np.array([0.0, 0.0, 0.0])
    for obj in charged_objects:
        r = position - obj.position
        r_mag = np.linalg.norm(r)
        if r_mag > 1e-10:
            E += k * obj.charge * r / r_mag ** 3
    return E


# 生成电场线起始点
def generate_start_points(charged_obj, num_points=20):
    if charged_obj.shape == "sphere":
        u = np.linspace(0, 2 * np.pi, num_points)
        v = np.linspace(0, np.pi, num_points)
        points = []
        for i in range(num_points):
            for j in range(num_points):
                x = charged_obj.position[0] + charged_obj.size * np.cos(u[i]) * np.sin(v[j])
                y = charged_obj.position[1] + charged_obj.size * np.sin(u[i]) * np.sin(v[j])
                z = charged_obj.position[2] + charged_obj.size * np.cos(v[j])
                points.append(np.array([x, y, z]))
        return points
    elif charged_obj.shape == "box":
        x = [charged_obj.position[0] - charged_obj.size / 2, charged_obj.position[0] + charged_obj.size / 2]
        y = [charged_obj.position[1] - charged_obj.size / 2, charged_obj.position[1] + charged_obj.size / 2]
        z = [charged_obj.position[2] - charged_obj.size / 2, charged_obj.position[2] + charged_obj.size / 2]
        points = []
        for xx in x:
            for yy in y:
                points.append(np.array([xx, yy, z[0]]))
                points.append(np.array([xx, yy, z[1]]))
        for xx in x:
            for zz in z:
                points.append(np.array([xx, y[0], zz]))
                points.append(np.array([xx, y[1], zz]))
        for yy in y:
            for zz in z:
                points.append(np.array([x[0], yy, zz]))
                points.append(np.array([x[1], yy, zz]))
        return points


# 追踪电场线
def trace_field_line(start_point, charged_objects, step_size=0.1, max_steps=500):
    line = [start_point]
    current_point = start_point
    for _ in range(max_steps):
        E = electric_field(current_point, charged_objects)
        E_mag = np.linalg.norm(E)
        if E_mag < 1e-3:
            break
        current_point = current_point + step_size * E / E_mag
        line.append(current_point)
    return np.array(line)


# 创建带电体列表
charged_objects = [
    ChargedObject([-3, 0, 0], 5e-6, shape="sphere", size=0.5),
    ChargedObject([2, 1, 0], -8e-6, shape="box", size=0.6),
    ChargedObject([4, -2, 0], 3e-6, shape="sphere", size=0.4)
]

# 创建 3D 图形
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')

# 绘制带电体
for obj in charged_objects:
    obj.plot(ax)

# 绘制电场线
for obj in charged_objects:
    if obj.charge > 0:
        start_points = generate_start_points(obj)
        for start_point in start_points:
            field_line = trace_field_line(start_point, charged_objects)
            ax.plot(field_line[:, 0], field_line[:, 1], field_line[:, 2], color='orange', linewidth=0.5)

# 绘制电场向量
x, y, z = np.meshgrid(np.linspace(-10, 10, 10), np.linspace(-10, 10, 10), np.linspace(-10, 10, 10))
Ex = np.zeros_like(x)
Ey = np.zeros_like(y)
Ez = np.zeros_like(z)
for i in range(x.shape[0]):
    for j in range(x.shape[1]):
        for k in range(x.shape[2]):
            position = np.array([x[i, j, k], y[i, j, k], z[i, j, k]])
            E = electric_field(position, charged_objects)
            Ex[i, j, k] = E[0]
            Ey[i, j, k] = E[1]
            Ez[i, j, k] = E[2]

ax.quiver(x, y, z, Ex, Ey, Ez, length=0.5, normalize=True, color='gray')

# 设置坐标轴标签和标题
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('Electric Field Visualization')

# 显示图形
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值