wave-function-collapse-3d.js

total 0
used 0
limit 0
/* title: Wave Function Collapse Rotating 3D Cube category: geometry files: head point stage ../point_src/stage.js dragging pointlist mouse --- 5 x 5 x 5 socket-constrained tiles. Rotating projected lattice, visible resolution and connections. */ const N=5, TOTAL=125; const D=[[1,0,0],[-1,0,0],[0,1,0],[0,-1,0],[0,0,1],[0,0,-1]], OP=[1,0,3,2,5,4]; const tiles=Array.from({length:64},(_,i)=>i); function xyz(i){return [i%5,Math.floor(i/5)%5,Math.floor(i/25)];} function neighbor(i,d){const p=xyz(i),v=D[d],x=p[0]+v[0],y=p[1]+v[1],z=p[2]+v[2];return x<0||x>=5||y<0||y>=5||z<0||z>=5?-1:x+5*y+25*z;} class CubeStage extends Stage{ canvas='playspace'; mounted(){ this.reset(); this.canvas.addEventListener('click',()=>this.reset()); window.addEventListener('keydown',e=>{if(e.code==='Space'){this.paused=!this.paused;e.preventDefault();}}); } reset(){ this.cells=Array.from({length:TOTAL},()=>tiles.slice()); this.steps=0;this.completed=false;this.dead=false;this.paused=false;this.last=0;this.angle=0;this.propagate(); } propagate(){ const queue=Array.from({length:TOTAL},(_,i)=>i); let cursor=0; while(cursor20000){this.dead=true;return;} const i=queue[cursor++]; for(let d=0;d<6;d++){ const j=neighbor(i,d); if(j<0){const keep=this.cells[i].filter(t=>!(t&(1<=0)queue.push(nb);}}} else { const permitted=this.cells[i].filter(t=>this.cells[j].some(u=>!!(t&(1<=0)queue.push(nb);}} } if(!this.cells[i].length){this.dead=true;return;} } } } step(){ if(this.completed||this.dead)return; const possible=[]; let best=Infinity; for(let i=0;i1){if(nc.length===1))this.completed=true; } project(p,w,h,scale){ const x=p[0]-2,y=p[1]-2,z=p[2]-2; // Three simultaneous Euler-axis rotations at different speeds. const ax=this.angle*.71,ay=this.angle,az=this.angle*.39; const sx=Math.sin(ax),cx=Math.cos(ax); const sy=Math.sin(ay),cy=Math.cos(ay); const sz=Math.sin(az),cz=Math.cos(az); // Rotate around X, then Y, then Z. const y1=y*cx-z*sx,z1=y*sx+z*cx; const xr=x*cy+z1*sy,zr=-x*sy+z1*cy; const yr=xr*sz+y1*cz,screenX=xr*cz-y1*sz; const depth=zr; const perspective=7.5/(7.5+depth*.12); return {x:w/2+screenX*scale*perspective,y:h/2+18+yr*scale*perspective,depth}; } draw(ctx){ const w=this.canvas.width,h=this.canvas.height; ctx.fillStyle='#0b1320';ctx.fillRect(0,0,w,h); this.angle+=.004; if(!this.paused&&!this.completed&&performance.now()-this.last>130){if(this.dead)this.reset();else this.step();this.last=performance.now();} ctx.textAlign='center';ctx.fillStyle='#e5f9ff';ctx.font='bold 20px sans-serif';ctx.fillText('3D WAVE FUNCTION COLLAPSE',w/2,34); ctx.font='14px sans-serif';ctx.fillStyle='#a2b8cc'; const settled=this.cells.filter(v=>v.length===1).length; ctx.fillText(settled+'/125 cells resolved · '+this.steps+' choices · '+(this.completed?'complete':this.paused?'paused':'collapsing'),w/2,58); ctx.fillText('Click to regenerate · Space to pause',w/2,h-18); const scale=Math.min(w*.115,(h-130)*.12); const points=Array.from({length:TOTAL},(_,i)=>this.project(xyz(i),w,h,scale)); const depthOrder=Array.from({length:TOTAL},(_,i)=>i).sort((a,b)=>points[b].depth-points[a].depth); ctx.lineWidth=1;ctx.strokeStyle='rgba(93,129,151,0.12)'; for(let i=0;ib.depth-a.depth); for(const s of segments){ctx.strokeStyle='rgba(101,231,215,0.8)';ctx.lineWidth=Math.max(2,scale*.14);ctx.lineCap='round';ctx.beginPath();ctx.moveTo(s.a.x,s.a.y);ctx.lineTo(s.b.x,s.b.y);ctx.stroke();} for(const i of depthOrder){ const p=points[i],n=this.cells[i].length; ctx.beginPath();ctx.arc(p.x,p.y,n===1?Math.max(3,scale*.13):Math.max(1.5,scale*.06),0,Math.PI*2); ctx.fillStyle=n===1?'#bafff0':'rgba(122,151,189,0.22)';ctx.fill(); } } } const stage=CubeStage.go();
Run
Meta Data
title Wave Function Collapse Rotating 3D Cube
imports ()
files ('head', 'point', 'stage', '../point_src/stage.js', 'dragging', 'pointlist', 'mouse')
unused_keys ()
unknown_keys ('category',)
category ['geometry']
filepath_exists True
path wave-function-collapse-3d.js
filepath wave-function-collapse-3d.js
clean_files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/point-content.js', '../point_src/pointdraw.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/stage-hooks.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js', '../point_src/functions/clamp.js', '../point_src/distances.js', '../point_src/protractor.js', '../point_src/text/beta.js', '../point_src/dragging.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/pointlistpen.js', '../point_src/events.js', '../point_src/automouse.js')
markdown {'html': '<p>5 x 5 x 5 socket-constrained tiles. Rotating projected lattice, visible resolution and connections.</p>', 'content': 'title: Wave Function Collapse Rotating 3D Cube\ncategory: geometry\nfiles:\n head\n point\n stage\n ../point_src/stage.js\n dragging\n pointlist\n mouse\n---\n5 x 5 x 5 socket-constrained tiles. Rotating projected lattice, visible resolution and connections.'}