mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-13 21:27:41 +02:00
[eric] dashboard: spawn picks the EUCLIDEAN-nearest open gap, not the first ring-scan cell (3rd card flung to a far corner when a big browser blocked the near cells)
This commit is contained in:
@@ -386,8 +386,18 @@ export function findOpenSpotNear(
|
||||
};
|
||||
}
|
||||
|
||||
// Spiral by ring perimeter; right/down preference for stability.
|
||||
// Ring order approximates distance but returns the first-in-scan cell, which flings a card to a
|
||||
// far corner when the near cells are blocked (a big browser + expanded chats). Instead pick the
|
||||
// cell CLOSEST to the anchor by real distance: scan outward, and once a ring yields a free cell,
|
||||
// scan ONE more ring (a ring-r corner ~r*1.41 can lose to a ring-(r+1) edge) then take the nearest.
|
||||
const MAX_RING = 32;
|
||||
const spotDist = (col: number, row: number): number => {
|
||||
const x = GRID_ORIGIN.x + col * cellW;
|
||||
const y = GRID_ORIGIN.y + row * cellH;
|
||||
return Math.hypot(x - anchorX, y - anchorY);
|
||||
};
|
||||
let best: { col: number; row: number; d: number } | null = null;
|
||||
let firstHitRing = -1;
|
||||
for (let r = 1; r <= MAX_RING; r++) {
|
||||
for (let dy = -r; dy <= r; dy++) {
|
||||
for (let dx = -r; dx <= r; dx++) {
|
||||
@@ -395,14 +405,20 @@ export function findOpenSpotNear(
|
||||
const col = baseCol + dx;
|
||||
const row = baseRow + dy;
|
||||
if (col < 0 || row < 0) continue;
|
||||
if (cellFree(col, row)) {
|
||||
return {
|
||||
x: GRID_ORIGIN.x + col * cellW,
|
||||
y: GRID_ORIGIN.y + row * cellH,
|
||||
};
|
||||
}
|
||||
if (!cellFree(col, row)) continue;
|
||||
const d = spotDist(col, row);
|
||||
if (!best || d < best.d) best = { col, row, d };
|
||||
}
|
||||
}
|
||||
if (best && firstHitRing === -1) firstHitRing = r;
|
||||
// Scan one ring past the first hit (a ring-r corner can lose to a ring-(r+1) edge), then commit.
|
||||
if (firstHitRing !== -1 && r >= firstHitRing + 1) break;
|
||||
}
|
||||
if (best) {
|
||||
return {
|
||||
x: GRID_ORIGIN.x + best.col * cellW,
|
||||
y: GRID_ORIGIN.y + best.row * cellH,
|
||||
};
|
||||
}
|
||||
|
||||
// Pathological, full canvas occupied near anchor. Fall back to the global first-empty scan so we never return an overlap.
|
||||
|
||||
Reference in New Issue
Block a user