Add dynamic SAT collision, oval/circle shapes, rotation support, and score display

This commit is contained in:
2026-10-17 22:01:54 -04:00
parent d1af53cf07
commit f596a48899
11 changed files with 278 additions and 112 deletions
+14 -6
View File
@@ -1,6 +1,7 @@
import type { LayoutEvaluation, LayoutState } from '../types';
import { evaluateLayout } from '../layout/evaluator';
import { entranceRect, findFreeSpot, overlapsAny, resolveMove } from '../geometry/bounds';
import { entranceCollider, findFreeSpot, furnitureCollider, overlapsAny, resolveMove } from '../geometry/bounds';
import type { Collider } from '../geometry/collision';
export interface NNOptions {
gridSize?: number;
@@ -57,14 +58,21 @@ export function optimizeWithNN(state: LayoutState, options: NNOptions = {}): { b
if (targetX < 0) targetX = 0;
if (targetY < 0) targetY = 0;
const room = candidate.room;
const others: any[] = candidate.furniture
const others: Collider[] = candidate.furniture
.filter((o) => o.id !== f.id)
.map((o) => ({ x: o.shape.x, y: o.shape.y, width: o.shape.width, height: o.shape.height }));
const ent = entranceRect(candidate);
.map(furnitureCollider);
const ent = entranceCollider(candidate);
if (ent) others.push(ent);
const b = overlapsAny({ x: targetX, y: targetY, width: f.shape.width, height: f.shape.height }, others)
const moving: Collider = {
x: targetX,
y: targetY,
width: f.shape.width,
height: f.shape.height,
rotation: f.shape.rotation ?? 0,
};
const b = overlapsAny(moving, others)
? findFreeSpot(room, { width: f.shape.width, height: f.shape.height }, others)
: resolveMove({ x: targetX, y: targetY, width: f.shape.width, height: f.shape.height }, others, room);
: resolveMove(moving, others, room);
f.shape.x = b.x;
f.shape.y = b.y;
f.shape.width = b.width;