228

Maxwell's EM Wave Propagation

True 3D vector field visualization of an electromagnetic wave derived from Maxwell's equations. Displays mutually perpendicular transverse Electric field E vectors (Cyan), Magnetic field B vectors (Rose), and the longitudinal Poynting energy propagation vector S = 1/μ₀(E × B).

Playground
60 FPS Canvas 2D
Click + Drag to interact with field
</>

Full Executable Algorithm Code

// 060 - Maxwell's EM Wave Propagation (physics)
// 1:1 Original algorithm engine source
function createMaxwellEMWave() {
  const NODE_COUNT = 38;
  return {
    setup() {
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const waveFreq = Number(params.frequency || 1.2);
      const waveAmp = Number(params.amplitude || 1);
      const t = timeState.time * waveFreq;
      ctx.fillStyle = "#020308";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.5;
      const cy = height * 0.52;
      const scale = Math.min(width, height) / 480;
      const rotY = 0.55 + Math.sin(t * 0.2) * 0.1;
      const rotX = 0.38;
      const rotZ = 0;
      ctx.save();
      ctx.globalCompositeOperation = "screen";
      const totalLength = 360 * scale;
      const k = 0.025;
      const pAxisStart = project3D(-totalLength * 0.5, 0, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
      const pAxisEnd = project3D(totalLength * 0.5, 0, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
      ctx.beginPath();
      ctx.moveTo(pAxisStart.x, pAxisStart.y);
      ctx.lineTo(pAxisEnd.x, pAxisEnd.y);
      ctx.strokeStyle = "rgba(255, 255, 255, 0.4)";
      ctx.lineWidth = 1.6;
      ctx.stroke();
      ctx.fillStyle = "#fbbf24";
      ctx.beginPath();
      ctx.arc(pAxisEnd.x, pAxisEnd.y, 5 * scale, 0, Math.PI * 2);
      ctx.fill();
      ctx.beginPath();
      for (let i = 0; i < NODE_COUNT; i++) {
        const normI = i / (NODE_COUNT - 1);
        const xPos = (normI - 0.5) * totalLength;
        const eField = Math.sin(xPos * k - t * 3.5) * (70 * waveAmp * scale);
        const pBase = project3D(xPos, 0, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
        const pTip = project3D(xPos, eField, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
        ctx.moveTo(pBase.x, pBase.y);
        ctx.lineTo(pTip.x, pTip.y);
        ctx.fillStyle = "#38bdf8";
        ctx.fillRect(pTip.x - 1.5, pTip.y - 1.5, 3, 3);
      }
      ctx.strokeStyle = "#38bdf8";
      ctx.lineWidth = 1.6;
      ctx.stroke();
      ctx.beginPath();
      for (let x = -totalLength * 0.5; x <= totalLength * 0.5; x += 4) {
        const eField = Math.sin(x * k - t * 3.5) * (70 * waveAmp * scale);
        const p = project3D(x, eField, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
        if (x === -totalLength * 0.5) ctx.moveTo(p.x, p.y);
        else ctx.lineTo(p.x, p.y);
      }
      ctx.strokeStyle = "#38bdf8";
      ctx.shadowColor = "#38bdf8";
      ctx.shadowBlur = 10;
      ctx.lineWidth = 2.2;
      ctx.stroke();
      ctx.shadowBlur = 0;
      ctx.beginPath();
      for (let i = 0; i < NODE_COUNT; i++) {
        const normI = i / (NODE_COUNT - 1);
        const xPos = (normI - 0.5) * totalLength;
        const bField = Math.sin(xPos * k - t * 3.5) * (70 * waveAmp * scale);
        const pBase = project3D(xPos, 0, 0, rotX, rotY, rotZ, cx, cy, 450, 520);
        const pTip = project3D(xPos, 0, bField, rotX, rotY, rotZ, cx, cy, 450, 520);
        ctx.moveTo(pBase.x, pBase.y);
        ctx.lineTo(pTip.x, pTip.y);
        ctx.fillStyle = "#f43f5e";
        ctx.fillRect(pTip.x - 1.5, pTip.y - 1.5, 3, 3);
      }
      ctx.strokeStyle = "#f43f5e";
      ctx.lineWidth = 1.6;
      ctx.stroke();
      ctx.beginPath();
      for (let x = -totalLength * 0.5; x <= totalLength * 0.5; x += 4) {
        const bField = Math.sin(x * k - t * 3.5) * (70 * waveAmp * scale);
        const p = project3D(x, 0, bField, rotX, rotY, rotZ, cx, cy, 450, 520);
        if (x === -totalLength * 0.5) ctx.moveTo(p.x, p.y);
        else ctx.lineTo(p.x, p.y);
      }
      ctx.strokeStyle = "#f43f5e";
      ctx.shadowColor = "#f43f5e";
      ctx.shadowBlur = 10;
      ctx.lineWidth = 2.2;
      ctx.stroke();
      ctx.shadowBlur = 0;
      ctx.restore();
      ctx.save();
      ctx.font = "11px monospace";
      ctx.fillStyle = "rgba(56, 189, 248, 0.9)";
      ctx.fillText(`Maxwell's Equations \u2014 Electromagnetic Wave Propagation`, 20, 28);
      ctx.fillStyle = "#94a3b8";
      ctx.fillText(`\u2207 \xD7 E = -\u2202B/\u2202t  |  \u2207 \xD7 B = \u03BC\u2080\u03B5\u2080 \u2202E/\u2202t  |  c = 1/\u221A(\u03BC\u2080\u03B5\u2080)`, 20, 44);
      ctx.fillText(`Electric Vector E(x,t) [Cyan] \u22A5 Magnetic Vector B(x,t) [Rose] \u22A5 Poynting Vector S [Gold]`, 20, 60);
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "frequency",
    "label": "Wave Frequency (ω)",
    "type": "range",
    "min": 0.5,
    "max": 2.5,
    "step": 0.1,
    "defaultValue": 1.2,
    "description": "Angular frequency of the electromagnetic oscillation"
  },
  {
    "key": "amplitude",
    "label": "Field Amplitude (E₀)",
    "type": "range",
    "min": 0.4,
    "max": 1.8,
    "step": 0.1,
    "defaultValue": 1,
    "description": "Peak electric and magnetic field amplitude"
  }
];

if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['maxwell-em-wave']) {
  const inst = typeof createMaxwellEMWave === 'function' ? createMaxwellEMWave() : null;
  if (inst && inst.setup) {
    inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
  }
  window.__art_instances['maxwell-em-wave'] = inst;
}

const instance = window.__art_instances['maxwell-em-wave'];
if (instance && instance.render) {
  instance.render(
    { ctx, width, height, dpr: 1, aspectRatio: width / height },
    { time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
    defaultParams
  );
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

medium
Analytical Equation
×E=Bt,×B=μ0ϵ0Et,S=1μ0(E×B)\nabla \times \mathbf{E} = -\frac{\partial \mathbf{B}}{\partial t}, \quad \nabla \times \mathbf{B} = \mu_0\epsilon_0\frac{\partial \mathbf{E}}{\partial t}, \quad \mathbf{S} = \frac{1}{\mu_0}(\mathbf{E} \times \mathbf{B})
Click to expand
Compact Formula
E(z,t) = E_0 sin(kz - wt) j_hat; B(z,t) = B_0 sin(kz - wt) k_hat;

Mathematical Tags

#electrodynamics #maxwell-equations #em-wave #poynting-vector #physics-study #vector-fields
Author: Electrodynamics Core Target: 60 FPS

Export & Embed: Maxwell's EM Wave Propagation

4K PNG Snapshot

High-resolution single frame render

WebM Video (5s Loop)

60 FPS browser-captured stream

Standalone JS Script

Complete executable Canvas 2D algorithm

HTML Iframe Embed

<iframe src="https://art.fazleyrabbi.xyz/embed/maxwell-em-wave" width="500" height="500" frameborder="0" loading="lazy"></iframe>
ESC
↑↓ Navigate Select
110 Mathematical Artworks
Made by Fazley Rabbi

Support the Project

Keep mathematical creative coding alive & open source

Or via Direct Payoneer ($0 Fee)
Payoneer Customer ID: $0 Fee Direct
24076084

💡 Payoneer app: Go to Pay → Pay to recipient → Enter ID 24076084.

Thank you for supporting generative mathematical animations! ✨