diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 021357c4..721e3543 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -445,11 +445,22 @@ 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 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/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/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: '', }) 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/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..3ed8f9a1 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 @@ -1311,265 +1309,194 @@ 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] + // console.log('currentRoof : ', currentRoof.direction, currentRoof.attributes.planeSize) - 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가 같은 내부선 - yEqualInnerLines = anotherRoof.filter((roof) => roof.y1 === roof.y2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)) //y가 같은 내부선 + 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 - 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) // 맞은편 벽까지의 길이 - 지붕의 기반 길이 + const currentAngle = Math.atan2(currentY2 - currentY1, currentX2 - currentX1) * (180 / Math.PI) + anotherRoof + .filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof)) + .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 } - 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 + 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) { + } } }) - .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) + 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)) // 벽과 지붕의 거리 - return isX1Between && isX2Between && isY1Between && isY2Between - }) - } + 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) * (currentPlaneSize / 2)) / 10) + startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentPlaneSize / 2)) / 10) + + const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength)) + const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength)) + + 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) { - 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 - } + 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 { - 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 - } + return current } }, 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 + if (intersectLines.length > 0) { + const intersectLine = intersectLines[0] + 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 - console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength) + const hypo = Math.sqrt(Math.pow(Math.abs(startXPoint - endXPoint), 2) + Math.pow(Math.abs(startYPoint - endYPoint), 2)) - 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 + 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 + (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 + 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 * ridgeMinLength) + endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMinLength) } + console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', endXPoint, 'endYPoint', endYPoint) - // 마루 그리기 - 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) + 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) @@ -1682,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) @@ -1772,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 }, @@ -2186,10 +2126,8 @@ 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 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 +2203,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 +2233,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 @@ -2484,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, @@ -2503,7 +2442,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() } } @@ -2949,7 +2892,6 @@ 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) const hip1 = new QLine([currentRoof.x1, currentRoof.y1, gable1.x1, gable1.y1], {