From c02bda452eb25e953c419c45cd09487998d158b3 Mon Sep 17 00:00:00 2001 From: ysCha Date: Wed, 31 Dec 2025 15:38:51 +0900 Subject: [PATCH] =?UTF-8?q?=ED=95=A0=EB=8B=B9=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofcover/useRoofAllocationSetting.js | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 4bb3d8ca..3ef5aa97 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -475,17 +475,57 @@ export function useRoofAllocationSetting(id) { const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id)) const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id)) // Filter out lines from roofBase.lines that share any points with newEaveLines + // ... existing code ... + // ... existing code ... const linesToKeep = roofBase.lines.filter(roofLine => { - return !newEaveLines.some(eaveLine => { - // Check if any endpoint of roofLine matches any endpoint of eaveLine - return ( - // Check if any endpoint of roofLine matches any endpoint of eaveLine - (Math.abs(roofLine.x1 - eaveLine.x1) < 0.1 && Math.abs(roofLine.y1 - eaveLine.y1) < 0.1) || // p1 matches p1 - (Math.abs(roofLine.x2 - eaveLine.x2) < 0.1 && Math.abs(roofLine.y2 - eaveLine.y2) < 0.1) // p2 matches p2 - ); - }); - }); + const shouldRemove = newEaveLines.some(eaveLine => { + // 1. 기본적인 포인트 일치 확인 + const rX1 = roofLine.x1, rY1 = roofLine.y1, rX2 = roofLine.x2, rY2 = roofLine.y2; + const eX1 = eaveLine.x1, eY1 = eaveLine.y1, eX2 = eaveLine.x2, eY2 = eaveLine.y2; + const isP1Matched = (Math.abs(rX1 - eX1) < 0.1 && Math.abs(rY1 - eY1) < 0.1) || (Math.abs(rX1 - eX2) < 0.1 && Math.abs(rY1 - eY2) < 0.1); + const isP2Matched = (Math.abs(rX2 - eX1) < 0.1 && Math.abs(rY2 - eY1) < 0.1) || (Math.abs(rX2 - eX2) < 0.1 && Math.abs(rY2 - eY2) < 0.1); + + if (isP1Matched || isP2Matched) { + // 2. 일직선(평행)인지 확인 + const dx1 = rX2 - rX1; + const dy1 = rY2 - rY1; + const dx2 = eX2 - eX1; + const dy2 = eY2 - eY1; + const crossProduct = Math.abs(dx1 * dy2 - dy1 * dx2); + const mag1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); + const mag2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); + const isStraight = (mag1 * mag2) === 0 ? true : (crossProduct / (mag1 * mag2) < 0.01); + + if (isStraight) { + // 3. [핵심] 몸통이 포개지는지(Overlap) 확인 + // 한 선의 끝점이 다른 선의 "내부"에 들어와 있는지 체크 + const isPointInside = (x, y, x1, y1, x2, y2) => { + const dotProduct = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1); + if (dotProduct < 0.1) return false; // 시작점 바깥쪽 + const squaredLength = (x2 - x1) ** 2 + (y2 - y1) ** 2; + if (dotProduct > squaredLength - 0.1) return false; // 끝점 바깥쪽 + return true; // 선의 내부(몸통)에 있음 + }; + + // roofLine의 끝점 중 하나가 eaveLine의 몸통 안에 있거나, + // eaveLine의 끝점 중 하나가 roofLine의 몸통 안에 있으면 "포개짐"으로 판단 + const isOverlapping = + isPointInside(rX1, rY1, eX1, eY1, eX2, eY2) || + isPointInside(rX2, rY2, eX1, eY1, eX2, eY2) || + isPointInside(eX1, eY1, rX1, rY1, rX2, rY2) || + isPointInside(eX2, eY2, rX1, rY1, rX2, rY2); + + if (isOverlapping) { + console.log('Removing overlapping line:', roofLine); + return true; // 포개지는 경우에만 삭제 + } + } + } + return false; // 끝점만 닿아 있거나 직각인 경우는 살림 + }); + return !shouldRemove; + }); // Combine remaining lines with newEaveLines roofBase.lines = [...linesToKeep, ...newEaveLines]; } else {