From 19220bc3cc80cd79532149c93dc7898003434db0 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Wed, 27 Nov 2024 13:20:47 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=95=EA=B3=B5=EC=A7=80=EB=B6=95=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useMode.js | 70 ++++++++++---------- src/util/qpolygon-utils.js | 131 ++++++++++++++++++++++++++++--------- 2 files changed, 136 insertions(+), 65 deletions(-) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 31336413..6f6f3ad7 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1508,47 +1508,47 @@ export function useMode() { const handleOuterlinesTest2 = (polygon, offset = 50) => { // TODO [ljyoung] : offset 입력 처리 후 제거 해야함. polygon.lines.forEach((line, index) => { - /*line.attributes = { + line.attributes = { type: LINE_TYPE.WALLLINE.EAVES, offset: 50, width: 50, pitch: 4, sleeve: true, - }*/ - /*if (index % 2 === 0) { - line.attributes = { - type: LINE_TYPE.WALLLINE.GABLE, - offset: 30, - width: 50, - pitch: 4, - sleeve: true, - } - } else { - line.attributes = { - type: LINE_TYPE.WALLLINE.EAVES, - offset: 50, - width: 50, - pitch: 4, - sleeve: true, - } - }*/ - if (index === polygon.lines.length - 1) { - line.attributes = { - type: LINE_TYPE.WALLLINE.GABLE, - offset: 30, - width: 50, - pitch: 4, - sleeve: true, - } - } else { - line.attributes = { - type: LINE_TYPE.WALLLINE.EAVES, - offset: 50, - width: 50, - pitch: 4, - sleeve: true, - } } + /*if (index % 2 !== 0) { + line.attributes = { + type: LINE_TYPE.WALLLINE.GABLE, + offset: 30, + width: 50, + pitch: 4, + sleeve: true, + } + } else { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + offset: 50, + width: 50, + pitch: 4, + sleeve: true, + } + }*/ + /*if (index === polygon.lines.length - 1) { + line.attributes = { + type: LINE_TYPE.WALLLINE.GABLE, + offset: 30, + width: 50, + pitch: 4, + sleeve: true, + } + } else { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, + offset: 50, + width: 50, + pitch: 4, + sleeve: true, + } + }*/ }) const roof = drawRoofPolygon(polygon) //지붕 그리기 diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 493417bd..e580fbb7 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1410,8 +1410,39 @@ export const drawGabledRoof = (roofId, canvas) => { let points = [] const intersectRidge = [] // 현재 roof가 wall보다 작을때 이전, 다음 지붕의 offset만큼 포인트를 조정한다. - if (currentRoof.attributes.planeSize >= currentWall.attributes.planeSize) { + if (currentRoof.attributes.planeSize > currentWall.attributes.planeSize) { points.push({ x: currentRoof.x1, y: currentRoof.y1 }, { x: currentRoof.x2, y: currentRoof.y2 }) + } else if (currentRoof.attributes.planeSize === currentWall.attributes.planeSize) { + const deltaX = currentRoof.x2 - currentRoof.x1 + const deltaY = currentRoof.y2 - currentRoof.y1 + let x1 = currentRoof.x1, + y1 = currentRoof.y1, + x2 = currentRoof.x2, + y2 = currentRoof.y2 + + if (deltaX !== 0) { + const minX = Math.min(currentRoof.x1, currentRoof.x2, currentWall.x1, currentWall.x2) + const maxX = Math.max(currentRoof.x1, currentRoof.x2, currentWall.x1, currentWall.x2) + if (x1 > x2) { + x1 = maxX + x2 = minX + } else { + x1 = minX + x2 = maxX + } + } + if (deltaY !== 0) { + const minY = Math.min(currentRoof.y1, currentRoof.y2, currentWall.y1, currentWall.y2) + const maxY = Math.max(currentRoof.y1, currentRoof.y2, currentWall.y1, currentWall.y2) + if (y1 > y2) { + y1 = maxY + y2 = minY + } else { + y1 = minY + y2 = maxY + } + } + points.push({ x: x1, y: y1 }, { x: x2, y: y2 }) } else { const deltaX = currentRoof.x2 - currentRoof.x1 const deltaY = currentRoof.y2 - currentRoof.y1 @@ -1429,7 +1460,7 @@ export const drawGabledRoof = (roofId, canvas) => { { vertex1: { x: ridge.x1, y: ridge.y1 }, vertex2: { x: ridge.x2, y: ridge.y2 } }, ) if (intersection && !intersection.isIntersectionOutside) { - intersectRidge.push({ line: ridge, name: 'mid' }) + intersectRidge.push({ line: ridge }) } } if (Math.sign(midX - ridgeMidX) === signX || Math.sign(midY - ridgeMidY) === signY) { @@ -1442,43 +1473,80 @@ export const drawGabledRoof = (roofId, canvas) => { { vertex1: { x: ridge.x1, y: ridge.y1 }, vertex2: { x: ridge.x2, y: ridge.y2 } }, ) if (prevIntersect && !prevIntersect.isIntersectionOutside) { - intersectRidge.push({ line: ridge, name: 'prev' }) + intersectRidge.push({ line: ridge }) } if (nextIntersect && !nextIntersect.isIntersectionOutside) { - intersectRidge.push({ line: ridge, name: 'next' }) + intersectRidge.push({ line: ridge }) } } }) - intersectRidge.forEach((intersect) => { + intersectRidge.forEach((intersect, index) => { const line = intersect.line - if (currentRoof.attributes.planeSize >= currentWall.attributes.planeSize) { + const ridge = new fabric.Line([line.x1, line.y1, line.x2, line.y2], { + stroke: 'red', + strokeWidth: 2, + selectable: false, + }) + canvas.add(ridge) + canvas.renderAll() + if (currentRoof.attributes.planeSize > currentWall.attributes.planeSize) { points.push({ x: line.x1, y: line.y1 }, { x: line.x2, y: line.y2 }) - } else { - if (intersect.name === 'mid') { - let lineX1 = line.x1, - lineY1 = line.y1, - lineX2 = line.x2, - lineY2 = line.y2 - const prevCheck1 = Math.sqrt(Math.pow(Math.round(lineX1 - currentRoof.x1), 2) + Math.pow(Math.round(lineY1 - currentRoof.y1), 2)) - const prevCheck2 = Math.sqrt(Math.pow(Math.round(lineX2 - currentRoof.x1), 2) + Math.pow(Math.round(lineY2 - currentRoof.y1), 2)) - const deltaX = currentRoof.x2 - currentRoof.x1 - const deltaY = currentRoof.y2 - currentRoof.y1 - console.log('deltaX : ', deltaX, 'deltaY : ', deltaY) - if (prevCheck1 < prevCheck2) { - lineX1 = lineX1 - Math.sign(deltaX) * prevRoof.attributes.offset - lineY1 = lineY1 - Math.sign(deltaY) * prevRoof.attributes.offset - lineX2 = lineX2 + Math.sign(deltaX) * nextRoof.attributes.offset - lineY2 = lineY2 + Math.sign(deltaY) * nextRoof.attributes.offset + } else if (currentRoof.attributes.planeSize === currentWall.attributes.planeSize) { + const deltaX = currentRoof.x2 - currentRoof.x1 + const deltaY = currentRoof.y2 - currentRoof.y1 + let x1 = line.x1, + y1 = line.y1, + x2 = line.x2, + y2 = line.y2 + if (deltaX !== 0) { + const minX = Math.min(currentWall.x1, currentWall.x2, currentRoof.x1, currentRoof.x2, line.x1, line.x2) + const maxX = Math.max(currentWall.x1, currentWall.x2, currentRoof.x1, currentRoof.x2, line.x1, line.x2) + if (x1 > x2) { + x1 = maxX + x2 = minX } else { - lineX1 = lineX1 + Math.sign(deltaX) * prevRoof.attributes.offset - lineY1 = lineY1 + Math.sign(deltaY) * prevRoof.attributes.offset - lineX2 = lineX2 - Math.sign(deltaX) * nextRoof.attributes.offset - lineY2 = lineY2 - Math.sign(deltaY) * nextRoof.attributes.offset + x1 = minX + x2 = maxX } - points.push({ x: lineX1, y: lineY1 }, { x: lineX2, y: lineY2 }) } + if (deltaY !== 0) { + const minY = Math.min(currentWall.y1, currentWall.y2, currentRoof.y1, currentRoof.y2, line.y1, line.y2) + const maxY = Math.max(currentWall.y1, currentWall.y2, currentRoof.y1, currentRoof.y2, line.y1, line.y2) + if (y1 > y2) { + y1 = maxY + y2 = minY + } else { + y1 = minY + y2 = maxY + } + } + points.push({ x: x1, y: y1 }, { x: x2, y: y2 }) + } else { + let lineX1 = line.x1, + lineY1 = line.y1, + lineX2 = line.x2, + lineY2 = line.y2 + const prevCheck1 = Math.sqrt(Math.pow(Math.round(lineX1 - currentRoof.x1), 2) + Math.pow(Math.round(lineY1 - currentRoof.y1), 2)) + const prevCheck2 = Math.sqrt(Math.pow(Math.round(lineX2 - currentRoof.x1), 2) + Math.pow(Math.round(lineY2 - currentRoof.y1), 2)) + const deltaX = currentRoof.x2 - currentRoof.x1 + const deltaY = currentRoof.y2 - currentRoof.y1 + if (prevCheck1 < prevCheck2) { + lineX1 = lineX1 - Math.sign(deltaX) * prevRoof.attributes.offset + lineY1 = lineY1 - Math.sign(deltaY) * prevRoof.attributes.offset + lineX2 = lineX2 + Math.sign(deltaX) * nextRoof.attributes.offset + lineY2 = lineY2 + Math.sign(deltaY) * nextRoof.attributes.offset + } else { + lineX1 = lineX1 + Math.sign(deltaX) * prevRoof.attributes.offset + lineY1 = lineY1 + Math.sign(deltaY) * prevRoof.attributes.offset + lineX2 = lineX2 - Math.sign(deltaX) * nextRoof.attributes.offset + lineY2 = lineY2 - Math.sign(deltaY) * nextRoof.attributes.offset + } + points.push({ x: lineX1, y: lineY1 }, { x: lineX2, y: lineY2 }) } + + canvas.remove(ridge) + canvas.renderAll() }) points = points.filter((point, index, self) => index === self.findIndex((p) => p.x === point.x && p.y === point.y)) @@ -1495,8 +1563,11 @@ export const drawGabledRoof = (roofId, canvas) => { const nextPoint = underStartPoint .filter((point) => point.x === startPoint.x) .reduce((prev, current) => { + if (prev === undefined) { + return current + } return Math.abs(prev.y - startPoint.y) < Math.abs(current.y - startPoint.y) ? prev : current - }) + }, undefined) if (nextPoint) { sortedPoints.push(nextPoint) } else { @@ -1504,7 +1575,7 @@ export const drawGabledRoof = (roofId, canvas) => { const prevHypos = Math.sqrt(Math.abs(Math.pow(prev.x - startPoint.x, 2)) + Math.abs(Math.pow(prev.y - startPoint.y, 2))) const currentHypos = Math.sqrt(Math.abs(Math.pow(current.x - startPoint.x, 2)) + Math.abs(Math.pow(current.y - startPoint.y, 2))) return prevHypos < currentHypos ? prev : current - }) + }, undefined) sortedPoints.push(nextPoint) } } else { @@ -1565,7 +1636,7 @@ export const drawGabledRoof = (roofId, canvas) => { const roofPolygon = new QPolygon(sortedPoints, { fill: 'transparent', stroke: 'blue', - strokeWidth: 1, + strokeWidth: 2, selectable: false, fontSize: roof.fontSize, name: 'roofPolygon',