From 919a97f96768ea0ef0e049f3a701d1912f5764ff Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Wed, 13 Nov 2024 09:38:13 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=A7=80=EB=B6=95=20=EB=A7=88=EB=A3=A8=20?= =?UTF-8?q?=EC=9E=AC=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 6 +- src/hooks/useMode.js | 2 +- src/util/qpolygon-utils.js | 181 +++++++++++++++++++++++++++++-------- 3 files changed, 145 insertions(+), 44 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 021357c4..4e4ed3a0 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -445,11 +445,11 @@ export default function Roof2(props) { { x: 113, y: 371.9 }, { x: 762, y: 371.9 }, { x: 762, y: 818.7 }, - { x: 1468.6, y: 818.7 }, - { x: 1468.6, y: 114.9 }, + { x: 1478.6, y: 818.7 }, + { x: 1478.6, y: 114.9 }, ] - const polygon = new QPolygon(type2, { + const polygon = new QPolygon(eightPoint, { fill: 'transparent', stroke: 'green', strokeWidth: 1, diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index ce7b8210..2ab7de9f 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1510,7 +1510,7 @@ export function useMode() { polygon.lines.forEach((line, index) => { line.attributes = { type: LINE_TYPE.WALLLINE.EAVES, - offset: 40, + offset: 50, width: 50, pitch: 4, sleeve: true, diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index ed375ec5..dca6fda3 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1249,8 +1249,6 @@ export const drawShedRoof = (roofId, canvas) => { const eaves = roof.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) const gables = roof.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.GABLE) - console.log('gable', gables) - let shedDegree = sheds[0].attributes.degree || 0 const shedChon = sheds[0].attributes.pitch || 0 @@ -1276,9 +1274,9 @@ export const drawRidgeRoof = (roofId, canvas) => { return } drawRidge(roof, canvas) - drawHips(roof, canvas) - connectLinePoint(roof, canvas) - modifyRidge(roof, canvas) + // drawHips(roof, canvas) + /*connectLinePoint(roof, canvas) + modifyRidge(roof, canvas)*/ } /** @@ -1311,33 +1309,135 @@ const drawRidge = (roof, canvas) => { // 지붕의 길이가 짧은 순으로 정렬 ridgeRoof.sort((a, b) => a.length - b.length) - console.log('ridgeRoof', ridgeRoof) - ridgeRoof.forEach((item) => { if (getMaxRidge(roofLines.length) > roof.ridges.length) { - let index = item.index, - beforePrevRoof, - prevRoof, - currentRoof = item.roof, - nextRoof, - afterNextRoof + const index = item.index, + currentRoof = item.roof + const prevRoof = index === 0 ? roofLines[wallLines.length - 1] : roofLines[index - 1] + const nextRoof = index === roofLines.length - 1 ? roofLines[0] : index === roofLines.length ? roofLines[1] : roofLines[index + 1] + const beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2] + const afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2] let startXPoint, startYPoint, endXPoint, endYPoint - prevRoof = index === 0 ? roofLines[wallLines.length - 1] : roofLines[index - 1] - nextRoof = index === roofLines.length - 1 ? roofLines[0] : index === roofLines.length ? roofLines[1] : roofLines[index + 1] - - beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2] - afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2] + let wallLine = wallLines.filter((w) => w.id === currentRoof.attributes.wallLine) + if (wallLine.length > 0) { + wallLine = wallLine[0] + } const anotherRoof = roofLines.filter((roof) => roof !== currentRoof && roof !== prevRoof && roof !== nextRoof) - let xEqualInnerLines = anotherRoof.filter((roof) => roof.x1 === roof.x2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)), //x가 같은 내부선 + /*let xEqualInnerLines = anotherRoof.filter((roof) => roof.x1 === roof.x2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)), //x가 같은 내부선 yEqualInnerLines = anotherRoof.filter((roof) => roof.y1 === roof.y2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)) //y가 같은 내부선 - let ridgeBaseLength = Math.round(currentRoof.attributes.planeSize / 2), // 지붕의 기반 길이 - ridgeMaxLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize), // 지붕의 최대 길이. 이전, 다음 벽 중 짧은 길이 - ridgeAcrossLength = Math.abs(Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) - currentRoof.attributes.planeSize) // 맞은편 벽까지의 길이 - 지붕의 기반 길이 + console.log('xEqualInnerLines', xEqualInnerLines, 'yEqualInnerLines', yEqualInnerLines) +*/ + let currentX1 = currentRoof.x1, + currentY1 = currentRoof.y1, + currentX2 = currentRoof.x2, + currentY2 = currentRoof.y2 + anotherRoof + .filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof)) + .forEach((roof) => { + const angle = calculateAngle(currentRoof.startPoint, currentRoof.endPoint) - calculateAngle(roof.startPoint, roof.endPoint) + console.log('확인 : ', angle) + if (angle === 90) { + } + }) + console.log('current angle : ', calculateAngle(currentRoof.startPoint, currentRoof.endPoint)) + const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심 + const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심 + /* + const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심 + const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심 + */ + const alpha = (currentRoof.x1 + currentRoof.x2) / 2 - (wallLine.x1 + wallLine.x2) / 2 // 벽과 지붕의 X 거리 + const beta = (currentRoof.y1 + currentRoof.y2) / 2 - (wallLine.y1 + wallLine.y2) / 2 // 벽과 지붕의 Y 거리 + const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 + + let ridgeBaseLength = Math.round(currentRoof.attributes.planeSize / 2) / 10, // 지붕의 기반 길이 + ridgeMaxLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10, // 지붕의 최대 길이. 이전, 다음 벽 중 짧은 길이 + ridgeAcrossLength = Math.abs(Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) - currentRoof.attributes.planeSize) / 10 // 맞은편 벽까지의 길이 - 지붕의 기반 길이 + + startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) + startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) + + console.log('ridgeMaxLength', ridgeMaxLength, Math.sign(alpha), Math.sign(alpha) * -1 * ridgeMaxLength) + const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength)) + + const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength)) + + console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', checkEndXPoint, 'endYPoint', checkEndYPoint) + + const checkLine = new QLine([startXPoint, startYPoint, checkEndXPoint, checkEndYPoint], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: LINE_TYPE.SUBLINE.HIP, + attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, + }) + const intersectLines = [] + roofLines.forEach((line) => { + const intersection = edgesIntersection( + { vertex1: { x: checkLine.x1, y: checkLine.y1 }, vertex2: { x: checkLine.x2, y: checkLine.y2 } }, + { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }, + ) + if (intersection && !intersection.isIntersectionOutside) { + intersectLines.push({ x: intersection.x, y: intersection.y, line: line }) + } + }) + if (intersectLines.length > 0) { + intersectLines.reduce((prev, current) => { + if (prev !== undefined) { + const prevDistance = Math.sqrt(Math.pow(prev.x - startXPoint, 2) + Math.pow(prev.y - startYPoint, 2)) + const currentDistance = Math.sqrt(Math.pow(current.x - startXPoint, 2) + Math.pow(current.y - startYPoint, 2)) + return prevDistance > currentDistance ? current : prev + } else { + return current + } + }, undefined) + } + + if (intersectLines.length > 0) { + const intersectLine = intersectLines[0] + const diffX = intersectLine.x - startXPoint + const diffY = intersectLine.y - startYPoint + + endXPoint = Math.sign(diffX) * Math.round(Math.abs(diffX) - ridgeBaseLength) + startXPoint + endYPoint = Math.sign(diffY) * Math.round(Math.abs(diffY) - ridgeBaseLength) + startYPoint + } else { + endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMaxLength) + endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMaxLength) + } + console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', endXPoint, 'endYPoint', endYPoint) + + const ridge = new QLine([startXPoint, startYPoint, endXPoint, endYPoint], { + fontSize: roof.fontSize, + stroke: 'blue', + strokeWidth: 1, + name: LINE_TYPE.SUBLINE.RIDGE, + attributes: { roofId: roof.id }, + }) + + ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) + ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) + + if (ridge.attributes.planeSize > 0) { + canvas.add(ridge) + roof.ridges.push(ridge) + roof.innerLines.push(ridge) + + const distance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) + const dist1 = distance(startXPoint, startYPoint, currentRoof.x1, currentRoof.y1) + const dist2 = distance(endXPoint, endYPoint, currentRoof.x1, currentRoof.y1) + + currentRoof.attributes.ridgeCoordinate = { + x1: dist1 < dist2 ? startXPoint : endXPoint, + y1: dist1 < dist2 ? startYPoint : endYPoint, + } + } + + /* console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength) let acrossRoof = anotherRoof .filter((roof) => { @@ -1582,12 +1682,12 @@ const drawRidge = (roof, canvas) => { x1: dist1 < dist2 ? startXPoint : endXPoint, y1: dist1 < dist2 ? startYPoint : endYPoint, } - } + }*/ } }) //겹쳐지는 마루는 하나로 합침 - roof.ridges.forEach((ridge, index) => { + /*roof.ridges.forEach((ridge, index) => { roof.ridges .filter((ridge2) => !(ridge.x1 === ridge2.x1 && ridge.y1 === ridge2.y1 && ridge.x2 === ridge2.x2 && ridge.y2 === ridge2.y2)) .forEach((ridge2) => { @@ -1617,7 +1717,7 @@ const drawRidge = (roof, canvas) => { roof.innerLines.push(newRidge) } }) - }) + })*/ canvas?.renderAll() } @@ -2186,10 +2286,10 @@ const changeEavesRoof = (currentRoof, canvas) => { const alpha = midX - midWallX // 벽과 지붕의 X 거리 const beta = midY - midWallY // 벽과 지붕의 Y 거리 const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 - const addHipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비 - const addHipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비 - let hipX2 = 0 - let hipY2 = 0 + // const addHipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비 + // const addHipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비 + const hipX2 = Math.round(midX + -1 * (alpha / hypotenuse) * (currentRoof.length / 2)) + const hipY2 = Math.round(midY + -1 * (beta / hypotenuse) * (currentRoof.length / 2)) const innerLines = canvas ?.getObjects() @@ -2265,28 +2365,27 @@ const changeEavesRoof = (currentRoof, canvas) => { if (ridgeLines.length > 0) { const ridge = ridgeLines[0] + console.log(currentRoof.attributes.ridgeCoordinate) + console.log('ridge.x1 : ', ridge.x1, 'ridge.y1 : ', ridge.y1, 'ridge.x2 : ', ridge.x2, 'ridge.y2 : ', ridge.y2) if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) { ridge.set({ - x1: midX + addHipX2, - y1: midY + addHipY2, + x1: hipX2, + y1: hipY2, x2: ridge.x2, y2: ridge.y2, }) currentRoof.attributes.ridgeCoordinate = { x1: ridge.x1, y1: ridge.y1 } - hipX2 = midX + addHipX2 - hipY2 = midY + addHipY2 } if (ridge.x2 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y2 === currentRoof.attributes.ridgeCoordinate.y1) { ridge.set({ x1: ridge.x1, y1: ridge.y1, - x2: midX - addHipX2, - y2: midY - addHipY2, + x2: hipX2, + y2: hipY2, }) currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 } - hipX2 = midX - addHipX2 - hipY2 = midY - addHipY2 } + console.log('ridge.x1 : ', ridge.x1, 'ridge.y1 : ', ridge.y1, 'ridge.x2 : ', ridge.x2, 'ridge.y2 : ', ridge.y2) ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) } @@ -2296,6 +2395,8 @@ const changeEavesRoof = (currentRoof, canvas) => { canvas.remove(hip) }) + canvas?.renderAll() + const prevDegree = prevRoof.attributes.pitch > 0 ? getDegreeByChon(prevRoof.attributes.pitch) : prevRoof.attributes.degree const currentDegree = currentRoof.attributes.pitch > 0 ? getDegreeByChon(currentRoof.attributes.pitch) : currentRoof.attributes.degree const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree @@ -2912,7 +3013,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10 gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2))) canvas?.add(gable1) - roof.innerLines.push(gable1) + // roof.innerLines.push(gable1) hipX1 = (Math.sign(currentRoof.x2 - midX) * currentRoof.attributes.width) / 2 hipY1 = (Math.sign(currentRoof.y2 - midY) * currentRoof.attributes.width) / 2 @@ -2933,7 +3034,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10 gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2))) canvas?.add(gable2) - roof.innerLines.push(gable2) + // roof.innerLines.push(gable2) const gable3 = new QLine([gable1.x1, gable1.y1, gable2.x1, gable2.y1], { fontSize: roof.fontSize, @@ -2949,7 +3050,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { gable3.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10 gable3.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10 canvas?.add(gable3) - roof.innerLines.push(gable3) + // roof.innerLines.push(gable3) const hip1 = new QLine([currentRoof.x1, currentRoof.y1, gable1.x1, gable1.y1], { fontSize: roof.fontSize, From 73105e8199e2a213811a52a73e99c6aa3e4536a2 Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Thu, 14 Nov 2024 16:49:07 +0900 Subject: [PATCH 2/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=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/components/fabric/QPolygon.js | 4 ++- src/hooks/usePolygon.js | 54 ++++++++++++++++++++++++++++++- src/util/qpolygon-utils.js | 8 +++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index a365a882..c5a08cf1 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -272,9 +272,11 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { this.texts = [] points.forEach((start, i) => { const end = points[(i + 1) % points.length] + // planeSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10, + // actualSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10, const dx = end.x - start.x const dy = end.y - start.y - const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 + const length = Math.round(Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))) * 10 let midPoint diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index b83d8b1a..56052379 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -675,6 +675,57 @@ export const usePolygon = () => { const roofs = [] //polygonLines를 순회하며 innerLines와 교차하는 점을 line의 속성에 배열로 저장한다. + polygonLines.forEach((line) => { + let startPoint // 시작점 + let endPoint // 끝점 + if (line.x1 < line.x2) { + startPoint = { x: line.x1, y: line.y1 } + endPoint = { x: line.x2, y: line.y2 } + } else if (line.x1 > line.x2) { + startPoint = { x: line.x2, y: line.y2 } + endPoint = { x: line.x1, y: line.y1 } + } else { + if (line.y1 < line.y2) { + startPoint = { x: line.x1, y: line.y1 } + endPoint = { x: line.x2, y: line.y2 } + } else { + startPoint = { x: line.x2, y: line.y2 } + endPoint = { x: line.x1, y: line.y1 } + } + } + + line.startPoint = startPoint + line.endPoint = endPoint + }) + innerLines.forEach((line) => { + let startPoint // 시작점 + let endPoint // 끝점 + if (line.x1 < line.x2) { + startPoint = { x: line.x1, y: line.y1 } + endPoint = { x: line.x2, y: line.y2 } + } else if (line.x1 > line.x2) { + startPoint = { x: line.x2, y: line.y2 } + endPoint = { x: line.x1, y: line.y1 } + } else { + if (line.y1 < line.y2) { + startPoint = { x: line.x1, y: line.y1 } + endPoint = { x: line.x2, y: line.y2 } + } else { + startPoint = { x: line.x2, y: line.y2 } + endPoint = { x: line.x1, y: line.y1 } + } + } + + line.startPoint = startPoint + line.endPoint = endPoint + }) + + polygonLines.forEach((line) => { + line.set({ strokeWidth: 10 }) + canvas.add(line) + }) + canvas.renderAll() + polygonLines.forEach((line) => { const intersections = [] innerLines.forEach((innerLine) => { @@ -685,7 +736,7 @@ export const usePolygon = () => { intersections.push(innerLine.startPoint) } if (isPointOnLine(line, innerLine.endPoint)) { - if (isSamePoint(line.startPoint, innerLine.endPoint) || isSamePoint(line.startPoint, innerLine.endPoint)) { + if (isSamePoint(line.startPoint, innerLine.endPoint) || isSamePoint(line.endPoint, innerLine.endPoint)) { return } intersections.push(innerLine.endPoint) @@ -696,6 +747,7 @@ export const usePolygon = () => { const divideLines = polygonLines.filter((line) => line.intersections.length > 0) let newLines = [] + divideLines.forEach((line) => { const { intersections, startPoint, endPoint } = line diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index a229d1a7..0fff3c09 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -2484,7 +2484,7 @@ const changeGableRoof = (currentRoof, canvas) => { const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180)) hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) - roof.innerLines.push(hip1) + // roof.innerLines.push(hip1) let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX, midY], { fontSize: roof.fontSize, @@ -2503,7 +2503,11 @@ const changeGableRoof = (currentRoof, canvas) => { const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180)) hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) - roof.innerLines.push(hip2) + // roof.innerLines.push(hip2) + hip1.set({ visible: false }) + hip1.setViewLengthText(false) + hip2.set({ visible: false }) + hip2.setViewLengthText(false) canvas?.renderAll() } } From 39807cff44ca021c581a9bcdc60e9003b7fa1b24 Mon Sep 17 00:00:00 2001 From: basssy Date: Thu, 14 Nov 2024 17:02:56 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=EB=AC=BC=EA=B1=B4=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/management/StuffDetail.jsx | 2 +- src/components/management/StuffSearchCondition.jsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx index 6378aeec..ccb943c3 100644 --- a/src/components/management/StuffDetail.jsx +++ b/src/components/management/StuffDetail.jsx @@ -569,7 +569,7 @@ export default function StuffDetail() { form.setValue('remarks', managementState.remarks) }) } - }, [managementState, session]) + }, [managementState]) //경칭선택 변경 이벤트 const onChangeHonorificCode = (key) => { diff --git a/src/components/management/StuffSearchCondition.jsx b/src/components/management/StuffSearchCondition.jsx index 6a16695a..4a625539 100644 --- a/src/components/management/StuffSearchCondition.jsx +++ b/src/components/management/StuffSearchCondition.jsx @@ -155,7 +155,6 @@ export default function StuffSearchCondition() { handleClear1() //판매대리점선택 자동완성 클리어 resetStuffRecoil() setStuffSearch({ - ...stuffSearch, schSelSaleStoreId: '', schOtherSelSaleStoreId: '', }) From 1e9dca5b63bf4ab856234cb938471403215c5ebd Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Thu, 14 Nov 2024 17:29:21 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=A7=88=EB=A3=A8=20=EC=A7=80=EB=B6=95=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=EC=9E=AC=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 13 +- src/util/qpolygon-utils.js | 486 +++++++++++++------------------------ 2 files changed, 174 insertions(+), 325 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 4e4ed3a0..721e3543 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -449,7 +449,18 @@ export default function Roof2(props) { { x: 1478.6, y: 114.9 }, ] - const polygon = new QPolygon(eightPoint, { + const test3 = [ + { x: 100, y: 100 }, + { x: 100, y: 600 }, + { x: 600, y: 600 }, + { x: 600, y: 100 }, + { x: 500, y: 100 }, + { x: 500, y: 200 }, + { x: 200, y: 200 }, + { x: 200, y: 100 }, + ] + + const polygon = new QPolygon(eightPoint4, { fill: 'transparent', stroke: 'green', strokeWidth: 1, diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index dca6fda3..40eaec1b 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1274,9 +1274,9 @@ export const drawRidgeRoof = (roofId, canvas) => { return } drawRidge(roof, canvas) - // drawHips(roof, canvas) - /*connectLinePoint(roof, canvas) - modifyRidge(roof, canvas)*/ + drawHips(roof, canvas) + connectLinePoint(roof, canvas) + modifyRidge(roof, canvas) } /** @@ -1315,10 +1315,12 @@ const drawRidge = (roof, canvas) => { currentRoof = item.roof const prevRoof = index === 0 ? roofLines[wallLines.length - 1] : roofLines[index - 1] const nextRoof = index === roofLines.length - 1 ? roofLines[0] : index === roofLines.length ? roofLines[1] : roofLines[index + 1] - const beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2] - const afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2] + // const beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2] + // const afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2] let startXPoint, startYPoint, endXPoint, endYPoint + // console.log('currentRoof : ', currentRoof.direction, currentRoof.attributes.planeSize) + let wallLine = wallLines.filter((w) => w.id === currentRoof.attributes.wallLine) if (wallLine.length > 0) { wallLine = wallLine[0] @@ -1326,49 +1328,107 @@ const drawRidge = (roof, canvas) => { const anotherRoof = roofLines.filter((roof) => roof !== currentRoof && roof !== prevRoof && roof !== nextRoof) - /*let xEqualInnerLines = anotherRoof.filter((roof) => roof.x1 === roof.x2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)), //x가 같은 내부선 - yEqualInnerLines = anotherRoof.filter((roof) => roof.y1 === roof.y2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)) //y가 같은 내부선 - - console.log('xEqualInnerLines', xEqualInnerLines, 'yEqualInnerLines', yEqualInnerLines) -*/ let currentX1 = currentRoof.x1, currentY1 = currentRoof.y1, currentX2 = currentRoof.x2, currentY2 = currentRoof.y2 + let ridgeMaxLength = Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10 + let ridgeMinLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10 + + const currentAngle = Math.atan2(currentY2 - currentY1, currentX2 - currentX1) * (180 / Math.PI) anotherRoof .filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof)) - .forEach((roof) => { - const angle = calculateAngle(currentRoof.startPoint, currentRoof.endPoint) - calculateAngle(roof.startPoint, roof.endPoint) - console.log('확인 : ', angle) - if (angle === 90) { + .forEach((innerRoof) => { + const vector1 = { x: currentRoof.x2 - currentRoof.x1, y: currentRoof.y2 - currentRoof.y1 } + const vector2 = { x: innerRoof.x2 - innerRoof.x1, y: innerRoof.y2 - innerRoof.y1 } + + const dotProduct = vector1.x * vector2.x + vector1.y * vector2.y + const magnitude1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y) + const magnitude2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y) + const angle = (Math.acos(dotProduct / (magnitude1 * magnitude2)) * 180) / Math.PI + + // console.log('innerRoof', innerRoof) + // console.log('현재라인', currentRoof, '현재라인의 각도 : ', currentAngle, 'inner 라인과의 각도:', angle) + + //현재 지붕선과 직각인 선 + if (Math.abs(angle) === 90) { + const innerBefore = roofLines.find((line) => innerRoof.x1 === line.x2 && innerRoof.y1 === line.y2) + const ibAngle = Math.atan2(innerBefore.y2 - innerBefore.y1, innerBefore.x2 - innerBefore.x1) * (180 / Math.PI) + // console.log('현재라인과 직각인 선의 이전라인', innerBefore, '각도', ibAngle) + if (Math.abs(currentAngle - ibAngle) === 180) { + // console.log('currentRoof 의 x2,y2 좌표에서 연결된 라인') + if (currentAngle === 0 || currentAngle === 180) { + currentX2 = innerRoof.x1 + ridgeMinLength = + Math.round( + Math.sqrt( + Math.pow(Math.round(Math.abs(nextRoof.x1 - nextRoof.x2) * 10), 2) + + Math.pow(Math.round(Math.abs(nextRoof.y1 - innerRoof.y2) * 10), 2), + ), + ) / 10 + } + if (currentAngle === 90 || currentAngle === 270) { + currentY2 = innerRoof.y1 + ridgeMinLength = + Math.round( + Math.sqrt( + Math.pow(Math.round(Math.abs(nextRoof.x1 - innerRoof.x2) * 10), 2) + + Math.pow(Math.round(Math.abs(nextRoof.y1 - nextRoof.y2) * 10), 2), + ), + ) / 10 + } + } + if (Math.abs(currentAngle - ibAngle) === 0) { + // console.log('currentRoof 의 x1,y1 좌표에서 연결된 라인', currentAngle) + if (currentAngle === 0 || currentAngle === 180) { + currentX1 = innerRoof.x2 + ridgeMinLength = + Math.round( + Math.sqrt( + Math.pow(Math.round(Math.abs(prevRoof.x1 - prevRoof.x2) * 10), 2) + + Math.pow(Math.round(Math.abs(prevRoof.y1 - innerRoof.y1) * 10), 2), + ), + ) / 10 + } + if (currentAngle === 90 || currentAngle === 270) { + currentY1 = innerRoof.y2 + ridgeMinLength = + Math.round( + Math.sqrt( + Math.pow(Math.round(Math.abs(prevRoof.x1 - innerRoof.x1) * 10), 2) + + Math.pow(Math.round(Math.abs(prevRoof.y1 - prevRoof.y2) * 10), 2), + ), + ) / 10 + } + } + } + //현재 지붕선과 반대인 선 + if (Math.abs(angle) === 180) { + // console.log('현재라인과 반대인 선') + if (currentAngle === 0 || currentAngle === 180) { + } + if (currentAngle === 90 || currentAngle === 270) { + } } }) - console.log('current angle : ', calculateAngle(currentRoof.startPoint, currentRoof.endPoint)) - const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심 - const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심 - /* - const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심 - const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심 - */ + const midX = (currentX1 + currentX2) / 2 // 지붕의 X 중심 + const midY = (currentY1 + currentY2) / 2 // 지붕의 Y 중심 const alpha = (currentRoof.x1 + currentRoof.x2) / 2 - (wallLine.x1 + wallLine.x2) / 2 // 벽과 지붕의 X 거리 const beta = (currentRoof.y1 + currentRoof.y2) / 2 - (wallLine.y1 + wallLine.y2) / 2 // 벽과 지붕의 Y 거리 const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 - let ridgeBaseLength = Math.round(currentRoof.attributes.planeSize / 2) / 10, // 지붕의 기반 길이 - ridgeMaxLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10, // 지붕의 최대 길이. 이전, 다음 벽 중 짧은 길이 - ridgeAcrossLength = Math.abs(Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) - currentRoof.attributes.planeSize) / 10 // 맞은편 벽까지의 길이 - 지붕의 기반 길이 + const currentPlaneSize = Math.sqrt( + Math.pow(Math.round(Math.abs(currentX1 - currentX2) * 10), 2) + Math.pow(Math.round(Math.abs(currentY1 - currentY2) * 10), 2), + ) + let ridgeBaseLength = Math.round(currentPlaneSize / 2) / 10 // 지붕의 기반 길이 - startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) - startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) + startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentPlaneSize / 2)) / 10) + startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentPlaneSize / 2)) / 10) - console.log('ridgeMaxLength', ridgeMaxLength, Math.sign(alpha), Math.sign(alpha) * -1 * ridgeMaxLength) const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength)) - const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength)) - console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', checkEndXPoint, 'endYPoint', checkEndYPoint) - const checkLine = new QLine([startXPoint, startYPoint, checkEndXPoint, checkEndYPoint], { fontSize: roof.fontSize, stroke: 'red', @@ -1400,14 +1460,28 @@ const drawRidge = (roof, canvas) => { if (intersectLines.length > 0) { const intersectLine = intersectLines[0] - const diffX = intersectLine.x - startXPoint - const diffY = intersectLine.y - startYPoint - + const diffX = Math.round(intersectLine.x - startXPoint) + const diffY = Math.round(intersectLine.y - startYPoint) endXPoint = Math.sign(diffX) * Math.round(Math.abs(diffX) - ridgeBaseLength) + startXPoint endYPoint = Math.sign(diffY) * Math.round(Math.abs(diffY) - ridgeBaseLength) + startYPoint + + const hypo = Math.sqrt(Math.pow(Math.abs(startXPoint - endXPoint), 2) + Math.pow(Math.abs(startYPoint - endYPoint), 2)) + + const intersectLength = Math.sqrt(Math.pow(Math.abs(midX - intersectLine.x), 2) + Math.pow(Math.abs(midY - intersectLine.y), 2)) + console.log('intersect 좌표까지의 거리 : ', intersectLength) + console.log('hypotenuse', hypo, 'ridgeMinLength', ridgeMinLength) + if (intersectLength < prevRoof.attributes.planeSize / 10 && intersectLength < nextRoof.attributes.planeSize / 10) { + endXPoint = startXPoint + endYPoint = startYPoint + } else { + if (ridgeMinLength < hypo) { + endXPoint = Math.round(startXPoint + Math.sign(diffX) * ridgeMinLength) + endYPoint = Math.round(startYPoint + Math.sign(diffY) * ridgeMinLength) + } + } } else { - endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMaxLength) - endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMaxLength) + endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMinLength) + endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMinLength) } console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', endXPoint, 'endYPoint', endYPoint) @@ -1436,258 +1510,11 @@ const drawRidge = (roof, canvas) => { y1: dist1 < dist2 ? startYPoint : endYPoint, } } - - /* - console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength) - let acrossRoof = anotherRoof - .filter((roof) => { - const angle1 = calculateAngle(currentRoof.startPoint, currentRoof.endPoint) - const angle2 = calculateAngle(roof.startPoint, roof.endPoint) - if (Math.abs(angle1 - angle2) === 180) { - return roof - } - }) - .reduce((prev, current) => { - let hasBetweenRoof = false - if (current.x1 === current.x2) { - hasBetweenRoof = roofLines - .filter((roof) => roof !== current) - .some((line) => { - let currentY2 = currentRoof.y2 - if (yEqualInnerLines.length > 0) { - yEqualInnerLines.forEach((line) => { - currentY2 = Math.abs(currentRoof.y1 - currentY2) < Math.abs(currentRoof.y1 - line.y1) ? currentY2 : line.y1 - }) - } - const isY1Between = (line.y1 > currentRoof.y1 && line.y1 < currentY2) || (line.y1 > currentY2 && line.y1 < currentRoof.y1) - const isY2Between = (line.y2 > currentRoof.y1 && line.y2 < currentY2) || (line.y2 > currentY2 && line.y2 < currentRoof.y1) - const isX1Between = (line.x1 > currentRoof.x1 && line.x1 < current.x1) || (line.x1 > currentRoof.x1 && line.x1 < current.x1) - const isX2Between = (line.x2 > currentRoof.x1 && line.x2 < current.x1) || (line.x2 > currentRoof.x1 && line.x2 < current.x1) - - return isY1Between && isY2Between && isX1Between && isX2Between - }) - } - if (current.y1 === current.y2) { - hasBetweenRoof = roofLines - .filter((roof) => roof !== current) - .some((line) => { - let currentX2 = currentRoof.x2 - if (xEqualInnerLines.length > 0) { - xEqualInnerLines.forEach((line) => { - currentX2 = Math.abs(currentRoof.x1 - currentX2) < Math.abs(currentRoof.x1 - line.x1) ? currentX2 : line.x1 - }) - } - const isX1Between = (line.x1 > currentRoof.x1 && line.x1 < currentX2) || (line.x1 > currentX2 && line.x1 < currentRoof.x1) - const isX2Between = (line.x2 > currentRoof.x1 && line.x2 < currentX2) || (line.x2 > currentX2 && line.x2 < currentRoof.x1) - const isY1Between = (line.y1 > currentRoof.y1 && line.y1 < current.y1) || (line.y1 > currentRoof.y1 && line.y1 < current.y1) - const isY2Between = (line.y2 > currentRoof.y1 && line.y2 < current.y1) || (line.y2 > currentRoof.y1 && line.y2 < current.y1) - - return isX1Between && isX2Between && isY1Between && isY2Between - }) - } - - if (prev !== undefined) { - if (currentRoof.x1 === currentRoof.x2) { - return Math.abs(currentRoof.y1 - prev.y1) > Math.abs(currentRoof.y1 - current.y1) ? prev : current - } - if (currentRoof.y1 === currentRoof.y2) { - return Math.abs(currentRoof.x1 - prev.x1) > Math.abs(currentRoof.x1 - current.x1) ? prev : current - } - } else { - if (!hasBetweenRoof) { - if (currentRoof.x1 === currentRoof.x2) { - return Math.sign(currentRoof.y1 - currentRoof.y2) !== Math.sign(current.y1 - current.y2) ? current : undefined - } - if (currentRoof.y1 === currentRoof.y2) { - return Math.sign(currentRoof.x1 - currentRoof.x2) !== Math.sign(current.x1 - current.x2) ? current : undefined - } - return undefined - } else { - return undefined - } - } - }, undefined) - if (acrossRoof !== undefined) { - if (currentRoof.x1 === currentRoof.x2) { - if (ridgeAcrossLength < Math.abs(currentRoof.x1 - acrossRoof.x1)) { - ridgeAcrossLength = Math.round(Math.round(Math.abs(currentRoof.x1 - acrossRoof.x1) * 10) - currentRoof.attributes.planeSize) - } - } - if (currentRoof.y1 === currentRoof.y2) { - if (ridgeAcrossLength < Math.abs(currentRoof.y1 - acrossRoof.y1)) { - ridgeAcrossLength = Math.round(Math.round(Math.abs(currentRoof.y1 - acrossRoof.y1) * 10) - currentRoof.attributes.planeSize) - } - } - } - - ridgeBaseLength = ridgeBaseLength / 10 - ridgeMaxLength = ridgeMaxLength / 10 - ridgeAcrossLength = ridgeAcrossLength / 10 - - console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength) - - if (ridgeBaseLength > 0 && ridgeMaxLength > 0 && ridgeAcrossLength > 0) { - let ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) - if (currentRoof.x1 === currentRoof.x2) { - startXPoint = currentRoof.x1 + (nextRoof.direction === 'right' ? 1 : -1) * ridgeBaseLength - startYPoint = currentRoof.y1 + (currentRoof.direction === 'top' ? -1 : 1) * ridgeBaseLength - endXPoint = startXPoint + (nextRoof.direction === 'right' ? 1 : -1) * ridgeLength - endYPoint = startYPoint - let adjustY - if (currentRoof.direction === 'top') { - if (afterNextRoof.direction === 'bottom' && beforePrevRoof.direction === 'bottom') { - adjustY = - Math.abs(currentRoof.x1 - afterNextRoof.x1) < Math.abs(currentRoof.x1 - beforePrevRoof.x1) ? afterNextRoof.y2 : beforePrevRoof.y1 - } else if (afterNextRoof.direction === 'bottom' && afterNextRoof.y2 > currentRoof.y2 && afterNextRoof.y2 < currentRoof.y1) { - adjustY = afterNextRoof.y2 - } else if (beforePrevRoof.direction === 'bottom' && beforePrevRoof.y1 > currentRoof.y2 && beforePrevRoof.y1 < currentRoof.y1) { - adjustY = beforePrevRoof.y1 - } - if (adjustY) { - startYPoint = currentRoof.y1 - Math.abs(currentRoof.y1 - adjustY) / 2 - endYPoint = startYPoint - } - } - if (currentRoof.direction === 'bottom') { - if (afterNextRoof.direction === 'top' && beforePrevRoof.direction === 'top') { - adjustY = - Math.abs(currentRoof.x1 - afterNextRoof.x1) < Math.abs(currentRoof.x1 - beforePrevRoof.x1) ? afterNextRoof.y2 : beforePrevRoof.y1 - } else if (afterNextRoof.direction === 'top' && afterNextRoof.y2 < currentRoof.y2 && afterNextRoof.y2 > currentRoof.y1) { - adjustY = afterNextRoof.y2 - } else if (beforePrevRoof.direction === 'top' && beforePrevRoof.y1 < currentRoof.y2 && beforePrevRoof.y1 > currentRoof.y1) { - adjustY = beforePrevRoof.y1 - } - if (adjustY) { - startYPoint = currentRoof.y1 + Math.abs(currentRoof.y1 - adjustY) / 2 - endYPoint = startYPoint - } - } - if (yEqualInnerLines.length > 0) { - yEqualInnerLines.reduce((prev, current) => { - if (prev !== undefined) { - return Math.abs(currentRoof.y1 - prev.y1) < Math.abs(currentRoof.y1 - current.y1) ? prev : current - } else { - return current - } - }, undefined) - startYPoint = - Math.abs(currentRoof.y1 - startYPoint) * 2 <= Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1) - ? startYPoint - : Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1) - endYPoint = startYPoint - ridgeAcrossLength = Math.max(prevRoof.length, nextRoof.length) - Math.abs(currentRoof.y1 - startYPoint) * 2 - if ( - //yEqualInnerLines 이 다음 벽보다 안쪽에 있을때 - Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1) <= Math.abs(currentRoof.y1 - nextRoof.y1) && - Math.abs(currentRoof.x1 - yEqualInnerLines[0].x2) >= Math.abs(currentRoof.x1 - nextRoof.x2) - ) { - ridgeMaxLength = Math.round(Math.abs(currentRoof.x1 - yEqualInnerLines[0].x2) * 10) / 10 - } - ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) - startXPoint = currentRoof.x1 + (nextRoof.direction === 'right' ? 1 : -1) * Math.abs(currentRoof.y1 - startYPoint) - endXPoint = startXPoint + (nextRoof.direction === 'right' ? 1 : -1) * ridgeLength - } - } - if (currentRoof.y1 === currentRoof.y2) { - startXPoint = currentRoof.x1 + (currentRoof.direction === 'left' ? -1 : 1) * ridgeBaseLength - startYPoint = currentRoof.y1 + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeBaseLength - endXPoint = startXPoint - endYPoint = startYPoint + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeLength - - let adjustX - if (currentRoof.direction === 'right') { - if (afterNextRoof.direction === 'left' && beforePrevRoof.direction === 'left') { - adjustX = - Math.abs(currentRoof.y1 - afterNextRoof.y1) < Math.abs(currentRoof.y1 - beforePrevRoof.y1) ? afterNextRoof.x2 : beforePrevRoof.x1 - } else if (afterNextRoof.direction === 'left' && afterNextRoof.x2 < currentRoof.x2 && afterNextRoof.x2 > currentRoof.x1) { - adjustX = afterNextRoof.x2 - } else if (beforePrevRoof.direction === 'left' && beforePrevRoof.x1 < currentRoof.x2 && beforePrevRoof.x1 > currentRoof.x1) { - adjustX = beforePrevRoof.x1 - } - if (adjustX) { - startXPoint = currentRoof.x1 + Math.abs(currentRoof.x1 - adjustX) / 2 - endXPoint = startXPoint - } - } - if (currentRoof.direction === 'left') { - if (afterNextRoof.direction === 'right' && beforePrevRoof.direction === 'right') { - adjustX = - Math.abs(currentRoof.y1 - afterNextRoof.y1) < Math.abs(currentRoof.y1 - beforePrevRoof.y1) ? afterNextRoof.x2 : beforePrevRoof.x1 - } else if (afterNextRoof.direction === 'right' && afterNextRoof.x2 > currentRoof.x2 && afterNextRoof.x2 < currentRoof.x1) { - adjustX = afterNextRoof.x2 - } else if (beforePrevRoof.direction === 'right' && beforePrevRoof.x1 > currentRoof.x2 && beforePrevRoof.x1 < currentRoof.x1) { - adjustX = beforePrevRoof.x1 - } - if (adjustX) { - startXPoint = currentRoof.x1 - Math.abs(currentRoof.x1 - adjustX) / 2 - endXPoint = startXPoint - } - } - if (xEqualInnerLines.length > 0) { - xEqualInnerLines.reduce((prev, current) => { - if (prev !== undefined) { - return Math.abs(currentRoof.x1 - prev.x1) < Math.abs(currentRoof.x1 - current.x1) ? prev : current - } else { - return current - } - }, undefined) - startXPoint = - Math.abs(currentRoof.x1 - startXPoint) * 2 <= Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1) - ? startXPoint - : Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1) - endXPoint = startXPoint - ridgeAcrossLength = Math.max(prevRoof.length, nextRoof.length) - Math.abs(currentRoof.x1 - startXPoint) * 2 - if ( - //xEqualInnerLines 이 다음 벽보다 안쪽에 있을때 - Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1) <= Math.abs(currentRoof.x1 - nextRoof.x1) && - Math.abs(currentRoof.y1 - xEqualInnerLines[0].y2) >= Math.abs(currentRoof.y1 - nextRoof.y2) - ) { - ridgeMaxLength = Math.round(Math.abs(currentRoof.y1 - xEqualInnerLines[0].y2) * 10) / 10 - } - ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) - startYPoint = currentRoof.y1 + (nextRoof.direction === 'bottom' ? 1 : -1) * Math.abs(currentRoof.x1 - startXPoint) - endYPoint = startYPoint + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeLength - } - } - } - - // 마루 그리기 - if (startXPoint !== undefined && startYPoint !== undefined && endXPoint !== undefined && endYPoint !== undefined) { - startXPoint = Math.round(startXPoint * 10) / 10 - startYPoint = Math.round(startYPoint * 10) / 10 - endXPoint = Math.round(endXPoint * 10) / 10 - endYPoint = Math.round(endYPoint * 10) / 10 - const ridge = new QLine( - [Math.min(startXPoint, endXPoint), Math.min(startYPoint, endYPoint), Math.max(startXPoint, endXPoint), Math.max(startYPoint, endYPoint)], - { - fontSize: roof.fontSize, - stroke: 'blue', - strokeWidth: 1, - name: LINE_TYPE.SUBLINE.RIDGE, - attributes: { roofId: roof.id }, - }, - ) - ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) - ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10) - - canvas.add(ridge) - roof.ridges.push(ridge) - roof.innerLines.push(ridge) - - const distance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) - const dist1 = distance(startXPoint, startYPoint, currentRoof.x1, currentRoof.y1) - const dist2 = distance(endXPoint, endYPoint, currentRoof.x1, currentRoof.y1) - - currentRoof.attributes.ridgeCoordinate = { - x1: dist1 < dist2 ? startXPoint : endXPoint, - y1: dist1 < dist2 ? startYPoint : endYPoint, - } - }*/ } }) //겹쳐지는 마루는 하나로 합침 - /*roof.ridges.forEach((ridge, index) => { + roof.ridges.forEach((ridge, index) => { roof.ridges .filter((ridge2) => !(ridge.x1 === ridge2.x1 && ridge.y1 === ridge2.y1 && ridge.x2 === ridge2.x2 && ridge.y2 === ridge2.y2)) .forEach((ridge2) => { @@ -1717,7 +1544,7 @@ const drawRidge = (roof, canvas) => { roof.innerLines.push(newRidge) } }) - })*/ + }) canvas?.renderAll() } @@ -1782,39 +1609,52 @@ const drawHips = (roof, canvas) => { const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree const ridgeCoordinate = currentRoof.attributes.ridgeCoordinate - const hip1 = new QLine([currentRoof.x1, currentRoof.y1, ridgeCoordinate.x1, ridgeCoordinate.y1], { - fontSize: roof.fontSize, - stroke: 'red', - strokeWidth: 1, - name: LINE_TYPE.SUBLINE.HIP, - attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, - }) - canvas.add(hip1) - const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10 - const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180)) - hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 - if (prevDegree === currentDegree) { - hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) - } - roof.hips.push(hip1) - roof.innerLines.push(hip1) - const hip2 = new QLine([currentRoof.x2, currentRoof.y2, ridgeCoordinate.x1, ridgeCoordinate.y1], { - fontSize: roof.fontSize, - stroke: 'red', - strokeWidth: 1, - name: LINE_TYPE.SUBLINE.HIP, - attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, - }) - canvas.add(hip2) - const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10 - const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180)) - hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 - if (nextDegree === currentDegree) { - hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) + const vectorX1 = ridgeCoordinate.x1 - currentRoof.x1 + const vectorY1 = ridgeCoordinate.y1 - currentRoof.y1 + const angle1 = Math.atan2(vectorY1, vectorX1) * (180 / Math.PI) + console.log('angle1', Math.abs(Math.round(angle1)) % 45) + if (Math.abs(Math.round(angle1)) % 45 === 0) { + const hip1 = new QLine([currentRoof.x1, currentRoof.y1, ridgeCoordinate.x1, ridgeCoordinate.y1], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: LINE_TYPE.SUBLINE.HIP, + attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, + }) + canvas.add(hip1) + const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10 + const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180)) + hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 + if (prevDegree === currentDegree) { + hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) + } + roof.hips.push(hip1) + roof.innerLines.push(hip1) + } + + const vectorX2 = ridgeCoordinate.x1 - currentRoof.x2 + const vectorY2 = ridgeCoordinate.y1 - currentRoof.y2 + const angle2 = Math.atan2(vectorY2, vectorX2) * (180 / Math.PI) + console.log('angle2', Math.abs(Math.round(angle2)) % 45) + if (Math.abs(Math.round(angle2)) % 45 === 0) { + const hip2 = new QLine([currentRoof.x2, currentRoof.y2, ridgeCoordinate.x1, ridgeCoordinate.y1], { + fontSize: roof.fontSize, + stroke: 'red', + strokeWidth: 1, + name: LINE_TYPE.SUBLINE.HIP, + attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, + }) + canvas.add(hip2) + const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10 + const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180)) + hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 + if (nextDegree === currentDegree) { + hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) + } + roof.hips.push(hip2) + roof.innerLines.push(hip2) } - roof.hips.push(hip2) - roof.innerLines.push(hip2) }) const hipLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.HIP && object.attributes.roofId === roof.id) @@ -1872,7 +1712,7 @@ const drawHips = (roof, canvas) => { if (ridgePoints !== undefined) { const hip = new QLine([currentRoof.x1, currentRoof.y1, ridgePoints.x, ridgePoints.y], { fontSize: roof.fontSize, - stroke: 'red', + stroke: 'yellow', strokeWidth: 1, name: LINE_TYPE.SUBLINE.HIP, attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, @@ -2286,8 +2126,6 @@ const changeEavesRoof = (currentRoof, canvas) => { const alpha = midX - midWallX // 벽과 지붕의 X 거리 const beta = midY - midWallY // 벽과 지붕의 Y 거리 const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 - // const addHipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비 - // const addHipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비 const hipX2 = Math.round(midX + -1 * (alpha / hypotenuse) * (currentRoof.length / 2)) const hipY2 = Math.round(midY + -1 * (beta / hypotenuse) * (currentRoof.length / 2)) @@ -2585,7 +2423,7 @@ const changeGableRoof = (currentRoof, canvas) => { const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180)) hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) - roof.innerLines.push(hip1) + // roof.innerLines.push(hip1) let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX, midY], { fontSize: roof.fontSize, @@ -2604,7 +2442,7 @@ const changeGableRoof = (currentRoof, canvas) => { const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180)) hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) - roof.innerLines.push(hip2) + // roof.innerLines.push(hip2) canvas?.renderAll() } } @@ -3013,7 +2851,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10 gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2))) canvas?.add(gable1) - // roof.innerLines.push(gable1) + roof.innerLines.push(gable1) hipX1 = (Math.sign(currentRoof.x2 - midX) * currentRoof.attributes.width) / 2 hipY1 = (Math.sign(currentRoof.y2 - midY) * currentRoof.attributes.width) / 2 @@ -3034,7 +2872,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10 gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2))) canvas?.add(gable2) - // roof.innerLines.push(gable2) + roof.innerLines.push(gable2) const gable3 = new QLine([gable1.x1, gable1.y1, gable2.x1, gable2.y1], { fontSize: roof.fontSize, @@ -3068,7 +2906,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) canvas?.add(hip1) - roof.innerLines.push(hip1) + // roof.innerLines.push(hip1) const hip2 = new QLine([currentRoof.x2, currentRoof.y2, gable2.x1, gable2.y1], { fontSize: roof.fontSize, @@ -3086,7 +2924,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => { hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) canvas?.add(hip2) - roof.innerLines.push(hip2) + // roof.innerLines.push(hip2) } } }