- 옮김: B04 2 · B05 23 · B06 11 · A00_Common/design 13 (9,299 줄) · 이미 logic/ 에 있던 16 파일 그대로 - 안 옮김: 묶음 입구(package.json build:*) · 파이썬 · 순수지만 계산 아닌 8 (보기 결선 · 콜백 · API 타입 · 갈아끼움 알림판) - import 266 줄(142 파일) · 시험 · 주석 · 짝 표시 문자열 경로 고침 · B05 · B06 CLAUDE.md 짝 줄 logic/ - 시험 도우미 새 경로: 가짜 require 열쇠 · B05()/B06() 부름 · 형제 import 자리 · tsc 묶어 돌리는 시험 · 정규식 · rglob - design_view_cross 줄 한도 시험 685 → 688 (긴 import 경로 줄바꿈 3줄) - 확인: typecheck 0 · 서버 묶음 넷(corridor · server-calc · b07-extent · b07-note) 다시 지어 코드 같음(//#region 경로 주석만 다름) · 관련 시험 270 파일 — 남은 실패 19 는 옮기기 전과 같음 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
/* =============================================================================
|
|
* B05_Profile_Footprint_Strokes.ts
|
|
* 평면 발자국(가게 키 `footprint` · 계약 `PlanFootprint`) → 그릴 선 갈래(PLAN 346-2).
|
|
*
|
|
* 도로 끝 좌 · 우 = `road` · 비탈 끝 = 점마다 깎기 여부(`slopeLeftCut` · `slopeRightCut` —
|
|
* footprint 단계가 붙임)로 `cut` · `fill` 조각 · 깎기 여부가 없으면 `slope` 한 줄.
|
|
* 조각이 바뀌는 점은 앞뒤 조각이 함께 가짐(선이 끊겨 보이지 않게 · `splitRuns` 와 같은 규칙).
|
|
* ========================================================================== */
|
|
|
|
import type { PlanFootprint, Vertex } from "../../A00_Common/design/logic/design_pipeline_types";
|
|
|
|
export type FootprintStrokeKind = "road" | "cut" | "fill" | "slope";
|
|
|
|
export interface FootprintStroke {
|
|
kind: FootprintStrokeKind;
|
|
points: Vertex[];
|
|
}
|
|
|
|
/** footprint 단계 출력 — 계약 칸 + 비탈 끝 점마다 깎기 여부(없을 수 있음). */
|
|
export type FootprintValue = PlanFootprint & {
|
|
slopeLeftCut?: ReadonlyArray<boolean>;
|
|
slopeRightCut?: ReadonlyArray<boolean>;
|
|
};
|
|
|
|
function slopeRuns(points: Vertex[], cut: ReadonlyArray<boolean> | undefined): FootprintStroke[] {
|
|
if (points.length < 2) return [];
|
|
if (!cut || cut.length !== points.length) return [{ kind: "slope", points }];
|
|
const runs: FootprintStroke[] = [];
|
|
let current: FootprintStroke | null = null;
|
|
points.forEach((point, index) => {
|
|
const kind = cut[index] ? "cut" : "fill";
|
|
if (current?.kind !== kind) {
|
|
current?.points.push(point);
|
|
current = { kind, points: [point] };
|
|
runs.push(current);
|
|
} else {
|
|
current.points.push(point);
|
|
}
|
|
});
|
|
return runs.filter((run) => run.points.length >= 2);
|
|
}
|
|
|
|
/** 그릴 선 — 도로 끝 둘 · 비탈 끝 조각들(2점 미만은 뺌). */
|
|
export function footprintStrokes(footprint: FootprintValue | null): FootprintStroke[] {
|
|
if (!footprint) return [];
|
|
const road = [footprint.roadLeft, footprint.roadRight]
|
|
.filter((points) => points?.length >= 2)
|
|
.map((points): FootprintStroke => ({ kind: "road", points }));
|
|
return [
|
|
...road,
|
|
...slopeRuns(footprint.slopeLeft ?? [], footprint.slopeLeftCut),
|
|
...slopeRuns(footprint.slopeRight ?? [], footprint.slopeRightCut),
|
|
];
|
|
}
|