From edb0783e26e9e515af2f9310db7f61552c53981b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 18 Jul 2025 18:24:22 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 67 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 463be9f2..f59a9b22 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -764,6 +764,7 @@ export const usePolygon = () => { const splitPolygonWithLines = (polygon) => { polygon.set({ visible: false }) + let innerLines = [...polygon.innerLines].filter((line) => line.visible) /*// innerLine이 세팅이 안되어있는경우 찾아서 세팅한다. @@ -783,6 +784,67 @@ export const usePolygon = () => { }*/ canvas.renderAll() let polygonLines = [...polygon.lines] + + // polygonLines와 innerLines의 겹침을 확인하고 type을 변경하는 함수 + const checkLineOverlap = (line1, line2) => { + // 두 선분이 같은 직선 위에 있는지 확인 + const isOnSameLine = (l1, l2) => { + // 수직선인 경우 (x1 == x2) + if (Math.abs(l1.x1 - l1.x2) < 1 && Math.abs(l2.x1 - l2.x2) < 1) { + return Math.abs(l1.x1 - l2.x1) < 1 + } + // 수평선인 경우 (y1 == y2) + if (Math.abs(l1.y1 - l1.y2) < 1 && Math.abs(l2.y1 - l2.y2) < 1) { + return Math.abs(l1.y1 - l2.y1) < 1 + } + // 대각선인 경우는 기울기가 같은지 확인 + const slope1 = (l1.y2 - l1.y1) / (l1.x2 - l1.x1) + const slope2 = (l2.y2 - l2.y1) / (l2.x2 - l2.x1) + const intercept1 = l1.y1 - slope1 * l1.x1 + const intercept2 = l2.y1 - slope2 * l2.x1 + return Math.abs(slope1 - slope2) < 0.01 && Math.abs(intercept1 - intercept2) < 1 + } + + if (!isOnSameLine(line1, line2)) { + return false + } + + // 선분들이 같은 직선 위에 있다면 겹치는 부분이 있는지 확인 + const getLineRange = (line) => { + if (Math.abs(line.x1 - line.x2) < 1) { + // 수직선: y 범위 확인 + return { + min: Math.min(line.y1, line.y2), + max: Math.max(line.y1, line.y2), + } + } else { + // 수평선 또는 대각선: x 범위 확인 + return { + min: Math.min(line.x1, line.x2), + max: Math.max(line.x1, line.x2), + } + } + } + + const range1 = getLineRange(line1) + const range2 = getLineRange(line2) + + // 겹치는 부분이 있는지 확인 + return !(range1.max < range2.min || range2.max < range1.min) + } + + // innerLines와 polygonLines의 겹침을 확인하고 type 변경 + innerLines.forEach((innerLine) => { + polygonLines.forEach((polygonLine) => { + if (checkLineOverlap(innerLine, polygonLine)) { + // innerLine의 type을 polygonLine의 type으로 변경 + if (polygonLine.attributes?.type && innerLine.attributes) { + innerLine.attributes.type = polygonLine.attributes.type + } + } + }) + }) + const roofs = [] //polygonLines를 순회하며 innerLines와 교차하는 점을 line의 속성에 배열로 저장한다. @@ -1081,8 +1143,8 @@ export const usePolygon = () => { let representLines = [] let representLine - // 지붕을 그리면서 기존 polygon의 line중 연결된 line을 찾는다. - polygonLines.forEach((line) => { + // 지붕을 그리면서 기존 polygon의 line중 연결된 line을 찾는다. + ;[...polygonLines, ...innerLines].forEach((line) => { let startFlag = false let endFlag = false const startPoint = line.startPoint @@ -1115,7 +1177,6 @@ export const usePolygon = () => { }) if (!representLine) { - representLines = representLines.filter((line) => line.stroke !== 'blue') representLines.forEach((line) => { if (!representLine) { representLine = line