xxxxxxxxxx
87
// https://upload.wikimedia.org/wikipedia/commons/b/bd/Fourier_series_square_wave_circles_animation.svg
let wavePoints = [];
let theta = 0;
squareWaveSeries = (i) => (2 * i) + 1
squareWaveRadius = (n) => 4 / (n * PI)
squareWaveFreq = (n, theta) => n * theta
sawtoothWaveSeries = (i) => i + 1
sawtoothWaveRadius = (n) => {
if (n % 2 === 0) return 2 / (-1 * n * PI)
else return 2 / (n * PI)
}
sawtoothWaveFreq = (n, theta) => n * theta
let waveSeriesFn = squareWaveSeries
let radiusFn = squareWaveRadius
let freqFn = squareWaveFreq
//let waveSeriesFn = sawtoothWaveSeries
//let radiusFn = sawtoothWaveRadius
//let freqFn = squareWaveFreq
let rotationSpeed = 0.03
// quanto maior o nCircles (slider.value()), mais se aproxima da onda que ser quer imitar
// let nCricles = 7
let scaleRadius = 100
let radius = 0
let translateX = 200;
let translateY = 200;
function setup() {
createCanvas(1000, 600);
slider = createSlider(1, 20, 3);
}
function draw() {
background(0);
let xCoord = 0;
let yCoord = 0;
theta += rotationSpeed
for (let i = 0; i < slider.value(); i++ ) {
let n = waveSeriesFn(i)
radius = radiusFn(n) * scaleRadius
let freq = freqFn(n, theta)
stroke(255, 100)
noFill()
ellipse(xCoord + translateX, yCoord + translateY, radius * 2)
let prevCoordX = xCoord
let prevCoordY = yCoord
xCoord += radius * sin(freq)
yCoord += radius * cos(freq)
stroke(255)
line(prevCoordX + translateX, prevCoordY + translateY, xCoord + translateX, yCoord + translateY)
}
let shift = 200
wavePoints.unshift(xCoord)
// eliminate the points out of the canvas
if (wavePoints.length > width - (translateX + shift)) wavePoints.pop()
// draw sinusoid
beginShape()
wavePoints.forEach((value, index) => vertex(index + translateX + shift, value + translateY))
endShape()
// draw line connecting the last rotating circle to the sinusoied
fill(255)
ellipse(xCoord + translateX, yCoord + translateY, 3)
line(xCoord + translateX, yCoord + translateY, 0 + translateX + shift, wavePoints[0] + translateY)
}