228

Fourier Epicycles Transform

Visualizes the mathematical foundation of the Fourier Transform in the complex plane. Chains rotating complex exponential phasor gears (epicycles) summing harmonic modes to reconstruct complex geometric curves, complete with live amplitude spectrum bars.

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

Full Executable Algorithm Code

// 059 - Fourier Epicycles Transform (physics)
// 1:1 Original algorithm engine source
function createFourierEpicycles() {
  const N_MAX = 24;
  const harmonics = [];
  for (let k = 1; k <= N_MAX; k++) {
    const freq = k % 2 === 1 ? k : -k;
    const r = 110 / Math.abs(freq) * (1 / (1 + Math.abs(freq) * 0.05));
    harmonics.push({ k: freq, radius: r, phase: k * 0.4 });
  }
  harmonics.sort((a, b) => b.radius - a.radius);
  const drawnTrail = [];
  return {
    setup() {
      drawnTrail.length = 0;
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const terms = Math.min(harmonics.length, Math.floor(Number(params.termsCount || 16)));
      const rotSpeed = Number(params.cycleSpeed || 0.6);
      const t = timeState.time * rotSpeed;
      ctx.fillStyle = "#020409";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.46;
      const cy = height * 0.5;
      let curX = cx;
      let curY = cy;
      ctx.save();
      ctx.globalCompositeOperation = "screen";
      for (let i = 0; i < terms; i++) {
        const h = harmonics[i];
        const prevX = curX;
        const prevY = curY;
        const theta = h.k * t + h.phase;
        curX += h.radius * Math.cos(theta);
        curY += h.radius * Math.sin(theta);
        ctx.beginPath();
        ctx.arc(prevX, prevY, h.radius, 0, Math.PI * 2);
        ctx.strokeStyle = "rgba(56, 189, 248, 0.2)";
        ctx.lineWidth = 1;
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(curX, curY);
        ctx.strokeStyle = "rgba(56, 189, 248, 0.7)";
        ctx.lineWidth = 1.4;
        ctx.stroke();
        ctx.fillStyle = "#38bdf8";
        ctx.beginPath();
        ctx.arc(curX, curY, 2.5, 0, Math.PI * 2);
        ctx.fill();
      }
      drawnTrail.push({ x: curX, y: curY });
      if (drawnTrail.length > 550) drawnTrail.shift();
      if (drawnTrail.length > 2) {
        ctx.beginPath();
        for (let i = 0; i < drawnTrail.length; i++) {
          const pt = drawnTrail[i];
          if (i === 0) ctx.moveTo(pt.x, pt.y);
          else ctx.lineTo(pt.x, pt.y);
        }
        ctx.strokeStyle = "#f43f5e";
        ctx.shadowColor = "#f43f5e";
        ctx.shadowBlur = 12;
        ctx.lineWidth = 2.4;
        ctx.stroke();
        ctx.shadowBlur = 0;
      }
      const specX = width - 150;
      const specY = height - 120;
      const specW = 130;
      const specH = 95;
      ctx.restore();
      ctx.save();
      ctx.fillStyle = "rgba(15, 23, 42, 0.85)";
      ctx.strokeStyle = "rgba(56, 189, 248, 0.3)";
      ctx.lineWidth = 1;
      ctx.strokeRect(specX, specY, specW, specH);
      ctx.fillRect(specX, specY, specW, specH);
      ctx.font = "9px monospace";
      ctx.fillStyle = "#94a3b8";
      ctx.fillText("Fourier Spectrum |c_k|", specX + 8, specY + 14);
      const barWidth = Math.max(3, (specW - 20) / terms);
      for (let k = 0; k < terms; k++) {
        const barH = harmonics[k].radius / harmonics[0].radius * 60;
        const bx = specX + 10 + k * barWidth;
        const by = specY + specH - 10 - barH;
        ctx.fillStyle = "#38bdf8";
        ctx.fillRect(bx, by, barWidth - 1, barH);
      }
      ctx.font = "11px monospace";
      ctx.fillStyle = "rgba(56, 189, 248, 0.9)";
      ctx.fillText(`Fourier Transform & Epicycles \u2014 Complex Analysis`, 20, 28);
      ctx.fillStyle = "#94a3b8";
      ctx.fillText(`f(t) = \u2211_{k=-N}^N c_k e^{i k \u03C9 t} | c_k = 1/T \u222B_0^T f(t) e^{-i k \u03C9 t} dt`, 20, 44);
      ctx.fillText(`Active Epicycle Phasors: ${terms} harmonic modes | Reconstruction Error \u2192 0`, 20, 60);
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "termsCount",
    "label": "Harmonic Terms (N)",
    "type": "range",
    "min": 2,
    "max": 24,
    "step": 1,
    "defaultValue": 16,
    "description": "Number of active Fourier epicycle phasor modes"
  },
  {
    "key": "cycleSpeed",
    "label": "Rotation Speed",
    "type": "range",
    "min": 0.2,
    "max": 2,
    "step": 0.1,
    "defaultValue": 0.6,
    "description": "Fundamental angular frequency ω"
  }
];

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

const instance = window.__art_instances['fourier-epicycles-transform'];
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

high
Analytical Equation
f(t)=k=NNckeikωt,ck=1T0Tf(t)eikωtdtf(t) = \sum_{k=-N}^{N} c_k e^{i k \omega t}, \quad c_k = \frac{1}{T} \int_0^T f(t) e^{-i k \omega t} dt
Click to expand
Compact Formula
z(t) = sum(c_k * exp(i * k * omega * t))

Mathematical Tags

#fourier-transform #complex-analysis #epicycles #phasors #math-study #signal-processing
Author: Harmonic Analysis Core Target: 60 FPS

Export & Embed: Fourier Epicycles Transform

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/fourier-epicycles-transform" 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! ✨