Add venue planner: OOP furniture, shapes, conditions, room/birds-eye UI, layout+optimize modes, pathfinding, random search + NN stub
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import type { LayoutEvaluation, LayoutState } from '../types';
|
||||
import { evaluateLayout } from '../layout/evaluator';
|
||||
|
||||
export interface NNOptions {
|
||||
gridSize?: number;
|
||||
iterations?: number;
|
||||
}
|
||||
|
||||
export function optimizeWithNN(state: LayoutState, options: NNOptions = {}): { bestState: LayoutState; bestEval: LayoutEvaluation } {
|
||||
const candidate: LayoutState = {
|
||||
room: { ...state.room },
|
||||
entrance: state.entrance ? { ...state.entrance } : null,
|
||||
furniture: state.furniture.map((f) => ({
|
||||
...f,
|
||||
shape: { ...f.shape, points: f.shape.points?.map((p) => ({ ...p })) },
|
||||
})),
|
||||
};
|
||||
|
||||
const entrance = candidate.entrance;
|
||||
const centerX = candidate.room.width / 2;
|
||||
const centerY = candidate.room.height / 2;
|
||||
|
||||
for (const f of candidate.furniture) {
|
||||
if (f.lockedForOptimization) continue;
|
||||
let targetX = f.shape.x;
|
||||
let targetY = f.shape.y;
|
||||
const needsNearEntrance = f.conditions.some((c) => c.kind === 'near_entrance');
|
||||
const needsCenter = f.conditions.some((c) => c.kind === 'around_open_area');
|
||||
if (entrance && needsNearEntrance) {
|
||||
targetX = entrance.x + (Math.random() - 0.5) * 40;
|
||||
targetY = entrance.y + (Math.random() - 0.5) * 40;
|
||||
} else if (needsCenter) {
|
||||
targetX = centerX - f.shape.width / 2 + (Math.random() - 0.5) * 60;
|
||||
targetY = centerY - f.shape.height / 2 + (Math.random() - 0.5) * 60;
|
||||
} else {
|
||||
targetX = Math.random() * (candidate.room.width - f.shape.width);
|
||||
targetY = Math.random() * (candidate.room.height - f.shape.height);
|
||||
}
|
||||
if (targetX < 0) targetX = 0;
|
||||
if (targetY < 0) targetY = 0;
|
||||
if (targetX + f.shape.width > candidate.room.width) targetX = candidate.room.width - f.shape.width;
|
||||
if (targetY + f.shape.height > candidate.room.height) targetY = candidate.room.height - f.shape.height;
|
||||
f.shape.x = targetX;
|
||||
f.shape.y = targetY;
|
||||
}
|
||||
|
||||
const bestEval = evaluateLayout(candidate, options.gridSize || 10);
|
||||
return { bestState: candidate, bestEval };
|
||||
}
|
||||
Reference in New Issue
Block a user