【p5js】近くから見ると青海波、遠くから見るとアインシュタイン
ってのをやりたかったけど、近くから見てもアインシュタイン
以下ソース
const p = { height: 1500, r: 100, dr:12, dt:5, ds:3, get strokeMax(){ return this.strokeMin+this.ds; }, get strokeMin(){ return this.dr; } } let img; function preload(){ img=loadImage('data:image/jpeg;base64/*省略*/'); } function setup() { angleMode(DEGREES); console.assert(p.dr*cos(p.dt/2)>2*p.strokeMax,'probably circle hit line') p['width']=img.width*p.height/img.height; createCanvas(p.width,p.height); background(220); for (let y = 0; y <= p.height + 100; y += p.r) { for (let x = 0; x <= p.width+100; x += p.r * sqrt(3)) { multiCircle(x,y); } const y_ = y + p.r / 2; for (let x = sqrt(3) * p.r / 2; x <= p.width+100; x += p.r * sqrt(3)) { multiCircle(x,y_); } } save('albert.png'); } function draw() { } const multiCircle = (centerX, centerY) => { const dr=p.dr; for (let r = p.r; r > 0; r -= dr) { oneCircle(centerX, centerY, r); } } const oneCircle = (centerX, centerY, size) => { let theta = 150; const dt = p.dt; let x = centerX - size * cos(theta); let y = centerY - size * sin(theta); for (; theta > 30; theta -= dt) { const xx = centerX - size * cos(theta - dt); const yy = centerY - size * sin(theta - dt); const gray=color2Gray(-getAveGray((x+xx)/2,(y+yy)/2,2,2)); strokeWeight(gray2Weight(gray)); stroke(color(44,96,gray2narrow(gray))); line(x, y, xx, yy); [x, y] = [xx, yy]; } noStroke(); circle(centerX, centerY, (size*cos(dt/2)) *2); stroke(color(44,96,255)); // stroke(1); } const getGray=(color)=>{ return (color[0]+color[1]+color[2])/3.0; } const getAveGray=(centerX,centerY,dx,dy)=>{ let sumGray=0.0; for(let x=centerX-dx;x<=centerX+dx;x+=1){ for(let y=centerY-dy;y<=centerY+dy;y+=1){ sumGray+=getGray(img.get(convertPos(x),convertPos(y))); } } return sumGray/((dx*2)*(dy*2)); } const convertPos=(x)=>{ return x*img.height/p.height; } const color2Gray=(x)=>{ return map(x,-255,0,0,255); } const gray2Weight=(x)=>{ return map(x,0,255,p.strokeMin,p.strokeMax); } const gray2narrow=(x)=>{ return map(x,0,255,230,255); }