fix(B05 평면 곡선 네모): 모든 곡선 BC · EC 네모를 예상노선 뒤 · 노선 앞으로 (414-2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
This commit is contained in:
2026-10-18 12:15:30 +09:00
co-authored by Claude Opus 5.5
parent e488605d72
commit 7990740569
2 changed files with 38 additions and 24 deletions
+26 -23
View File
@@ -236,6 +236,32 @@ export function drawRouteEditScene(context: CanvasRenderingContext2D, scene: Rou
style.getPropertyValue("--color-text-secondary") || "#9ca3af",
1.6,
);
// 곡선 시작·끝점 — 잡아서 직선 각도와 R 을 함께 바꾸는 손잡이(2026-09-07 사용자 지시).
// **속을 비우고 테두리를 굵게** 그린다 — 선·노드와 색이 같으면 눈에도 안 띄고 집기도 어렵다.
// 예상노선 뒤 · 노선 앞(414-2) — 노선이 네모 위를 지나감 · 고른 곡선은 `drawPickedCurve` 가 위에.
context.save();
context.lineWidth = 2;
scene.curveInfo.forEach((curve) => {
// **늘 보인다**(2026-09-07 사용자 지시) — 직선이 곡선에 닿는 자리는 손잡이이기 이전에
// **읽을 정보**다. 한때 고른 곡선만 내보였더니 「표기가 다 사라졌다」는 지적을 받았다.
// 노드를 못 집던 문제는 집기 우선순위(노드가 먼저)로 따로 풀었으므로 다 내놓아도 된다.
if (scene.curveOn[curve.node_first] === false) return; // 곡선을 지운 자리에는 접선점도 없다.
// 고른 곡선은 속을 채워 도드라지게 — 지금 끌 수 있는 것이 무엇인지 보이게.
const isPicked = curve.node_first === scene.picked;
[curve.start, curve.end].forEach((point) => {
const [x, y] = toScreen([point[0], point[1]]);
context.beginPath();
const size = isPicked ? CURVE_HANDLE_PX + 1 : CURVE_HANDLE_PX;
context.rect(x - size, y - size, size * 2, size * 2);
context.fillStyle = isPicked
? style.getPropertyValue("--map-route") || "#f97316"
: style.getPropertyValue("--map-halo") || "rgba(255,255,255,0.95)";
context.fill();
context.strokeStyle = style.getPropertyValue("--map-route") || "#f97316";
context.stroke();
});
});
context.restore();
// 선은 **폴리라인**(원호 포함)을 그리고, 잡는 동그라미는 **노드**에만 찍는다.
// 노드를 옮기는 동안에는 폴리라인이 없으므로 노드를 곧바로 이어 미리 보인다.
strokePolyline(
@@ -294,29 +320,6 @@ export function drawRouteEditScene(context: CanvasRenderingContext2D, scene: Rou
}
});
// 곡선 시작·끝점 — 잡아서 직선 각도와 R 을 함께 바꾸는 손잡이(2026-09-07 사용자 지시).
// **속을 비우고 테두리를 굵게** 그린다 — 선·노드와 색이 같으면 눈에도 안 띄고 집기도 어렵다.
context.lineWidth = 2;
scene.curveInfo.forEach((curve) => {
// **늘 보인다**(2026-09-07 사용자 지시) — 직선이 곡선에 닿는 자리는 손잡이이기 이전에
// **읽을 정보**다. 한때 고른 곡선만 내보였더니 「표기가 다 사라졌다」는 지적을 받았다.
// 노드를 못 집던 문제는 집기 우선순위(노드가 먼저)로 따로 풀었으므로 다 내놓아도 된다.
if (scene.curveOn[curve.node_first] === false) return; // 곡선을 지운 자리에는 접선점도 없다.
// 고른 곡선은 속을 채워 도드라지게 — 지금 끌 수 있는 것이 무엇인지 보이게.
const isPicked = curve.node_first === scene.picked;
[curve.start, curve.end].forEach((point) => {
const [x, y] = toScreen([point[0], point[1]]);
context.beginPath();
const size = isPicked ? CURVE_HANDLE_PX + 1 : CURVE_HANDLE_PX;
context.rect(x - size, y - size, size * 2, size * 2);
context.fillStyle = isPicked
? style.getPropertyValue("--map-route") || "#f97316"
: style.getPropertyValue("--map-halo") || "rgba(255,255,255,0.95)";
context.fill();
context.strokeStyle = style.getPropertyValue("--map-route") || "#f97316";
context.stroke();
});
});
context.restore();
drawPickedCurve(context, scene, style);
drawPickHover(context, scene, line, style, NODE_R);
@@ -23,12 +23,23 @@ def test_노드는_라벨_뒤_맨_위_회전_안():
scene = render[render.index("export function drawRouteEditScene(") :]
scene = scene[: scene.index("context.restore(); // 회전 끝")]
labels = scene.index("drawContourLabels(context, scene, band, style);")
for later in ("scene.planned.forEach(", "scene.curveInfo.forEach(", "drawPickHover("):
for later in ("scene.planned.forEach(", "drawPickedCurve(", "drawPickHover("):
assert labels < scene.index(later), later
for earlier in ("drawStationMarks(", "scene.overStations?.(", "drawMeasureMarks("):
assert scene.index(earlier) < labels, earlier
def test_곡선_네모는_예상노선_뒤_노선_앞():
"""414-2 — 모든 곡선 BC · EC 네모 = 예상노선 뒤 · 노선 앞(노선이 네모 위를 지나감)."""
render = _read("B05_Profile_UI_RouteEdit_Render.ts")
scene = render[render.index("export function drawRouteEditScene(") :]
expected = scene.index("scene.expected,")
squares = scene.index("scene.curveInfo.forEach(")
route = scene.index("strokePolyline(", squares)
assert expected < squares < route
assert scene[route:].split(",")[2].strip() == "line"
def test_집기_맴돔_한_함수():
pointer = _read("B05_Profile_UI_RouteEdit_Pointer.ts")
assert "pickAtScreen(" in pointer