fix(B07): 유역도에서 노선을 살리고 방위표·정보표 배치와 절취면을 정리한다
노선이 유역 해칭 아래에 깔려 보이지 않았다. polyline_entity에 width를 더해 노선만 굵게(3) 그리고, 그리기 순서를 해칭·정보표 다음으로 옮긴다. bbox 계산에는 그대로 포함시켜 오른쪽 칸 위치는 흔들리지 않는다. 오른쪽 칸을 방위표(맨 위) → 유역 정보표(아래로 쌓기) 순으로 바꾸고 방위표를 14mm에서 26mm로 키운다. 도면 오른쪽 위 구석에 따로 놓던 옛 배치는 걷어낸다. 등고선·세류선 절취가 경계 바깥 점을 하나씩 물고 나와 외곽이 들쭉날쭉했다. Liang-Barsky 선분 절취로 바꿔 끝점이 경계 위에 정확히 놓이게 하고, 그만큼 두었던 물림 여유(_CLIP_SLACK 14mm)를 없앤다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -137,28 +137,65 @@ def _geometry_lines(geometry: Any) -> list[list[tuple[float, float]]]:
|
||||
return []
|
||||
|
||||
|
||||
def _clip_segment(
|
||||
start: tuple[float, float],
|
||||
end: tuple[float, float],
|
||||
box: tuple[float, float, float, float],
|
||||
) -> tuple[tuple[float, float], tuple[float, float]] | None:
|
||||
"""선분에서 상자 안에 드는 부분만 돌려준다(Liang-Barsky). 겹치지 않으면 None."""
|
||||
min_x, min_y, max_x, max_y = box
|
||||
dx = end[0] - start[0]
|
||||
dy = end[1] - start[1]
|
||||
t0, t1 = 0.0, 1.0
|
||||
for numerator, denominator in (
|
||||
(start[0] - min_x, -dx),
|
||||
(max_x - start[0], dx),
|
||||
(start[1] - min_y, -dy),
|
||||
(max_y - start[1], dy),
|
||||
):
|
||||
if denominator == 0.0:
|
||||
if numerator < 0.0:
|
||||
return None # 경계와 나란한데 바깥이다
|
||||
continue
|
||||
t = numerator / denominator
|
||||
if denominator < 0.0:
|
||||
if t > t1:
|
||||
return None
|
||||
t0 = max(t0, t)
|
||||
else:
|
||||
if t < t0:
|
||||
return None
|
||||
t1 = min(t1, t)
|
||||
return (
|
||||
(start[0] + t0 * dx, start[1] + t0 * dy),
|
||||
(start[0] + t1 * dx, start[1] + t1 * dy),
|
||||
)
|
||||
|
||||
|
||||
def clip_line_to_box(
|
||||
line: list[tuple[float, float]], box: tuple[float, float, float, float]
|
||||
) -> list[list[tuple[float, float]]]:
|
||||
"""범위 안에 든 연속 구간만 조각으로 잘라 낸다(경계 한 점씩 물려 끊긴 티를 줄인다).
|
||||
"""범위 안에 든 부분만 조각으로 잘라 낸다 — 끝점은 경계 위에 정확히 놓인다.
|
||||
|
||||
도엽 등고선 한 줄은 도엽 끝까지 이어지므로, 걸치면 통째로 남기면 도면이 A1을 넘는다.
|
||||
예전 구현은 경계 바깥 점을 하나씩 물고 나와 외곽선이 들쭉날쭉했다(2026-08-31 사용자
|
||||
지적). 이제 교차점을 계산해 자르므로 절취면이 곧게 떨어진다.
|
||||
"""
|
||||
min_x, min_y, max_x, max_y = box
|
||||
runs: list[list[tuple[float, float]]] = []
|
||||
current: list[tuple[float, float]] = []
|
||||
for index, point in enumerate(line):
|
||||
x, y = point
|
||||
if min_x <= x <= max_x and min_y <= y <= max_y:
|
||||
if not current and index > 0:
|
||||
current.append(line[index - 1]) # 바깥쪽 직전 점까지 물린다
|
||||
current.append(point)
|
||||
elif current:
|
||||
current.append(point)
|
||||
runs.append(current)
|
||||
for start, end in zip(line, line[1:]):
|
||||
piece = _clip_segment(start, end, box)
|
||||
if piece is None:
|
||||
current = []
|
||||
if current:
|
||||
runs.append(current)
|
||||
continue
|
||||
head, tail = piece
|
||||
if head == tail:
|
||||
continue # 경계에 점으로만 닿았다
|
||||
if current and current[-1] == head:
|
||||
current.append(tail)
|
||||
else:
|
||||
current = [head, tail]
|
||||
runs.append(current)
|
||||
return [run for run in runs if len(run) >= 2]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user