38 lines
2.1 KiB
JavaScript
38 lines
2.1 KiB
JavaScript
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;i<lengths.length;i++) {
|
|
if(distance<=lengths[i]&&lengths[i]>0) {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);});
|
|
}
|