import { position, PORTS, trackPoints } from './path-math.js'; export { hexPoints, trackPoints, PORTS } from './path-math.js'; export function layout(cells,width,height) { const raw=cells.map(c=>position(c.q,c.r)); const minX=Math.min(...raw.map(p=>p.x))-1,maxX=Math.max(...raw.map(p=>p.x))+1; const minY=Math.min(...raw.map(p=>p.y))-.866,maxY=Math.max(...raw.map(p=>p.y))+.866; const size=Math.min((width-48)/(maxX-minX),(height-50)/(maxY-minY),47); const ox=width/2-(minX+maxX)/2*size,oy=height/2-(minY+maxY)/2*size; return {size,ox,oy,bounds:{top:minY*size+oy,bottom:maxY*size+oy}}; } export function center(cell, view) { const p=position(cell.q,cell.r,view.size); return {x:p.x+view.ox,y:p.y+view.oy}; } export function routePoints(route,view,extend=false) { if(route.travelPoints)return route.travelPoints.map(p=>({x:p.x*view.size+view.ox,y:p.y*view.size+view.oy})); const points=[]; route.steps.forEach(s=>{ const c=center(s,view), end=PORTS[s.exit]; if(s.enter===null) points.push(c,{x:c.x+end.x*view.size,y:c.y+end.y*view.size}); else points.push(...trackPoints(c.x,c.y,view.size,s.enter,s.exit)); }); if(route.end) { const c=center(route.end,view);points.push(c); if(extend&&route.status==='exit') {const port=PORTS[route.steps[route.steps.length-1].exit];points.push({x:c.x+port.x*120,y:c.y+port.y*120});} } return points; } export function pointAlong(points,ratio) { const lengths=points.slice(1).map((p,i)=>Math.hypot(p.x-points[i].x,p.y-points[i].y)); let distance=lengths.reduce((a,b)=>a+b,0)*Math.max(0,Math.min(1,ratio)); for(let i=0;i0) {const t=distance/lengths[i],a=points[i],b=points[i+1];return {x:a.x+(b.x-a.x)*t,y:a.y+(b.y-a.y)*t,angle:Math.atan2(b.y-a.y,b.x-a.x)};} distance-=lengths[i]; } const a=points[points.length-2]||points[0],b=points[points.length-1];return {...b,angle:Math.atan2(b.y-a.y,b.x-a.x)}; } export function hitCell(cells,view,x,y) { return cells.find(cell=>{const c=center(cell,view),dx=Math.abs(x-c.x)/view.size,dy=Math.abs(y-c.y)/view.size;return dx<=1&&dy<=Math.sqrt(3)/2&&Math.sqrt(3)*dx+dy<=Math.sqrt(3);}); }