Merge remote-tracking branch 'origin/sub_laptop_3' into main_laptop_1

This commit is contained in:
2026-10-19 14:46:35 +09:00
23 changed files with 729 additions and 72 deletions
+32
View File
@@ -107,3 +107,35 @@ def curve_moves(before: list[tuple[str, float]], after: list[tuple[str, float]])
if best >= 0:
out[key] = free.pop(best)[0]
return out
#: 같은 자리로 보는 중심 차(m) · 축 차 — 브라우저 틀 ↔ 서버 틀 차(467)를 넘김.
SEAT_XY_M = 0.01
SEAT_AXIS = 1e-3
def station_seat(station: dict | None) -> tuple[float, float, tuple[float, float] | None] | None:
"""종단 측점 줄(``center_x`` · ``center_y`` · ``frame.left_xy``) → 자리 · 모르면 None."""
if not isinstance(station, dict):
return None
try:
x, y = float(station["center_x"]), float(station["center_y"])
except (KeyError, TypeError, ValueError):
return None
left = (station.get("frame") or {}).get("left_xy")
axis = (float(left[0]), float(left[1])) if isinstance(left, list) and len(left) == 2 else None
return x, y, axis
def same_seat(a, b) -> bool:
"""노선이 바뀐 뒤 그 측점이 같은 자리인가(요구 275-3) — 짝 ``sameSeat`` · 거울 475-3.
자리 = (x, y, 왼쪽 단위 벡터 | None) · 한쪽을 모르면 같은 자리로 봄(옛 동작).
"""
if a is None or b is None:
return True
if math.hypot(a[0] - b[0], a[1] - b[1]) > SEAT_XY_M:
return False
if a[2] is None or b[2] is None:
return True
return abs(a[2][0] - b[2][0]) <= SEAT_AXIS and abs(a[2][1] - b[2][1]) <= SEAT_AXIS
+27
View File
@@ -97,3 +97,30 @@ export function curveMoves(
}
return out;
}
/** 측점 자리 — 중심 좌표 · 왼쪽 단위 벡터(횡단 축 · 없으면 좌표만 봄). */
export interface StationSeat {
x: number;
y: number;
left?: readonly [number, number] | null;
}
/** 같은 자리로 보는 중심 차(m) · 축 차 — 브라우저 틀 ↔ 서버 틀 차(467)를 넘김. */
export const SEAT_XY_M = 0.01;
export const SEAT_AXIS = 1e-3;
/**
* 노선이 바뀐 뒤 그 측점이 같은 자리인가(요구 275-3) — 자리 · 축이 같으면 지형이 같아 「자리 칸」(암 경계 · 2단
* 경사 · 손 상단측)을 들고 감 · 한쪽 자리를 모르면 같은 자리로 봄(옛 목록 · 옛 동작) · 짝 `same_seat` ·
* 거울 시험 `test_475_3_seat_carry.py`.
*/
export function sameSeat(
a: StationSeat | null | undefined,
b: StationSeat | null | undefined,
): boolean {
if (!a || !b) return true;
if (Math.hypot(a.x - b.x, a.y - b.y) > SEAT_XY_M) return false;
if (!a.left || !b.left) return true;
return (
Math.abs(a.left[0] - b.left[0]) <= SEAT_AXIS && Math.abs(a.left[1] - b.left[1]) <= SEAT_AXIS
);
}