Answer to Question #175539 in Python for Jordan

Question #175539

Write a GUI to visualize electric field lines of point charges located in a plane.


The functionality the program should provide

  • Positive and negative point charges are displayed as blue and red dots, respectively.
  • The area of the dot is proportional to the magnitude of the charge.
  • 32 field lines emerge from each positive charge
  • A left-mouse press and release on a charge deletes the charge
  • A left-mouse press not on a charge followed by a mouse motion adds a charge as follows:
  •  location of new charge is the mouse-press position.
  •  magnitude of the charge is round(dx), where dx is the x-positional difference between location of mouse-release and mouse-press. 
  • A left-mouse press on a charge followed by a mouse motion drags the charge resulting in:
  • charges being redrawn,
  • field lines being recalculated and displayed.
  • For better responsiveness, in dragging mode only 8 field lines per charge are used and only the changed elements of the figure are redrawn, not the full figure.
1
Expert's answer
2021-03-26T12:39:16-0400
import matplotlib.pyplot as plt
import numpy as np
import plot.offline as py
from scipy.integrate import ode as ode
py.init_notebook_mode()

class charge:
    def __init__(self, q, pos):
        self.q = q
        self.pos = pos


def E_point_charge(q, a, x, y):
    return q * (x - a[0]) / ((x - a[0]) ** 2 + (y - a[1]) ** 2) ** (1.5), \
           q * (y - a[1]) / ((x - a[0]) ** 2 + (y - a[1]) ** 2) ** (1.5)


def E_total(x, y, charges):
    Ex, Ey = 0, 0
    for C in charges:
        E = E_point_charge(C.q, C.pos, x, y)
        Ex = Ex + E[0]
        Ey = Ey + E[1]
    return [Ex, Ey]


def E_dir(t, y, charges):
    Ex, Ey = E_total(y[0], y[1], charges)
    n = np.sqrt(Ex ** 2 + Ey * Ey)
    return [Ex / n, Ey / n]


#--- part 3-------------


charges = [charge( 1, [0.56, 0.56]),
           charge(-1, [0.26, 0.76]),
           charge( 1, [0.66, 0.16]),
           charge(-1, [0.66, 0.86]) ]

# calculate field lines
R = 0.01
# loop over all charges
xs, ys = [], []
for C in charges:
    # plot field lines starting in current charge
    dt = 0.8*R
    if C.q < 0:
       
        continue
    # loop over field lines starting in different directions
    # around current charge
    for alpha in np.linspace(0, 2*np.pi*31/32, 32):
        r = ode(E_dir)
        r.set_integrator('vode')
        r.set_f_params(charges)
        x = [ C.pos[0] + np.cos(alpha)*R ]
        y = [ C.pos[1] + np.sin(alpha)*R ]
        r.set_initial_value([x[0], y[0]], 0)
        cnt = 0
        while r.successful():
            Enorm = E_total(r.y[0],r.y[1],charges)
            Enorm = (Enorm[0]**2 + Enorm[1]**2)**0.5
            a = 5
            dt = R*a*Enorm**(-0.4)
            #if cnt % 1000 == 0:
            #    print(r.y[0],r.y[1],Enorm,dt2)
            #cnt += 1
            r.integrate(r.t+dt)
            x.append(r.y[0])
            y.append(r.y[1])
            hit_charge=False
            # check if field line ends in some charge
            for C2 in charges:
                if np.sqrt((r.y[0]-C2.pos[0])**2+(r.y[1]-C2.pos[1])**2)<R:
                    hit_charge = True
            if hit_charge:
                break
        xs.append(x)
        ys.append(y)

#----- part 4---------------
fig = plt.figure(figsize=(7, 7),facecolor="w")
ax = fig.add_subplot(111)

# plot field line
for x, y in zip(xs,ys):
    ax.plot(x, y, color="k",lw=0.8)

# plot point charges
for C in charges:
    if C.q>0:
        ax.plot(C.pos[0], C.pos[1], 'ro', ms=10*np.sqrt(C.q))
    if C.q<0:
        ax.plot(C.pos[0], C.pos[1], 'bo', ms=10*np.sqrt(-C.q))


ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_aspect('equal','datalim')
plt.savefig('electric_field_lines_pyplot_wo_mayavi.png',
            dpi=250,bbox_inches="tight",pad_inches=0.02)
plt.show()

Need a fast expert's response?

Submit order

and get a quick answer at the best price

for any assignment or question with DETAILED EXPLANATIONS!

Comments

No comments. Be the first!

Leave a comment

LATEST TUTORIALS
New on Blog
APPROVED BY CLIENTS