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,