Article
Electromagnetism · ⏱ ≈ 16 хв читання

Coulomb's Law & Electric Fields

The electrostatic force between point charges follows an inverse-square law — the same mathematical form as gravity. We derive the electric field, potential, and Gauss's law, trace field lines for arbitrary charge configurations, and implement an O(N log N) Barnes–Hut tree for many-body electrostatic simulations.

1. Coulomb's Law

Charles-Augustin de Coulomb measured the force between charged spheres in 1785 and found it follows an inverse-square law:

F = k |q₁ q₂| / r² (magnitude) Vector form: F₁₂ = k q₁ q₂ (r̂₁₂) / r₁₂² k = 1/(4πε₀) ≈ 8.988 × 10⁹ N·m²/C² ε₀ = 8.854 × 10⁻¹² F/m (permittivity of free space)

Like charges repel (F > 0), unlike charges attract (F < 0). The force falls off as 1/r² — at double the distance, the force is four times weaker. This is the same power law as Newtonian gravity; the difference is that electric charges can be positive or negative, giving both attraction and repulsion.

Gravity vs Electrostatics

Both are inverse-square laws. But the electromagnetic force between an electron and proton is ~10³⁶ times stronger than their gravitational attraction.

Charge quantisation

Electric charge is quantised: q = n · e, where e = 1.602 × 10⁻¹⁹ C. Quarks carry ±e/3, but free charges always come in integer multiples of e.

Conservation

Total electric charge is conserved in all processes. Pair production creates equal + and − charges; pair annihilation destroys them.

In a medium

Replace ε₀ with ε = εᵣε₀. Water (εᵣ ≈ 80) screens electrostatic forces dramatically — essential for biology and ionic solutions.

2. Electric Field & Superposition

The electric field E(r) at position r due to a point charge q at origin is the force per unit test charge:

E(r) = k q r̂ / r² [N/C = V/m] Superposition (N charges): E_total(r) = Σᵢ k qᵢ (r − rᵢ) / |r − rᵢ|³

The naïve sum over all pairs is O(N²) — prohibitive for large N. For a continuous distribution with charge density ρ(r'):

E(r) = k ∫ ρ(r') (r − r') / |r − r'|³ dV'

The electric field is a vector field — at each point in space it has both magnitude and direction. Field lines (see section 5) visualise this field geometrically.

3. Electric Potential & Energy

The electric potential V is the scalar quantity whose negative gradient is the field:

V(r) = k q / r (single point charge) E = −∇V → Eₓ = −∂V/∂x, Eᵧ = −∂V/∂y Potential energy of charge q at potential V: U = q V Potential energy of two-charge system: U₁₂ = k q₁ q₂ / r₁₂

Since E is conservative (∮E·dl = 0 in electrostatics), the work done moving a charge between two points is path-independent and depends only on the potential difference: W = q(V_B − V_A).

Poisson's equation connects potential to charge density: ∇²V = −ρ/ε₀. In free space (ρ = 0) this reduces to Laplace's equation ∇²V = 0 — used in boundary-value problems for capacitors and conductors.

4. Gauss's Law

Gauss's law is one of Maxwell's four equations and provides a powerful shortcut when symmetry is present:

∮ E · dA = Q_enc / ε₀ Differential form: ∇ · E = ρ / ε₀

Three canonical applications using Gaussian surfaces:

5. Field Lines & Equipotentials

Electric field lines are integral curves of E(r): they start on positive charges, end on negative charges, and never cross. Their density indicates field strength. Equipotential surfaces are everywhere perpendicular to field lines.

Tracing a field line from seed position r₀:

dr/ds = E(r) / |E(r)| (s = arc-length parameter) Euler step: r_{n+1} = r_n + h · E(r_n) / |E(r_n)| Use RK4 for smooth lines with larger step sizes h

For a dipole (+q at −d, −q at +d), the field has a characteristic figure-eight pattern of closed lines. Dipole moment p = qd points from − to + charge; the far field falls off as 1/r³ and depends on angle: E ~ (1/r³)(2cosθ r̂ + sinθ θ̂).

6. Conductors & Shielding

In electrostatic equilibrium, free charges in a conductor rearrange until E = 0 everywhere inside. Consequences:

The capacitance C of a conductor measures how much charge it holds per unit potential: C = Q/V. For a parallel-plate capacitor with plate area A and separation d: C = ε₀A/d. Adding a dielectric with permittivity εᵣ multiplies C by εᵣ.

7. JavaScript — Barnes–Hut Electrostatics

For N charged particles, direct summation is O(N²). The Barnes–Hut algorithm builds a quadtree (2D) or octree (3D) and approximates distant clusters as a single "macro-charge", reducing the complexity to O(N log N).

// Barnes–Hut quadtree node
class BHNode {
  constructor(cx, cy, size) {
    this.cx = cx; this.cy = cy; this.size = size;
    this.totalQ = 0; this.comX = 0; this.comY = 0;
    this.children = null; this.particle = null;
  }

  insert(p) {
    if (!this.totalQ) {
      this.particle = p;
      this.totalQ = p.q;
      this.comX = p.x; this.comY = p.y;
      return;
    }
    if (!this.children) this.subdivide();
    if (this.particle) {
      this._insertIntoChild(this.particle);
      this.particle = null;
    }
    this._insertIntoChild(p);
    // update centre of charge
    this.comX = (this.comX * this.totalQ + p.x * p.q) / (this.totalQ + p.q);
    this.comY = (this.comY * this.totalQ + p.y * p.q) / (this.totalQ + p.q);
    this.totalQ += p.q;
  }

  subdivide() {
    const h = this.size / 2;
    this.children = [
      new BHNode(this.cx - h/2, this.cy - h/2, h),
      new BHNode(this.cx + h/2, this.cy - h/2, h),
      new BHNode(this.cx - h/2, this.cy + h/2, h),
      new BHNode(this.cx + h/2, this.cy + h/2, h),
    ];
  }

  _insertIntoChild(p) {
    const idx = (p.x > this.cx ? 1 : 0) + (p.y > this.cy ? 2 : 0);
    this.children[idx].insert(p);
  }

  // Compute electric force on particle p (theta = opening ratio, ~0.5)
  force(p, theta, k = 8.988e9) {
    if (!this.totalQ) return {fx: 0, fy: 0};
    const dx = this.comX - p.x, dy = this.comY - p.y;
    const r2 = dx * dx + dy * dy;
    if (r2 === 0) return {fx: 0, fy: 0};
    const r = Math.sqrt(r2);
    // Barnes–Hut criterion: treat as single macro-charge if s/r < theta
    if (!this.children || this.size / r < theta || this.particle) {
      const mag = k * p.q * this.totalQ / r2;
      return {fx: mag * dx / r, fy: mag * dy / r};
    }
    let fx = 0, fy = 0;
    for (const child of this.children) {
      const f = child.force(p, theta, k);
      fx += f.fx; fy += f.fy;
    }
    return {fx, fy};
  }
}

// Field line tracer (RK4)
function traceFieldLine(charges, x0, y0, step = 2, maxSteps = 500) {
  const pts = [{x: x0, y: y0}];
  let x = x0, y = y0;
  const k = 1; // normalised units
  for (let i = 0; i < maxSteps; i++) {
    let ex = 0, ey = 0;
    for (const c of charges) {
      const dx = x - c.x, dy = y - c.y;
      const r3 = (dx * dx + dy * dy) ** 1.5;
      if (r3 < 1e-6) continue;
      ex += k * c.q * dx / r3;
      ey += k * c.q * dy / r3;
    }
    const mag = Math.hypot(ex, ey);
    if (mag < 1e-10) break;
    x += step * ex / mag;
    y += step * ey / mag;
    pts.push({x, y});
  }
  return pts;
}

8. Applications

Connection: The N-Body Gravity simulation uses the same Barnes–Hut algorithm applied to gravitational forces (replace kq₁q₂ with −Gm₁m₂).
🔊 Open Chladni Patterns →