Last active
December 10, 2019 08:44
-
-
Save AHaliq/6151cc5a3da6718724a8942e221f1a2e to your computer and use it in GitHub Desktop.
Coding Train Challenge #125, fourier series implemented in functional style with waves in terms of amplitude, frequency and range
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let STAGE_WIDTH = 800; | |
const STAGE_HEIGHT = 400; | |
const L_BORDER = 25; | |
const COLBG = 220; | |
const COL1 = 100; | |
const COL2 = 195; | |
const PIVOTRADI = 10; | |
const LINEGAP = 5; | |
let UNITRADI = 50; | |
let DW; | |
let RT_BORDER; | |
let LM_X = 0; | |
const LM_MAXT = 600; | |
let LM_T = 0; | |
let TICK = 0.03; | |
let D = []; | |
let wave = []; | |
let time = 0; | |
let presetIndex = 0; | |
const PRESETS = [ | |
["square","4/(PI*((2*i)+1))","(2*i)+1","0"], | |
["sawtooth","2/(PI*(i+1))*pow(-1,(i+1))","i+1","0"], | |
["phased square","4/(PI*((2*i)+1))","(2*i)+1","PI/20"], | |
]; | |
function setup() { | |
STAGE_WIDTH = windowWidth; | |
createCanvas(STAGE_WIDTH, STAGE_HEIGHT); | |
//D = [[50,1,0],[25,2,0],[10,3,0]] // manual diagram test | |
var gen = (n,a,f,p) => Array.apply(null, Array(n)).map((_,i)=>i).map( | |
(i) => [UNITRADI * eval(a), eval(f), eval(p)]); | |
let a_TXT = createInput(); | |
let f_TXT = createInput(); | |
let p_TXT = createInput(); | |
let BTN = createButton("submit"); | |
let TICK_SLIDER = createSlider(1,20,3); | |
let UNITRADI_SLIDER = createSlider(25,100,50); | |
let ITERATIONS_SLIDER = createSlider(1,20,3); | |
let SEL = createSelect(); | |
PRESETS.map(([o]) => SEL.option(o)); | |
const setupD = () => { | |
n = ITERATIONS_SLIDER.value(); | |
D = gen(n,a_TXT.value(), f_TXT.value(), p_TXT.value()); | |
DW = D.reduce((pr,[a,f,p]) => pr + abs(a),0); | |
updateBorder(); | |
} | |
const setpresetText = () => { | |
a_TXT.value(PRESETS[presetIndex][1]); | |
f_TXT.value(PRESETS[presetIndex][2]); | |
p_TXT.value(PRESETS[presetIndex][3]); | |
} | |
setpresetText(); | |
SEL.changed(() => { | |
presetIndex = PRESETS.reduce((pr,[name,a,f,p],i) => | |
SEL.value() == name ? i : pr,-1); | |
setpresetText(); | |
setupD(); | |
}); | |
BTN.mousePressed(() => setupD()); | |
TICK_SLIDER.input(() => TICK = TICK_SLIDER.value()/100); | |
UNITRADI_SLIDER.input(() => { | |
UNITRADI = UNITRADI_SLIDER.value(); | |
setupD(); | |
}); | |
ITERATIONS_SLIDER.input(() => { | |
setupD(); | |
}); | |
setupD(); | |
} | |
function updateBorder() { | |
RT_BORDER = STAGE_WIDTH + LM_X - L_BORDER * 2; | |
} | |
function draw() { | |
background(COLBG); | |
translate(-LM_X + L_BORDER, STAGE_HEIGHT * 0.5); | |
if(LM_T < LM_MAXT) { | |
LM_T++; | |
}else { | |
LM_X++; | |
}// ease retract left min border | |
(([x,y]) => { | |
stroke(COL2); | |
noFill(); | |
line(LM_X, 0, RT_BORDER, 0); | |
line(x,y,DW,y); | |
ellipse(DW,y,PIVOTRADI); | |
stroke(COL1); | |
beginShape(); | |
wave.unshift(y); | |
wave = wave.splice(0, RT_BORDER - DW); | |
wave.map((y,i) => vertex(DW + i, y)); | |
endShape(); | |
}) (D.reduce(([x,y],[a,f,p],i) => { | |
let nx = x + a * cos(p + f * time); | |
let ny = y + a * sin(p + f * time); | |
// calculate pivot point | |
let olmx = LM_X; | |
LM_X = min(LM_X, x - abs(a)); | |
if(olmx != LM_X || round((olmx - (x - abs(a)))*0.1) == 0) LM_T = 0; | |
updateBorder(); | |
// calculate left minimum border | |
stroke(COL2); | |
noFill(); | |
ellipse(nx,ny,PIVOTRADI); | |
ellipse(x,y,a * 2); | |
let rx = DW - ((D.length - 1) * LINEGAP) + (i * LINEGAP); | |
line(rx,y,rx,ny); | |
ellipse(rx,ny,LINEGAP); | |
fill(COL1); | |
stroke(COL1); | |
line(x,y,nx,ny); | |
return [nx, ny]; | |
}, [0,0])); | |
time += TICK; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment