From 5e86c98afd8971d8d0d86b51a72e469350f011b2 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 24 Jul 2025 11:30:54 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EB=A1=9C=EC=A7=81=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 | 70 ++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index b66996cb..f72b6446 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -845,6 +845,7 @@ export const usePolygon = () => { if (polygonLine.attributes?.type && innerLine.attributes) { polygonLine.need = false innerLine.attributes.type = polygonLine.attributes.type + innerLine.attributes.isStart = true } } }) @@ -1025,6 +1026,10 @@ export const usePolygon = () => { polygonLines = [...polygonLines, ...newLines] + polygonLines.forEach((polygonLine) => { + polygonLine.attributes = { ...polygonLine.attributes, isStart: true } + }) + let allLines = [...polygonLines, ...innerLines] /*allLines.forEach((line) => { @@ -1058,16 +1063,6 @@ export const usePolygon = () => { allPoints.push(endPoint) }) - // allPoints에서 중복을 제거한다. - const uniquePoints = allPoints.filter((point, index, self) => { - return ( - index === - self.findIndex((p) => { - return isSamePoint(p, point) - }) - ) - }) - // 2025-02-19 대각선은 케라바, 직선은 용마루로 세팅 innerLines.forEach((innerLine) => { const startPoint = innerLine.startPoint @@ -1393,6 +1388,20 @@ export const usePolygon = () => { // 최종 함수 function getPath(start, end, graph, epsilon = 1) { + // startPoint와 arrivalPoint가 될 수 있는 점은 line.attributes.type이 'default' 혹은 null이 아닌 line인 경우에만 가능 + const isValidPoint = (point) => { + return allLines.some((line) => { + const isOnLine = isSamePoint(line.startPoint, point, epsilon) || isSamePoint(line.endPoint, point, epsilon) + const hasValidType = line.attributes?.type && line.attributes.type !== 'default' + return isOnLine && hasValidType + }) + } + + if (!isValidPoint(start) || !isValidPoint(end)) { + console.log('시작점 또는 도착점이 유효하지 않음. 무시.') + return [] + } + if (isDirectlyConnected(start, end, graph, epsilon)) { console.log('직선 연결 있음. 무시.') return [] @@ -1404,16 +1413,32 @@ export const usePolygon = () => { return [] } + // 사용된 노드들을 graph에서 제거 + if (path.length > 0) { + path.forEach((point) => { + const pointKey = pointToKey(point, epsilon) + delete graph[pointKey] + // 다른 노드들의 연결에서도 이 노드를 제거 + Object.keys(graph).forEach((key) => { + graph[key] = graph[key].filter((neighbor) => !isSamePoint(neighbor.point, point, epsilon)) + }) + }) + } + return path } const roofs = [] + const remainingLines = [...allLines] // 사용 가능한 line들의 복사본 - allLines.forEach((line) => { - // 그래프 생성 + // isStart가 true인 line들만 시작점으로 사용 + const startLines = remainingLines.filter(line => line.attributes?.isStart === true) + + startLines.forEach((startLine) => { + // 현재 남아있는 line들로 그래프 생성 const graph = {} - const edges = allLines - .filter((line2) => line !== line2) + const edges = remainingLines + .filter((line2) => line2 !== startLine) .map((line) => { return [line.startPoint, line.endPoint] }) @@ -1430,10 +1455,19 @@ export const usePolygon = () => { graph[key2].push({ point: p1, distance }) } - const startPoint = { ...line.startPoint } // 시작점 - - let arrivalPoint = { ...line.endPoint } // 도착점 - roofs.push(getPath(startPoint, arrivalPoint, graph)) + const startPoint = { ...startLine.startPoint } // 시작점 + let arrivalPoint = { ...startLine.endPoint } // 도착점 + + const roof = getPath(startPoint, arrivalPoint, graph) + if (roof.length > 0) { + roofs.push(roof) + + // 사용된 startLine을 remainingLines에서 제거 + const startLineIndex = remainingLines.findIndex(line => line === startLine) + if (startLineIndex !== -1) { + remainingLines.splice(startLineIndex, 1) + } + } }) return removeDuplicatePolygons( From e14e43f778a18eac4a3c6f50eacf0f9bc114236d Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 24 Jul 2025 12:46:47 +0900 Subject: [PATCH 2/4] =?UTF-8?q?round=EC=B2=98=EB=A6=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/canvas-util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index 166b7acb..d012f837 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -378,7 +378,7 @@ export const calculateIntersection = (line1, line2) => { export const getInterSectionLineNotOverCoordinate = (line1, line2) => { const result = intersect([line1.x1, line1.y1], [line1.x2, line1.y2], [line2.x1, line2.y1], [line2.x2, line2.y2]) if (result) { - return { x: Math.round(result[0]), y: Math.round(result[1]) } + return { x: result[0], y: result[1] } } return null } From 4684b458832a56eecbfae055d4a66dc2e3d2c27b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 24 Jul 2025 13:14:30 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EB=B3=B4=EC=A1=B0=EC=84=A0=20innerLines?= =?UTF-8?q?=EC=97=90=20=ED=8F=AC=ED=95=A8=20=EC=95=88=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=ED=98=84=EC=83=81=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 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index f72b6446..988213f7 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -765,6 +765,14 @@ export const usePolygon = () => { const splitPolygonWithLines = (polygon) => { polygon.set({ visible: false }) + const auxiliaryLines = canvas + .getObjects() + .filter((obj) => obj.name === 'auxiliaryLine' && polygon.inPolygonImproved(obj.startPoint) && polygon.inPolygonImproved(obj.endPoint)) + + auxiliaryLines.forEach((auxiliaryLine) => { + polygon.innerLines.push(auxiliaryLine) + }) + let innerLines = [...polygon.innerLines].filter((line) => line.visible) /*// innerLine이 세팅이 안되어있는경우 찾아서 세팅한다. @@ -1263,7 +1271,6 @@ export const usePolygon = () => { }) //지붕 완료 후 보조선을 전부 제거한다. - const auxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine') auxiliaryLines.forEach((line) => { canvas.remove(line) From 59d3bd61e2d45a05fbaa406c7d5ea1b3f6a01a86 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 24 Jul 2025 13:19:09 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EC=A7=80=EB=B6=95=EB=A9=B4=20=ED=95=A0?= =?UTF-8?q?=EB=8B=B9=20=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/usePolygon.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 988213f7..21429d66 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1444,22 +1444,23 @@ export const usePolygon = () => { startLines.forEach((startLine) => { // 현재 남아있는 line들로 그래프 생성 const graph = {} - const edges = remainingLines - .filter((line2) => line2 !== startLine) - .map((line) => { - return [line.startPoint, line.endPoint] - }) - for (const [p1, p2] of edges) { + for (const line of remainingLines.filter((line2) => line2 !== startLine)) { + const p1 = line.startPoint + const p2 = line.endPoint const key1 = pointToKey(p1) const key2 = pointToKey(p2) const distance = calcDistance(p1, p2) + const isStartLine = line.attributes?.isStart === true if (!graph[key1]) graph[key1] = [] if (!graph[key2]) graph[key2] = [] - graph[key1].push({ point: p2, distance }) - graph[key2].push({ point: p1, distance }) + // isStart가 아닌 line을 우선하도록 distance 조정 + const adjustedDistance = isStartLine ? distance + 1000 : distance + + graph[key1].push({ point: p2, distance: adjustedDistance, line }) + graph[key2].push({ point: p1, distance: adjustedDistance, line }) } const startPoint = { ...startLine.startPoint } // 시작점