Fourier Harmonics
Visual mechanical decomposition of square and sawtooth waves into revolving epicyclic phasor circles based on Fourier analysis.
60 FPS • Canvas 2D
Click + Drag to interact with field
</>
Full Executable Algorithm Code
108 lines
3458 chars
// 017 - Fourier Harmonics (waves)
// 1:1 Original algorithm engine source
function createFourierHarmonics() {
const MAX_HISTORY = 400;
const historyY = new Float32Array(MAX_HISTORY);
let historyCount = 0;
return {
setup() {
historyCount = 0;
},
render(context, timeState, params) {
const { ctx, width, height } = context;
const t = timeState.time * Number(params.speed || 1.2);
const harmonics = Math.min(15, Number(params.harmonicCount || 7));
const waveType = params.waveType || "square";
ctx.fillStyle = "#08090d";
ctx.fillRect(0, 0, width, height);
let x = width * 0.28;
let y = height * 0.5;
const baseRadius = Math.min(width, height) * 0.18;
for (let i = 0; i < harmonics; i++) {
const prevX = x;
const prevY = y;
const n = waveType === "square" ? i * 2 + 1 : i + 1;
const radius = waveType === "square" ? baseRadius * (4 / (n * Math.PI)) : baseRadius * (2 / (n * Math.PI));
x += radius * Math.cos(n * t);
y += radius * Math.sin(n * t);
ctx.strokeStyle = hsla((i * 35 + 200) % 360, 80, 60, 0.35);
ctx.lineWidth = 1;
ctx.beginPath();
ctx.arc(prevX, prevY, radius, 0, Math.PI * 2);
ctx.stroke();
ctx.strokeStyle = hsla((i * 35 + 200) % 360, 90, 70, 0.7);
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x, y);
ctx.stroke();
}
if (historyCount < MAX_HISTORY) {
historyY[historyCount++] = y;
} else {
for (let i = 0; i < MAX_HISTORY - 1; i++) {
historyY[i] = historyY[i + 1];
}
historyY[MAX_HISTORY - 1] = y;
}
const waveStartX = width * 0.52;
ctx.strokeStyle = "rgba(56, 189, 248, 0.5)";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(waveStartX, y);
ctx.stroke();
ctx.beginPath();
for (let i = 0; i < historyCount; i++) {
const px = waveStartX + i / MAX_HISTORY * (width * 0.44);
const py = historyY[historyCount - 1 - i];
if (i === 0) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.strokeStyle = hsla((t * 20 + 190) % 360, 95, 65, 0.9);
ctx.lineWidth = 2.2;
ctx.stroke();
}
};
}
// Default parameters from content metadata
const defaultParams = [
{
"key": "harmonicCount",
"label": "Harmonic Phasors (N)",
"type": "range",
"min": 1,
"max": 15,
"step": 1,
"defaultValue": 7,
"description": "Fourier series terms"
},
{
"key": "speed",
"label": "Phasor Rotation Speed",
"type": "range",
"min": 0.3,
"max": 3,
"step": 0.1,
"defaultValue": 1.2,
"description": "Fundamental frequency speed"
}
];
if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['fourier-harmonics']) {
const inst = typeof createFourierHarmonics === 'function' ? createFourierHarmonics() : null;
if (inst && inst.setup) {
inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
}
window.__art_instances['fourier-harmonics'] = inst;
}
const instance = window.__art_instances['fourier-harmonics'];
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
f(t)=π4k=1,3,5…∑Nk1sin(kωt)
Click to expand
∑
Fourier Harmonics
Full Mathematical System • waves
100%
Complete System of Equations
[Governing Law][Discrete Progression][Domain & Space][Parameter State]f(t)=π4k=1,3,5…∑Nk1sin(kωt)rk=(4/kπ)⋅R,x+=rkcos(kt),y+=rksin(kt),trace(y)x∈R2,t∈R+,ω∈[0,2π]λharmonicCount=7(Harmonic Phasors (N)),λspeed=1.2(Phasor Rotation Speed)
f(t)=π4k=1,3,5…∑Nk1sin(kωt)
Computational Implementation (JavaScript Engine Equivalent)
r_k = (4 / kπ) * R, x += r_k cos(k t), y += r_k sin(k t), trace(y) Compact Formula
r_k = (4 / kπ) * R, x += r_k cos(k t), y += r_k sin(k t), trace(y) Mathematical Tags
#fourier
#epicycles
#harmonics
#signal-processing
#waves
#synthesis
Author: Math Art Core Target: 60 FPS
Press ESC or F to exit