feat(475-3 요구 275-3): 노선이 바뀌면 자리 칸(암 경계 · 2단 경사 · 손 상단측)은 같은 자리 측점만 넘김 — 새 자리 = 기본값
- 자리 칸 목록 한 벌 = TS `SEAT_KEYS`(Station_Swap · 파이썬 Router_Design 이 그 글을 읽음) — two_stage_slope · rock_boundary_offset_m · cut_slope_ratio_user · section_mode · ditch_side - 자리 판정 한 벌 = `sameSeat` ↔ 파이썬 `same_seat`(중심 0.01 m · 왼쪽 축 1e-3 · 모르면 같은 자리 = 옛 동작) - 끌기 세션 넘김 · Node stations.carry = `carryKeyedStates`(목록 측점 자리 · 값마다 쓴 때 자리 `@seat` — 되돌리기로 되살린 값도 제 자리로) - 미리보기 = `pipelineCrossSource` 가 저장분 · 세션 자리 칸에 자리째 실음 → `crossAtSeat` 가 새 자리면 뺌 - B06 갈아끼움(노선 초안) = 자리 바뀐 측점 설계의 자리 칸 걷고 기본값(`unseated` · 브레인 덧) - 서버 노선 저장 = `carry_cross_inputs` 자리 칸 같은 자리만 · 손 단면 유형 · 측구 방향 = `compute_default_designs` 입력 - 옛 단언 시험 고침(자리 모름 목록 = 같은 자리 = 손 상단측도 넘김 · 「@seat」 칸 거름) · 새 시험 test_475_3_seat_carry - 위키 rules 넘김 규칙 줄 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user