feat(774-2): B05 예정노선 = 늘 노선 하나 — 끊긴 토막은 끝끼리만 붙고 맞닿으면 한 줄

- 한 선 페이지(기능 표 branch 숨김) 긋기 붙을 자리 = 다른 토막 끝만(가운데 노드 · 선 위 = 안 붙음 → 갈래 안 생김)
- 긋기 마침 = 맞닿은 토막 모두 이음(joinTouching · 꼬리↔머리 · 꼬리↔꼬리 · 머리↔머리) · D03 = 지금대로
- 끊긴 채 수정 끝냄 = 기존 막음 · 안내 그대로
- 시험: test_771_2 에 joinTouching 대조 더함

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-03 20:40:22 +09:00
co-authored by Claude Opus 5.5
parent 2a67a7092d
commit f6f29fdee1
3 changed files with 73 additions and 3 deletions
@@ -3,6 +3,7 @@
중간 노드에서 그은 점이 같은 선 다른 노드에 닿음 = 두 노드 사이 옛 구간을 새 점으로 갈음 · 한 줄 그대로 ·
거꾸로(앞 노드에 닿음) = 점 차례 뒤집어 넣음 · 같은 노드 = 까닭 글(꼴 그대로) · 끝점에 닿음 = 끝까지 갈음 ·
노드 기록 = 꼭짓점과 같은 길이.
774-2(요구 618) B05 = 늘 노선 하나 `logic/D03_PlanAnalysis_OneLine.ts` `joinTouching` = 맞닿은 토막 이음.
774-1(요구 616) 끝 판정 `rejoinMiss` = 다른 중간 노드만 끝 · 시작 노드 · 끝점 = 계속 긋기 까닭 글 · 시작 = 중간 노드만.
./venv/Scripts/python.exe -m pytest resources/tester/test_771_2_rejoin_span.py -q
@@ -17,12 +18,22 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[2]
TS_FILE = ROOT / "D03_PlanAnalysis" / "logic" / "D03_PlanAnalysis_Span.ts"
ONE_FILE = ROOT / "D03_PlanAnalysis" / "logic" / "D03_PlanAnalysis_OneLine.ts"
TSC = ROOT / "config" / "node_modules" / "typescript" / "bin" / "tsc"
_RUNNER = """
import { writeFileSync } from "node:fs";
import * as plan from "./D03_PlanAnalysis/logic/D03_PlanAnalysis_Plan.js";
import * as span from "./D03_PlanAnalysis/logic/D03_PlanAnalysis_Span.js";
import * as one from "./D03_PlanAnalysis/logic/D03_PlanAnalysis_OneLine.js";
const two = (a, b) => {
let m = plan.newLine(plan.emptyNetwork(), a[0]);
for (const p of a.slice(1)) m = plan.appendVertex(m, 0, p);
m = plan.newLine(m, b[0]);
for (const p of b.slice(1)) m = plan.appendVertex(m, 1, p);
return m;
};
const flat = (m) => m.lines.map((l) => l.vertices);
let n = plan.newLine(plan.emptyNetwork(), [0, 0]);
for (const p of [[100, 0], [200, 0], [300, 0], [400, 0]]) n = plan.appendVertex(n, 0, p);
const L = span.nodeRecord("length", 20, 9);
@@ -41,6 +52,11 @@ writeFileSync(
middle: [0, 1, 2, 3, 4].map((v) => span.isMiddleNode(5, v)),
tip_text: span.REJOIN_TIP,
hold_text: span.REJOIN_HOLD,
join_tail_head: flat(one.joinTouching(two([[0, 0], [1, 0]], [[1, 0], [2, 0]]))),
join_tail_tail: flat(one.joinTouching(two([[0, 0], [1, 0]], [[2, 0], [1, 0]]))),
join_head_head: flat(one.joinTouching(two([[1, 0], [0, 0]], [[1, 0], [2, 0]]))),
join_apart: flat(one.joinTouching(two([[0, 0], [1, 0]], [[5, 0], [6, 0]]))),
join_branch: flat(one.joinTouching(plan.appendVertex(plan.addBranch(n, 0, 2), 1, [200, 50]))),
}),
);
"""
@@ -53,6 +69,7 @@ def _run_ts(tmp_path: Path) -> dict:
"node",
str(TSC),
str(TS_FILE),
str(ONE_FILE),
"--outDir",
str(out),
"--rootDir",
@@ -122,3 +139,13 @@ def test_end_only_other_middle_node(tmp_path: Path) -> None:
assert r["miss"] == [None, None, hold, tip, tip, None]
assert "중간 노드" in tip and "중간 노드" in hold
assert r["middle"] == [False, True, True, True, False]
def test_one_line_join_touching(tmp_path: Path) -> None:
"""774-2 — 맞닿은 두 토막 = 한 선(어느 끝이든 · 차례 이어짐) · 떨어진 토막 · 갈래 = 그대로."""
r = _run_ts(tmp_path)
assert r["join_tail_head"] == [[[0, 0], [1, 0], [2, 0]]]
assert r["join_tail_tail"] == [[[0, 0], [1, 0], [2, 0]]]
assert r["join_head_head"] in ([[[0, 0], [1, 0], [2, 0]]], [[[2, 0], [1, 0], [0, 0]]])
assert len(r["join_apart"]) == 2
assert len(r["join_branch"]) == 2 # 갈래(D03 꼴)는 안 이음