From a332737654dad905747b730d2ce0789f7d0eb060 Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 13 May 2026 12:14:42 +0900 Subject: [PATCH] =?UTF-8?q?[RACK-TILT]=20removeShortEdges=20=EC=A7=81?= =?UTF-8?q?=EA=B0=81=20=EB=85=B8=EC=B9=98=20=EB=B3=80=ED=98=95=20=EC=B0=A8?= =?UTF-8?q?=EB=8B=A8=20=E2=80=94=20tiny=20edge=20=EB=A8=B8=EC=A7=80=20?= =?UTF-8?q?=EC=8B=9C=20axis-aligned=20=EA=B0=80=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useMode.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index c1b5524c..4bb91ba8 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1730,10 +1730,25 @@ export function useMode() { // edge[i] 가 tiny 이면 시작 정점 vertex[i] 를 제거해 앞쪽 edge 와 병합한다. // 이렇게 하면 남는 cleaned edge 의 line 매핑(cleanedLines[k]=lines[kept[k]]) 이 // edge[i+1] (실제 긴 edge) 의 line 을 쓰게 되므로 offset 계산이 안정해진다. + // [tiny edge axis guard 2026-05-13] 단, 제거 후 새로 생기는 엣지가 axis-aligned 인 경우에만 안전. + // 직각 노치(예: H 91mm + V 24.5mm 코너) 의 24.5mm edge 를 단순 제거하면 v[i-1]→v[i+1] 가 + // 15° 대각선이 되어 inset+clipOffsetToOriginal 후 mm 단위 zigzag 토막으로 보임 (RACK-TILT). + // 원본 데이터가 wallBaseLine 의 axis-aligned 직각 노치를 보존해야 하므로, 대각선 결과가 되면 skip. const TINY_EDGE_THRESHOLD = 30 + const AXIS_TOL = 0.5 for (let i = 0; i < n; i++) { if (edges[i].length < TINY_EDGE_THRESHOLD) { - removeIndices.add(i) + const prev = (i + n - 1) % n + const nxt = (i + 1) % n + const vPrev = vertices[prev] + const vNext = vertices[nxt] + // 새 엣지 v[prev]→v[nxt] 가 수평 또는 수직인 경우만 머지 (drift artifact 흡수). + // 그 외(직각 노치 사이의 short step) 는 진짜 geometry 이므로 보존. + const isAxisAligned = + Math.abs(vPrev.y - vNext.y) < AXIS_TOL || Math.abs(vPrev.x - vNext.x) < AXIS_TOL + if (isAxisAligned) { + removeIndices.add(i) + } } }