// script: js W=240;H=136;SZ=W*H;MW=W/2;MH=H/2; PALETTE=0x3fc0;SCREEN=0x0000;HOFFSET=0x3ff9;abs=Math.abs;floor=Math.floor;max=Math.max;min=Math.min;sin=Math.sin;cos=Math.cos;rnd=Math.random;pow=Math.pow;sqrt=Math.sqrt;pi=Math.PI;tau=pi*2;function lerp(a,b,t){return a+(b-a)*t};function lin(sx,ex,sy,ey,t,cl=false){if (cl) {t=clamp(sx,ex,t);};return lerp(sy,ey,(t-sx)/(ex-sx))};function uf(a,b){return lerp(a,b,rnd())};function ri(mn,mx){return mn+floor(rnd()*(mx-mn+1))};function clamp(mn,mx,t){return max(min(mx,t),mn)};function ss(x){x=clamp(0,1,x);return x*x*(3.0-2.0*x)};function range(n){return Array.from(Array(n)).map((_,i)=>i)};function hsv2rgb(h,s,v){var h=(h%360); if (h<0){h=(h+360)%360;} let c=v*s; let x=c*(1-abs(((h/60)%2)-1)); let m=v-c; let [r,g,b]=[0,0,0]; if (h<60){[r,g]=[c,x];} else if (h<120){[r,g]=[x,c];} else if (h<180){[g,b]=[c,x];} else if (h<240){[g,b]=[x,c];} else if (h<300){[r,b]=[x,c];} else {[r,b]=[c,x];} return [r,g,b].map((x)=>(x+m)*255|0);};function pick(...vs){return vs[ri(0,vs.length-1)];};function hash(i){var s=floor(i);/*var s=i*747796405+2891336453;*/var w=((s>>((s>>28)+4))^s)*277803737;return (w>>22)^w;}; function viz_track(s=20,cl=false){vbank(1);if(cl){cls();};pix(0,0,11);pix(s,0,11);line(0,1,s*2,1,0);line(0,2,s*2,2,0);pix(le*s,1,12);pix(he*s,2,13);vbank(0);} /* Finkel's Prelude: min,max,abs,floor,pow,sin,cos,rnd pi,tau,sqrt,hash lerp,lin,uf,ri,clamp,ss,range,hsv2rgb pick */ function BOOT(){ cls(0) } class P{ constructor(x,y){ this.x=x this.y=y this.ox=0 this.oy=0 } pos(t){ return [ this.x+this.ox*t, this.y+this.oy*t, ] } reset(){ this.x+=this.ox this.y+=this.oy this.x=(this.x+nx)%nx this.y=(this.y+ny)%ny this.ox=0 this.oy=0 } } function reset(){ vert=pick(true,false) n=vert?nx:ny dirs=range(n).map(_=>pick(-2,-1,-1,0,1,1,2)) ps.forEach(p=>{ p.reset() if (vert){ p.oy=dirs[p.x] } else{ p.ox=dirs[p.y] } }) } nx=10 ny=8 ps=range(nx).flatMap(i=>{ return range(ny).map(j=>new P(i,j)) }) reset() bpm=120 spb=60/bpm period=spb lpt=0 function TIC(){ vbank(1) cls(0) vbank(0) make_pal() secs=time()/1000 pt=secs/period hpt=pt+0.5 pt=pt%1 hpt=hpt%1 if (lpt>pt){ reset() } ps.forEach((p,i)=>{ if (i%2==0){ return } t=pt t*=1 t=clamp(0,1,t) t=pow(t,0.2) var [x,y]=p.pos(t) s=24 m=2 //rect(x*s,y*s,s-m,s-m,i) w=0.9 ocs=[[x,y],[x+w,y],[x+w,y+w],[x,y+w]] tcs=ocs.map(pp=>{ var x=pp[0] var y=pp[1] th=lin(0,nx,0,tau,x) phi=lin(0,ny,0,tau,y) r=30+20*sin(phi) return [MW+sin(th)*r*2,MH-cos(th)*r*1.4] }) rs=ocs.map(pp=>{ var y=pp[1] phi=lin(0,ny,0,tau,y) return sin(phi) }) if (rs[0]>rs[2]){ return } vbank(1) col=12 line(...tcs[0],...tcs[1],col) line(...tcs[1],...tcs[2],col) line(...tcs[2],...tcs[3],col) line(...tcs[3],...tcs[0],col) vbank(0) ix=hash(i+floor(time()))%2 col=ix==0?0:15 col=15 if (hpt<0.1&&ix){ tri(...tcs[0],...tcs[1],...tcs[2],col) tri(...tcs[0],...tcs[3],...tcs[2],col) } }) lpt=pt vbank(0) for(i=0;i0.1){ poke4(i,v-1) } } } function make_pal(){ t=time()/2000 r=lin(-1,1,0.5,2,sin(t)) g=lin(-1,1,0.5,2,sin(t+tau/3)) b=lin(-1,1,0.5,2,sin(t+tau/3*2)) range(16).flatMap(i=>{ x=i/15.0 return [ pow(x,r)*255, pow(x,g)*255, pow(x,b)*255, ] }).forEach((c,i)=>{ poke(PALETTE+i,c) }) }