Files

28 lines
1.4 KiB
JavaScript

import { port } from './model.js';
import { measure } from './motion.js';
function bezier(a, b, c, d) {
return Array.from({ length: 37 }, (_, i) => {
const t = i / 36, u = 1 - t;
return { x: u ** 3 * a.x + 3 * u * u * t * b.x + 3 * u * t * t * c.x + t ** 3 * d.x,
y: u ** 3 * a.y + 3 * u * u * t * b.y + 3 * u * t * t * c.y + t ** 3 * d.y };
});
}
export function departure(route, kind, screen, perimeter) {
const points = route.points.map(screen), end = points.at(-1), dir = port(kind, route.exitDir);
const direction = { x: dir.x * 2, y: dir.y * 2 };
const hit = perimeter.intersect(end, direction);
const a = hit.parameter + 26 / perimeter.unit;
const entry = perimeter.at(a), tangent = { x: Math.cos(entry.angle), y: Math.sin(entry.angle) };
const join = bezier(end, { x: end.x + direction.x * hit.distance * .65, y: end.y + direction.y * hit.distance * .65 },
{ x: entry.x - tangent.x * 18, y: entry.y - tangent.y * 18 }, entry);
return { path: measure([...points, ...join.slice(1)]), boardLength: measure(points).length, entry: a, connector: join };
}
export function garagePath(perimeter, width) {
const finish = perimeter.at(0);
return measure(bezier(finish,
{ x: finish.x + Math.cos(finish.angle) * 22, y: finish.y + Math.sin(finish.angle) * 22 },
{ x: width - 76, y: finish.y - 8 }, { x: width - 62, y: finish.y - 36 }));
}