From 94bbbc0f3a3518eb219f95027a0d9fc9826ab7b6 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Mon, 2 Sep 2024 14:41:51 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A7=88=EB=A3=A8=20=ED=85=9C=ED=94=8C?= =?UTF-8?q?=EB=A6=BF=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/qpolygon-utils.js | 729 +++++++++++++++---------------------- 1 file changed, 294 insertions(+), 435 deletions(-) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 387198a6..2e9f9ebe 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1195,415 +1195,308 @@ function calculateAngleBetweenLines(line1, line2) { } export const drawHippedRoof = (polygon, chon) => { - drawRoofRidge(polygon) - // drawHips(polygon) - // connectLinePoint(polygon) + drawRoofRidge(polygon, chon) + drawHips(polygon) + connectLinePoint(polygon) } -/*마루 그리기 - 외벽의 모양이 돌출된 ㄷ의 형태일때 - 현재 라인의 외벽길이가 붙어있는 두외벽의 길이보다 짧거나 같다면 - 지붕의 두 꼭지점에서 외벽의 두 꼭지점으로 45도 방향으로 선을 그려 만나는 지점이 마루의 시작점이 되고 - 시작점에서 부터 (가장 긴선 - ( 삼각형의 빗변 에서 직각까지의 수직길이 x 2))의 길이가 마루의 끝점이 된다. - 다만 마루의 길이는 나머지 나머지 두 지붕의 길이중 짧은선의 길이를 넘어갈수 없다. -*/ -const drawRoofRidge = (polygon) => { - const lines = polygon.wall.lines - console.log('polygon.wall.lines : ', polygon.wall.lines) - console.log('polygon.wall.points : ', polygon.wall.points) - polygon.lines.forEach((value, index) => { - let currentLine, prevWall, currentWall, nextWall - let startXPoint, startYPoint, endXPoint, endYPoint + +const drawRoofRidge = (polygon, chon) => { + const points = [] + polygon.wall.points.forEach((point) => points.push({ x: point.x, y: point.y })) + console.log('points : ', points) + + const walls = polygon.wall.lines // 외벽의 라인 + const roofs = polygon.lines // 지붕의 라인 + const ridgeWall = [] + walls.forEach((wall, index) => { + let currentRoof, prevWall, currentWall, nextWall + if (index === 0) { - prevWall = polygon.wall.lines[polygon.wall.lines.length - 1] + prevWall = walls[walls.length - 1] } else { - prevWall = polygon.wall.lines[index - 1] + prevWall = walls[index - 1] } - currentLine = polygon.lines[index] - currentWall = polygon.wall.lines[index] + currentRoof = roofs[index] + currentWall = walls[index] - if (index === polygon.lines.length - 1) { - nextWall = polygon.wall.lines[0] - } else if (index === polygon.lines.length) { - nextWall = polygon.wall.lines[1] + if (index === walls.length - 1) { + nextWall = walls[0] + } else if (index === walls.length) { + nextWall = walls[1] } else { - nextWall = polygon.wall.lines[index + 1] + nextWall = walls[index + 1] } - if (getLineDirection(prevWall) !== getLineDirection(nextWall) && currentWall.length < currentLine.length) { - let minX = Math.min(currentWall.x1, currentWall.x2, prevWall.x1, nextWall.x2) - let maxX = Math.max(currentWall.x1, currentWall.x2, prevWall.x1, nextWall.x2) - let minY = Math.min(currentWall.y1, currentWall.y2, prevWall.y1, nextWall.y2) - let maxY = Math.max(currentWall.y1, currentWall.y2, prevWall.y1, nextWall.y2) + if (getLineDirection(prevWall) !== getLineDirection(nextWall) && currentWall.length < currentRoof.length) { + ridgeWall.push({ index: index, wall: currentWall, length: currentWall.length }) + } + }) - let lineCoordinate = [ - { x: minX, y: minY }, - { x: minX, y: maxY }, - { x: maxX, y: maxY }, - { x: maxX, y: minY }, - ] + // 지붕의 길이가 짧은 순으로 정렬 + ridgeWall.sort((a, b) => a.length - b.length) - let innerPointLine = lines.filter((line) => { - if (getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { - return line - } - }) - console.log('innerPointLine : ', innerPointLine) - innerPointLine = innerPointLine.reduce((prev, current) => { - if (prev !== undefined) { - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - return Math.abs(currentWall.x1 - prev.x1 + (currentWall.x1 - prev.x2)) < - Math.abs(currentWall.x1 - current.x1 + (currentWall.x1 - current.x2)) - ? prev - : current - } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - return Math.abs(currentWall.y1 - prev.y1 + (currentWall.y1 - prev.y2)) < - Math.abs(currentWall.y1 - current.y1 + (currentWall.y1 - current.y2)) - ? prev - : current - } - } else { - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - return current - } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - return current - } - } - }, undefined) - console.log('innerPointLine : ', innerPointLine) + ridgeWall.forEach((item) => { + if (getMaxRidge(walls.length) > polygon.ridges.length) { + let index = item.index, + // currentRoof = roofs[index], + beforePrevWall, + prevWall, + currentWall = item.wall, + nextWall, + afterNextWall + let startXPoint, startYPoint, endXPoint, endYPoint - console.log('여기 확인 ===== currentWall : ', currentWall) - let acrossLine = lines.filter((line) => { - if (currentWall.direction === 'top') { - if (prevWall.direction === 'right' && currentWall.x1 > line.x1 && line.direction === 'bottom') { - return line - } - if (prevWall.direction === 'left' && currentWall.x1 < line.x1 && line.direction === 'bottom') { - return line - } - } - if (currentWall.direction === 'bottom') { - if (prevWall.direction === 'right' && currentWall.x1 > line.x1 && line.direction === 'top') { - return line - } - if (prevWall.direction === 'left' && currentWall.x1 < line.x1 && line.direction === 'top') { - return line - } - } - if (currentWall.direction === 'left') { - if (prevWall.direction === 'top' && currentWall.y1 < line.y1 && line.direction === 'right') { - return line - } - if (prevWall.direction === 'bottom' && currentWall.y1 > line.y1 && line.direction === 'right') { - return line - } - } - if (currentWall.direction === 'right') { - if (prevWall.direction === 'top' && currentWall.y1 < line.y1 && line.direction === 'left') { - return line - } - if (prevWall.direction === 'bottom' && currentWall.y1 > line.y1 && line.direction === 'left') { - return line - } - } - }) - console.log('acrossLine : ', acrossLine) - if (acrossLine.length > 1) { - acrossLine = acrossLine.reduce((prev, current) => { - let baseLine = { x1: currentWall.x1, y1: currentWall.y1, x2: currentWall.x2, y2: currentWall.y2 } - if (innerPointLine !== undefined) { - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - baseLine = { - x1: currentWall.x1, - y1: currentWall.y1, - x2: - Math.abs(currentWall.x1 - innerPointLine.x1) < Math.abs(currentWall.x1 - innerPointLine.x2) ? innerPointLine.x1 : innerPointLine.x2, - y2: currentWall.y2, - } + if (index === 0) { + prevWall = walls[walls.length - 1] + } else { + prevWall = walls[index - 1] + } + + if (index === 0) { + beforePrevWall = walls[roofs.length - 2] + } else if (index === 1) { + beforePrevWall = walls[roofs.length - 1] + } else { + beforePrevWall = walls[index - 2] + } + + if (index === walls.length - 1) { + nextWall = walls[0] + } else if (index === walls.length) { + nextWall = walls[1] + } else { + nextWall = walls[index + 1] + } + + if (index === walls.length - 2) { + afterNextWall = walls[0] + } else if (index === walls.length - 1) { + afterNextWall = walls[1] + } else if (index === walls.length) { + afterNextWall = walls[2] + } else { + afterNextWall = walls[index + 2] + } + + const anotherRoof = walls.filter((wall) => wall !== currentWall && wall !== prevWall && wall !== nextWall) + let acrossRoof, xEqualInnerLines, yEqualInnerLines + xEqualInnerLines = anotherRoof.filter((roof) => roof.x1 === roof.x2 && isInnerLine(prevWall, currentWall, nextWall, roof)) //x가 같은 내부선 + yEqualInnerLines = anotherRoof.filter((roof) => roof.y1 === roof.y2 && isInnerLine(prevWall, currentWall, nextWall, roof)) //y가 같은 내부선 + + let ridgeBaseLength = currentWall.length / 2, // 지붕의 기반 길이 + ridgeMaxLength = Math.min(prevWall.length, nextWall.length), // 지붕의 최대 길이. 이전, 다음 벽 중 짧은 길이 + ridgeAcrossLength = Math.max(prevWall.length, nextWall.length) - currentWall.length // 맞은편 벽까지의 길이 - 지붕의 기반 길이 + + acrossRoof = anotherRoof + .filter((roof) => { + if (currentWall.direction === 'top' && roof.direction === 'bottom') { + if (nextWall.direction === 'right' && roof.x1 > currentWall.x1) { + return roof } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - baseLine = { - x1: currentWall.x1, - y1: currentWall.y1, - x2: currentWall.x2, - y2: - Math.abs(currentWall.y1 - innerPointLine.y1) < Math.abs(currentWall.y1 - innerPointLine.y2) ? innerPointLine.y1 : innerPointLine.y2, - } + if (nextWall.direction === 'left' && roof.x1 < currentWall.x1) { + return roof } } + if (currentWall.direction === 'right' && roof.direction === 'left') { + if (nextWall.direction === 'top' && roof.y1 < currentWall.y1) { + return roof + } + if (nextWall.direction === 'bottom' && roof.y1 > currentWall.y1) { + return roof + } + } + }) + .reduce((prev, current) => { + let hasBetweenWall = false + if (current.direction === 'top' || current.direction === 'bottom') { + hasBetweenWall = walls + .filter((wall) => wall !== current && wall !== currentWall) + .some((line) => { + let currentY2 = currentWall.y2 + if (yEqualInnerLines.length > 0) { + yEqualInnerLines.forEach((line) => { + currentY2 = Math.abs(currentWall.y1 - currentY2) < Math.abs(currentWall.y1 - line.y1) ? currentY2 : line.y1 + }) + } + const isY1Between = (line.y1 > currentWall.y1 && line.y1 < currentY2) || (line.y1 > currentY2 && line.y1 < currentWall.y1) + const isY2Between = (line.y2 > currentWall.y1 && line.y2 < currentY2) || (line.y2 > currentY2 && line.y2 < currentWall.y1) + const isX1Between = (line.x1 > currentWall.x1 && line.x1 < current.x1) || (line.x1 > currentWall.x1 && line.x1 < current.x1) + const isX2Between = (line.x2 > currentWall.x1 && line.x2 < current.x1) || (line.x2 > currentWall.x1 && line.x2 < current.x1) + return isY1Between && isY2Between && isX1Between && isX2Between + }) + } + if (current.direction === 'right' || current.direction === 'left') { + hasBetweenWall = walls + .filter((wall) => wall !== current && wall !== currentWall) + .some((line) => { + let currentX2 = currentWall.x2 + if (xEqualInnerLines.length > 0) { + xEqualInnerLines.forEach((line) => { + currentX2 = Math.abs(currentWall.x1 - currentX2) < Math.abs(currentWall.x1 - line.x1) ? currentX2 : line.x1 + }) + } + const isX1Between = (line.x1 > currentWall.x1 && line.x1 < currentX2) || (line.x1 > currentX2 && line.x1 < currentWall.x1) + const isX2Between = (line.x2 > currentWall.x1 && line.x2 < currentX2) || (line.x2 > currentX2 && line.x2 < currentWall.x1) + const isY1Between = (line.y1 > currentWall.y1 && line.y1 < current.y1) || (line.y1 > currentWall.y1 && line.y1 < current.y1) + const isY2Between = (line.y2 > currentWall.y1 && line.y2 < current.y1) || (line.y2 > currentWall.y1 && line.y2 < current.y1) + + return isX1Between && isX2Between && isY1Between && isY2Between + }) + } if (prev !== undefined) { if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - if (hasBetweenLines(lines, baseLine, current) > 0) { - return prev - } - if (prevWall.direction === 'right' && currentWall.x1 > current.x1) { - return Math.abs(prev.x1 - currentWall.x1) > Math.abs(current.x1 - currentWall.x1) ? prev : current - } - if (prevWall.direction === 'left' && currentWall.x1 < current.x1) { - return Math.abs(prev.x1 - currentWall.x1) > Math.abs(current.x1 - currentWall.x1) ? prev : current - } + return Math.abs(currentWall.y1 - prev.y1) > Math.abs(currentWall.y1 - current.y1) ? prev : current } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - console.log('prevWall : ', prevWall) - if (hasBetweenLines(lines, baseLine, current) > 0) { - return prev - } - if (prevWall.direction === 'top' && currentWall.y1 < current.y1) { - return Math.abs(prev.y1 - currentWall.y1) > Math.abs(current.y1 - currentWall.y1) ? prev : current - } - if (prevWall.direction === 'bottom' && currentWall.y1 > current.y1) { - return Math.abs(prev.y1 - currentWall.y1) > Math.abs(current.y1 - currentWall.y1) ? prev : current - } + if (currentWall.direction === 'right' || currentWall.direction === 'left') { + return Math.abs(currentWall.x1 - prev.x1) > Math.abs(currentWall.x1 - current.x1) ? prev : current } - return prev } else { - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - if (hasBetweenLines(lines, baseLine, current) > 0) { - return undefined - } - if (prevWall.direction === 'right' && currentWall.x1 > current.x1) { - return current - } - if (prevWall.direction === 'left' && currentWall.x1 < current.x1) { - return current - } - } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - if (hasBetweenLines(lines, baseLine, current) > 0) { - return undefined - } - if (prevWall.direction === 'top' && currentWall.y1 < current.y1) { - return current - } - if (prevWall.direction === 'bottom' && currentWall.y1 > current.y1) { - return current - } + if (!hasBetweenWall) { + return current + } else { + return undefined } } }, undefined) - } - console.log('acrossLine : ', acrossLine) - if (acrossLine.length === 1) { - acrossLine = acrossLine[0] - } - - let ridgeLengthToWall, ridgeBaseLength, ridgeLengthToAcrossLine, ridgeMaxLength - - console.log('currentWall : ', currentWall.length) - console.log('innerPointLine : ', innerPointLine) - if (innerPointLine !== undefined) { + if (acrossRoof !== undefined) { if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - console.log('currentWall : ', currentWall) - console.log('acrossLine : ', acrossLine) - if (innerPointLine.y1 === innerPointLine.y2) { - console.log('innerPointLine : ', innerPointLine) - ridgeBaseLength = Math.abs(currentWall.y1 - innerPointLine.y1) - ridgeLengthToWall = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.x1 - acrossLine.x1)) - ridgeBaseLength - ridgeLengthToWall = Math.min( - Math.max(Math.abs(currentWall.x1 - innerPointLine.x1), Math.abs(currentWall.x1 - innerPointLine.x2)), - ridgeLengthToWall, - ) - ridgeLengthToAcrossLine = Math.abs(acrossLine.x1 - innerPointLine.x1) - ridgeMaxLength = Math.max( - prevWall.length, - nextWall.length, - Math.abs(currentWall.x1 - acrossLine.x1), - Math.abs(currentWall.x1 - acrossLine.x1), - ) - } else { - ridgeBaseLength = - Math.abs(currentWall.y1 - innerPointLine.y1) < Math.abs(currentWall.y1 - innerPointLine.y2) - ? Math.abs(currentWall.y1 - innerPointLine.y1) - : Math.abs(currentWall.y1 - innerPointLine.y2) - ridgeLengthToWall = Math.max(prevWall.length, nextWall.length, ridgeBaseLength) - ridgeBaseLength - ridgeLengthToAcrossLine = Math.abs(acrossLine.x1 - innerPointLine.x1) - ridgeMaxLength = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.x1 - acrossLine.x1)) - } - console.log( - 'ridgeBaseLength : ', - ridgeBaseLength, - ' ridgeLengthToWall : ', - ridgeLengthToWall, - ' ridgeLengthToAcrossLine : ', - ridgeLengthToAcrossLine, - 'ridgeMaxLength : ', - ridgeMaxLength, - ) - if (ridgeBaseLength > 0) { - if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { - if (nextWall.direction === 'right') { - startXPoint = currentWall.x1 + ridgeBaseLength / 2 - endXPoint = startXPoint + ridgeLengthToWall - } - if (nextWall.direction === 'left') { - startXPoint = currentWall.x1 - ridgeBaseLength / 2 - endXPoint = startXPoint - ridgeLengthToWall - } - } else { - if (nextWall.direction === 'right') { - startXPoint = acrossLine.x1 - ridgeLengthToAcrossLine - ridgeBaseLength / 2 - endXPoint = acrossLine.x1 - ridgeBaseLength / 2 - } - if (nextWall.direction === 'left') { - startXPoint = acrossLine.x1 + ridgeLengthToAcrossLine + ridgeBaseLength / 2 - endXPoint = startXPoint - ridgeLengthToAcrossLine - } - } - if (currentWall.direction === 'top') { - startYPoint = currentWall.y1 - ridgeBaseLength / 2 - endYPoint = startYPoint - } - if (currentWall.direction === 'bottom') { - startYPoint = currentWall.y1 + ridgeBaseLength / 2 - endYPoint = startYPoint - } + if (ridgeAcrossLength < Math.abs(currentWall.x1 - acrossRoof.x1)) { + ridgeAcrossLength = Math.abs(currentWall.x1 - acrossRoof.x1) - currentWall.length } } if (currentWall.direction === 'right' || currentWall.direction === 'left') { - // console.log('currentWall.length : ', currentWall.length) - if (innerPointLine.x1 === innerPointLine.x2) { - ridgeBaseLength = Math.abs(currentWall.x1 - innerPointLine.x1) - ridgeLengthToWall = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.x1 - acrossLine.x1)) - ridgeBaseLength - ridgeLengthToAcrossLine = Math.abs(acrossLine.y1 - innerPointLine.y1) - ridgeLengthToWall = Math.min( - Math.max(Math.abs(currentWall.y1 - innerPointLine.y1), Math.abs(currentWall.y1 - innerPointLine.y2)), - ridgeLengthToWall, - ) - ridgeMaxLength = Math.max( - prevWall.length, - nextWall.length, - Math.abs(currentWall.y1 - acrossLine.y1), - Math.abs(currentWall.y1 - acrossLine.y2), - ) - } else { - ridgeBaseLength = - Math.abs(currentWall.x1 - innerPointLine.x1) < Math.abs(currentWall.x1 - innerPointLine.x2) - ? Math.abs(currentWall.x1 - innerPointLine.x1) - : Math.abs(currentWall.x1 - innerPointLine.x2) - ridgeLengthToWall = Math.max(prevWall.length, nextWall.length, ridgeBaseLength) - ridgeBaseLength - ridgeLengthToAcrossLine = Math.abs(acrossLine.y1 - innerPointLine.y1) - ridgeMaxLength = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.y1 - acrossLine.y1)) - } - console.log( - 'ridgeBaseLength : ', - ridgeBaseLength, - ' ridgeLengthToWall : ', - ridgeLengthToWall, - ' ridgeLengthToAcrossLine : ', - ridgeLengthToAcrossLine, - ) - if (ridgeBaseLength > 0) { - if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { - if (nextWall.direction === 'top') { - startYPoint = currentWall.y1 - ridgeBaseLength / 2 - endYPoint = startYPoint - ridgeLengthToWall - } - if (nextWall.direction === 'bottom') { - startYPoint = currentWall.y1 + ridgeBaseLength / 2 - endYPoint = startYPoint + ridgeLengthToWall - } - } else { - if (nextWall.direction === 'top') { - startYPoint = acrossLine.y1 + ridgeLengthToAcrossLine + ridgeBaseLength / 2 - endYPoint = acrossLine.y1 + ridgeBaseLength / 2 - } - if (nextWall.direction === 'bottom') { - startYPoint = acrossLine.y1 - ridgeLengthToAcrossLine - ridgeBaseLength / 2 - endYPoint = acrossLine.y1 - ridgeBaseLength / 2 - } - } - if (currentWall.direction === 'right') { - startXPoint = currentWall.x1 + ridgeBaseLength / 2 - endXPoint = startXPoint - } - if (currentWall.direction === 'left') { - startXPoint = currentWall.x1 - ridgeBaseLength / 2 - endXPoint = startXPoint - } - } - } - } else { - console.log('여기부터 확인 currentWall : ', currentWall.length) - console.log('acrossLine : ', acrossLine) - console.log('acrossLine : ', acrossLine.x1) - ridgeBaseLength = currentWall.length - ridgeLengthToWall = Math.min(prevWall.length, nextWall.length) - ridgeMaxLength = Math.max(prevWall.length, nextWall.length) - console.log('ridgeBaseLength : ', ridgeBaseLength, ' ridgeLengthToWall : ', ridgeLengthToWall, ' ridgeMaxLength : ', ridgeMaxLength) - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - ridgeLengthToAcrossLine = Math.abs(acrossLine.x1 - currentWall.x1) - ridgeBaseLength - ridgeMaxLength = Math.max(ridgeMaxLength, Math.abs(acrossLine.x1 - currentWall.x1)) - if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { - if (nextWall.direction === 'right') { - startXPoint = currentWall.x1 + ridgeBaseLength / 2 - endXPoint = startXPoint + ridgeLengthToWall - } - if (nextWall.direction === 'left') { - startXPoint = currentWall.x1 - ridgeBaseLength / 2 - endXPoint = startXPoint - ridgeLengthToWall - } - } else { - if (nextWall.direction === 'right') { - startXPoint = acrossLine.x1 - ridgeLengthToAcrossLine - ridgeBaseLength / 2 - endXPoint = startXPoint + ridgeLengthToAcrossLine - } - if (nextWall.direction === 'left') { - startXPoint = acrossLine.x1 + ridgeLengthToAcrossLine + ridgeBaseLength / 2 - endXPoint = startXPoint - ridgeLengthToAcrossLine - } - } - if (currentWall.direction === 'top') { - startYPoint = currentWall.y1 - ridgeBaseLength / 2 - endYPoint = startYPoint - } - if (currentWall.direction === 'bottom') { - startYPoint = currentWall.y1 + ridgeBaseLength / 2 - endYPoint = startYPoint - } - } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - ridgeLengthToAcrossLine = Math.abs(acrossLine.y1 - currentWall.y1) - ridgeBaseLength - ridgeMaxLength = Math.max(ridgeMaxLength, Math.abs(acrossLine.x1 - currentWall.x1)) - if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { - if (nextWall.direction === 'top') { - startYPoint = currentWall.y1 - ridgeBaseLength / 2 - endYPoint = startYPoint - ridgeLengthToWall - } - if (nextWall.direction === 'bottom') { - startYPoint = currentWall.y1 + ridgeBaseLength / 2 - endYPoint = startYPoint + ridgeLengthToWall - } - } else { - if (nextWall.direction === 'top') { - startYPoint = acrossLine.y1 + ridgeLengthToAcrossLine + ridgeBaseLength / 2 - endYPoint = acrossLine.y1 + ridgeBaseLength / 2 - } - if (nextWall.direction === 'bottom') { - startYPoint = acrossLine.y1 - ridgeLengthToAcrossLine - ridgeBaseLength / 2 - endYPoint = acrossLine.y1 - ridgeBaseLength / 2 - } - } - if (currentWall.direction === 'right') { - startXPoint = currentWall.x1 + ridgeBaseLength / 2 - endXPoint = startXPoint - } - if (currentWall.direction === 'left') { - startXPoint = currentWall.x1 - ridgeBaseLength / 2 - endXPoint = startXPoint + if (ridgeAcrossLength < Math.abs(currentWall.y1 - acrossRoof.y1)) { + ridgeAcrossLength = Math.abs(currentWall.y1 - acrossRoof.y1) - currentWall.length } } } - console.log('ridgeLengthToAcrossLine : ', ridgeLengthToAcrossLine) - console.log(startXPoint, startYPoint, endXPoint, endYPoint) - if ( - // polygon.ridges.length < getMaxRidge(lines.length) && - ridgeBaseLength <= ridgeMaxLength && - startXPoint !== undefined && - startYPoint !== undefined && - endXPoint !== undefined && - endYPoint !== undefined - ) { + + if (ridgeBaseLength > 0 && ridgeMaxLength > 0 && ridgeAcrossLength > 0) { + let ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + startXPoint = currentWall.x1 + (nextWall.direction === 'right' ? 1 : -1) * ridgeBaseLength + startYPoint = currentWall.y1 + (currentWall.direction === 'top' ? -1 : 1) * ridgeBaseLength + endXPoint = startXPoint + (nextWall.direction === 'right' ? 1 : -1) * ridgeLength + endYPoint = startYPoint + let adjustY + if (currentWall.direction === 'top') { + if (afterNextWall.direction === 'bottom' && beforePrevWall.direction === 'bottom') { + adjustY = + Math.abs(currentWall.x1 - afterNextWall.x1) < Math.abs(currentWall.x1 - beforePrevWall.x1) ? afterNextWall.y2 : beforePrevWall.y1 + } else if (afterNextWall.direction === 'bottom' && afterNextWall.y2 > currentWall.y2 && afterNextWall.y2 < currentWall.y1) { + adjustY = afterNextWall.y2 + } else if (beforePrevWall.direction === 'bottom' && beforePrevWall.y1 > currentWall.y2 && beforePrevWall.y1 < currentWall.y1) { + adjustY = beforePrevWall.y1 + } + if (adjustY) { + startYPoint = currentWall.y1 - Math.abs(currentWall.y1 - adjustY) / 2 + endYPoint = startYPoint + } + } + if (currentWall.direction === 'bottom') { + if (afterNextWall.direction === 'top' && beforePrevWall.direction === 'top') { + adjustY = + Math.abs(currentWall.x1 - afterNextWall.x1) < Math.abs(currentWall.x1 - beforePrevWall.x1) ? afterNextWall.y2 : beforePrevWall.y1 + } else if (afterNextWall.direction === 'top' && afterNextWall.y2 < currentWall.y2 && afterNextWall.y2 > currentWall.y1) { + adjustY = afterNextWall.y2 + } else if (beforePrevWall.direction === 'top' && beforePrevWall.y1 < currentWall.y2 && beforePrevWall.y1 > currentWall.y1) { + adjustY = beforePrevWall.y1 + } + if (adjustY) { + startYPoint = currentWall.y1 + Math.abs(currentWall.y1 - adjustY) / 2 + endYPoint = startYPoint + } + } + if (yEqualInnerLines.length > 0) { + yEqualInnerLines.reduce((prev, current) => { + if (prev !== undefined) { + return Math.abs(currentWall.y1 - prev.y1) < Math.abs(currentWall.y1 - current.y1) ? prev : current + } else { + return current + } + }, undefined) + startYPoint = + Math.abs(currentWall.y1 - startYPoint) * 2 <= Math.abs(currentWall.y1 - yEqualInnerLines[0].y1) + ? startYPoint + : Math.abs(currentWall.y1 - yEqualInnerLines[0].y1) + endYPoint = startYPoint + ridgeAcrossLength = Math.max(prevWall.length, nextWall.length) - Math.abs(currentWall.y1 - startYPoint) * 2 + if ( + //yEqualInnerLines 이 다음 벽보다 안쪽에 있을때 + Math.abs(currentWall.y1 - yEqualInnerLines[0].y1) <= Math.abs(currentWall.y1 - nextWall.y1) && + Math.abs(currentWall.x1 - yEqualInnerLines[0].x2) >= Math.abs(currentWall.x1 - nextWall.x2) + ) { + ridgeMaxLength = Math.abs(currentWall.x1 - yEqualInnerLines[0].x2) + } + ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) + startXPoint = currentWall.x1 + (nextWall.direction === 'right' ? 1 : -1) * Math.abs(currentWall.y1 - startYPoint) + endXPoint = startXPoint + (nextWall.direction === 'right' ? 1 : -1) * ridgeLength + } + } + if (currentWall.direction === 'left' || currentWall.direction === 'right') { + startXPoint = currentWall.x1 + (currentWall.direction === 'left' ? -1 : 1) * ridgeBaseLength + startYPoint = currentWall.y1 + (nextWall.direction === 'bottom' ? 1 : -1) * ridgeBaseLength + endXPoint = startXPoint + endYPoint = startYPoint + (nextWall.direction === 'bottom' ? 1 : -1) * ridgeLength + let adjustX + if (currentWall.direction === 'right') { + if (afterNextWall.direction === 'left' && beforePrevWall.direction === 'left') { + adjustX = + Math.abs(currentWall.y1 - afterNextWall.y1) < Math.abs(currentWall.y1 - beforePrevWall.y1) ? afterNextWall.x2 : beforePrevWall.x1 + } else if (afterNextWall.direction === 'left' && afterNextWall.x2 < currentWall.x2 && afterNextWall.x2 > currentWall.x1) { + adjustX = afterNextWall.x2 + } else if (beforePrevWall.direction === 'left' && beforePrevWall.x1 < currentWall.x2 && beforePrevWall.x1 > currentWall.x1) { + adjustX = beforePrevWall.x1 + } + if (adjustX) { + startXPoint = currentWall.x1 + Math.abs(currentWall.x1 - adjustX) / 2 + endXPoint = startXPoint + } + } + if (currentWall.direction === 'left') { + if (afterNextWall.direction === 'right' && beforePrevWall.direction === 'right') { + adjustX = + Math.abs(currentWall.y1 - afterNextWall.y1) < Math.abs(currentWall.y1 - beforePrevWall.y1) ? afterNextWall.x2 : beforePrevWall.x1 + } else if (afterNextWall.direction === 'right' && afterNextWall.x2 > currentWall.x2 && afterNextWall.x2 < currentWall.x1) { + adjustX = afterNextWall.x2 + } else if (beforePrevWall.direction === 'right' && beforePrevWall.x1 > currentWall.x2 && beforePrevWall.x1 < currentWall.x1) { + adjustX = beforePrevWall.x1 + } + if (adjustX) { + startXPoint = currentWall.x1 - Math.abs(currentWall.x1 - adjustX) / 2 + endXPoint = startXPoint + } + } + if (xEqualInnerLines.length > 0) { + xEqualInnerLines.reduce((prev, current) => { + if (prev !== undefined) { + return Math.abs(currentWall.x1 - prev.x1) < Math.abs(currentWall.x1 - current.x1) ? prev : current + } else { + return current + } + }, undefined) + startXPoint = + Math.abs(currentWall.x1 - startXPoint) * 2 <= Math.abs(currentWall.x1 - xEqualInnerLines[0].x1) + ? startXPoint + : Math.abs(currentWall.x1 - xEqualInnerLines[0].x1) + endXPoint = startXPoint + ridgeAcrossLength = Math.max(prevWall.length, nextWall.length) - Math.abs(currentWall.x1 - startXPoint) * 2 + if ( + //xEqualInnerLines 이 다음 벽보다 안쪽에 있을때 + Math.abs(currentWall.x1 - xEqualInnerLines[0].x1) <= Math.abs(currentWall.x1 - nextWall.x1) && + Math.abs(currentWall.y1 - xEqualInnerLines[0].y2) >= Math.abs(currentWall.y1 - nextWall.y2) + ) { + ridgeMaxLength = Math.abs(currentWall.y1 - xEqualInnerLines[0].y2) + } + ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength) + startYPoint = currentWall.y1 + (nextWall.direction === 'bottom' ? 1 : -1) * Math.abs(currentWall.x1 - startXPoint) + endYPoint = startYPoint + (nextWall.direction === 'bottom' ? 1 : -1) * ridgeLength + } + } + } + + // 마루 그리기 + if (!(startXPoint === undefined && startYPoint === undefined && endXPoint === undefined && endYPoint === undefined)) { const ridge = new QLine( [Math.min(startXPoint, endXPoint), Math.min(startYPoint, endYPoint), Math.max(startXPoint, endXPoint), Math.max(startYPoint, endYPoint)], { @@ -1615,13 +1508,10 @@ const drawRoofRidge = (polygon) => { polygon.canvas.add(ridge) polygon.ridges.push(ridge) polygon.innerLines.push(ridge) - polygon.canvas.renderAll() } } }) - //중복 제거 - polygon.ridges = polygon.ridges.filter((ridge, index, self) => index === self.findIndex((t) => t.x1 === ridge.x1 && t.y1 === ridge.y1)) - polygon.innerLines = polygon.innerLines.filter((line, index, self) => index === self.findIndex((t) => t.x1 === line.x1 && t.y1 === line.y1)) + //겹쳐지는 마루는 하나로 합침 polygon.ridges.forEach((ridge, index) => { polygon.ridges @@ -1653,44 +1543,27 @@ const drawRoofRidge = (polygon) => { } }) }) - console.log('polygon.ridges : ', polygon.ridges) } /** - * ridge 계산시 line 1과 line2 사이에 다른 라인이 있는지 확인 - * @param lines 전체 라인 - * @param baseLine1 currentWall - * @param baseLine2 acrossLine + * line 이 세 라인 사이에 존재하는지 확인한다. + * @param prevLine + * @param currentLine + * @param nextLine + * @param line */ -const hasBetweenLines = (lines, baseLine1, baseLine2) => { - let checkLines = [] - if (baseLine1.x1 === baseLine1.x2) { - checkLines = lines - .filter((line) => line.x1 === line.x2 && line.x1 < Math.max(baseLine1.x1, baseLine2.x1) && line.x1 > Math.min(baseLine1.x1, baseLine2.x1)) - .filter((line) => { - let checkY1 = Math.min(line.y1, line.y2) - let checkY2 = Math.max(line.y1, line.y2) - let baseY1 = Math.min(baseLine1.y1, baseLine1.y2) - let baseY2 = Math.max(baseLine1.y1, baseLine1.y2) - if ((checkY1 <= baseY1 && checkY2 > baseY1) || (checkY2 >= baseY2 && checkY1 < baseY2)) { - return line - } - }) +const isInnerLine = (prevLine, currentLine, nextLine, line) => { + let inside = false + let minX = Math.min(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2) + let maxX = Math.max(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2) + let minY = Math.min(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2) + let maxY = Math.max(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2) + + if (minX < line.x1 && line.x1 < maxX && minY < line.y1 && line.y1 < maxY && minX < line.x2 && line.x2 < maxX && minY < line.y2 && line.y2 < maxY) { + inside = true } - if (baseLine1.y1 === baseLine1.y2) { - checkLines = lines - .filter((line) => line.y1 === line.y2 && line.y1 < Math.max(baseLine1.y1, baseLine2.y1) && line.y1 > Math.min(baseLine1.y1, baseLine2.y1)) - .filter((line) => { - let checkX1 = Math.min(line.x1, line.x2) - let checkX2 = Math.max(line.x1, line.x2) - let baseX1 = Math.min(baseLine1.x1, baseLine1.x2) - let baseX2 = Math.max(baseLine1.x1, baseLine1.x2) - if ((checkX1 <= baseX1 && checkX2 > baseX1) || (checkX2 >= baseX2 && checkX1 < baseX2)) { - return line - } - }) - } - return checkLines.length + + return inside } /** @@ -1701,16 +1574,12 @@ const hasBetweenLines = (lines, baseLine1, baseLine2) => { */ const segmentsOverlap = (line1, line2) => { if (line1.y1 === line1.y2 && line2.y1 === line2.y2 && line1.y1 === line2.y1) { - // console.log('가로방향 겹침 확인 ') if ((line1.x1 <= line2.x1 && line1.x2 >= line2.x1) || (line1.x1 <= line2.x2 && line1.x2 >= line2.x2)) { - // console.log('가로방향 겹침') return true } } if (line1.x1 === line1.x2 && line2.x1 === line2.x2 && line1.x1 === line2.x1) { - // console.log('세로방향 겹침 확인') if ((line1.y1 <= line2.y1 && line1.y2 >= line2.y1) || (line1.y1 <= line2.y2 && line1.y2 >= line2.y2)) { - // console.log('세로방향 겹침') return true } } @@ -1721,12 +1590,9 @@ const drawHips = (polygon) => { /* 마루에서 시작되는 hip을 먼저 그립니다. */ - console.log('polygon.ridges', polygon.ridges) - console.log('polygon.lines', polygon.lines) polygon.ridges.forEach((ridge) => { let leftTop, rightTop, leftBottom, rightBottom if (ridge.y1 === ridge.y2) { - console.log('가로방향 마루') //왼쪽 좌표 기준 225, 315도 방향 라인확인 leftTop = polygon.lines .filter((line) => line.x1 < ridge.x1 && line.y1 < ridge.y1 && Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1)) @@ -1997,7 +1863,6 @@ const drawHips = (polygon) => { isRidgePointOnLine = true } }) - console.log('leftBottom isRidgePointOnLine : ', isRidgePointOnLine) if (!isRidgePointOnLine) { const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x2, ridge.y2], { fontSize: polygon.fontSize, @@ -2282,8 +2147,6 @@ const drawHips = (polygon) => { break } - console.log('nearRidge : ', nearRidge) - if (nearRidge !== undefined) { let endXPoint, endYPoint let minX, maxX, minY, maxY @@ -2351,7 +2214,6 @@ const drawHips = (polygon) => { }) // 마루와 연결되지 않은 hip을 그린다. - console.log('마루와 연결되지 않은 hip') polygon.lines.forEach((line, index) => { if (!isAlreadyHip(polygon, line)) { let prevLine, currentLine, nextLine @@ -2388,8 +2250,6 @@ const drawHips = (polygon) => { let acrossLine = getAcrossLine(polygon, currentLine, dVector) let hypotenuse, adjacent - console.log(acrossLine) - if (getLineDirection(prevLine) === getLineDirection(nextLine)) { hypotenuse = Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2)) } else { @@ -2398,11 +2258,8 @@ const drawHips = (polygon) => { Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2)), ) } - adjacent = getAdjacent(hypotenuse) - console.log('dVector : ', dVector) - switch (dVector) { case 45: endXPoint = currentLine.x1 + adjacent @@ -2432,7 +2289,6 @@ const drawHips = (polygon) => { polygon.innerLines.push(hip) } }) - // this.canvas.renderAll() } const getPointInPolygon = (polygon, point, isInclude = false) => { @@ -2441,7 +2297,6 @@ const getPointInPolygon = (polygon, point, isInclude = false) => { maxX = Math.max(polygon[0].x, polygon[1].x, polygon[2].x, polygon[3].x), minY = Math.min(polygon[0].y, polygon[1].y, polygon[2].y, polygon[3].y), maxY = Math.max(polygon[0].y, polygon[1].y, polygon[2].y, polygon[3].y) - if (!isInclude && minX < point.x && point.x < maxX && minY < point.y && point.y < maxY) { inside = true } @@ -2540,6 +2395,10 @@ const connectLinePoint = (polygon) => { } }) + console.log('polygon.ridges : ', polygon.ridges) + + console.log('missedPoints : ', missedPoints) + //추녀마루 polygon.hips.forEach((hip) => { let count = 0