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.
60 FPS • Canvas 2D
Click + Drag to interact with field
</>
Full Executable Algorithm Code
142 lines
4887 chars
// 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=−N∑Nckeikωt,ck=T1∫0Tf(t)e−ikωtdt
Click to expand
∑
Fourier Epicycles Transform
Full Mathematical System • physics
100%
Complete System of Equations
[Governing Law][Discrete Progression][Domain & Space][Parameter State]f(t)=k=−N∑Nckeikωt,ck=T1∫0Tf(t)e−ikωtdtz(t)=sum(ck⋅exp(i⋅k⋅omega⋅t))x∈R2,t∈R+,ω∈[0,2π]λtermsCount=16(Harmonic Terms (N)),λcycleSpeed=0.6(Rotation Speed)
f(t)=k=−N∑Nckeikωt,ck=T1∫0Tf(t)e−ikωtdt
Computational Implementation (JavaScript Engine Equivalent)
z(t) = sum(c_k * exp(i * k * omega * t)) 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
Press ESC or F to exit