From e685e53c5f5661d2587805422857438c8d6e9756 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Mon, 29 Jul 2024 18:21:42 +0900 Subject: [PATCH] =?UTF-8?q?=EB=94=94=EB=B2=84=EA=B9=85=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 26 +- src/components/fabric/QPolygon.js | 668 ++++++++++-------------------- src/util/canvas-util.js | 2 +- 3 files changed, 242 insertions(+), 454 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 8225d6b9..0fb89925 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -207,6 +207,28 @@ export default function Roof2() { { x: 897, y: 215 }, ] + const eightPoint3 = [ + { x: 200, y: 200 }, + { x: 200, y: 1000 }, + { x: 1000, y: 1000 }, + { x: 1000, y: 800 }, + { x: 600, y: 800 }, + { x: 600, y: 350 }, + { x: 1000, y: 350 }, + { x: 1000, y: 200 }, + ] + + const eightPoint4 = [ + { x: 200, y: 200 }, + { x: 200, y: 400 }, + { x: 500, y: 400 }, + { x: 500, y: 700 }, + { x: 800, y: 700 }, + { x: 800, y: 400 }, + { x: 1100, y: 400 }, + { x: 1100, y: 200 }, + ] + const octaType1 = [ { x: 100, y: 100 }, { x: 100, y: 600 }, @@ -217,8 +239,8 @@ export default function Roof2() { ] if (canvas) { - // const polygon = new QPolygon(octaType1, { - const polygon = new QPolygon(eightPoint2, { + const polygon = new QPolygon(eightPoint4, { + // const polygon = new QPolygon(eightPoint, { fill: 'transparent', stroke: 'black', strokeWidth: 1, diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index d343ab0b..0e355a56 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -5,6 +5,7 @@ import { distanceBetweenPoints, findClosestLineToPoint, findTopTwoIndexesByDistance, + getAdjacent, getDegreeByChon, getDirectionByPoint, getRoofHeight, @@ -33,6 +34,7 @@ export default class QPolygon extends fabric.Group { initOption ridges = [] hips = [] + innerLines = [] constructor(points, options, canvas) { /*if (points.length !== 4 && points.length !== 6) { @@ -913,7 +915,7 @@ export default class QPolygon extends fabric.Group { #drawHelpLineInOctagon(chon) { this.drawRoofRidge() this.drawHips() - // this.connectLinePoint() + this.connectLinePoint() } /*마루 그리기 @@ -959,9 +961,10 @@ export default class QPolygon extends fabric.Group { maxLineLength, } = this.getRoofBaseLine(prevLine, currentLine, nextLine, dVector) + console.log('currentLine.length : ' + currentLine.length) // 마루는 세개의 벽중에서 가장 길 수 없다. - // console.log('currentLineLength : ', currentLineLength, 'minLineLength : ', minLineLength, 'maxLineLength : ', maxLineLength) - // console.log('minLineLength <= currentLineLength <= maxLineLength', (minLineLength <= currentLineLength && currentLineLength <= maxLineLength)) + console.log('currentLineLength : ', currentLineLength, 'minLineLength : ', minLineLength, 'maxLineLength : ', maxLineLength) + console.log('minLineLength <= currentLineLength <= maxLineLength', (minLineLength <= currentLineLength && currentLineLength <= maxLineLength)) if (currentLineLength <= maxLineLength) { // console.log('currentLine.length : ' + currentLine.length) @@ -1011,12 +1014,13 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(ridge) this.ridges.push(ridge) + this.innerLines.push(ridge) } } } }, ) - this.canvas.renderAll() + // this.canvas.renderAll() } drawHips() { @@ -1026,16 +1030,14 @@ export default class QPolygon extends fabric.Group { this.ridges.forEach((ridge) => { let leftTop, rightTop, leftBottom, rightBottom if (ridge.x1 !== ridge.x2 && ridge.y1 === ridge.y2) { - console.log('가로방향 마루') + // console.log('가로방향 마루') //왼쪽 좌표 기준 225, 315도 방향 라인확인 leftTop = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 < ridge.y1 && Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1)) .reduce((prev, current) => { if (prev <= 0) { - console.log('prev undefined') return current } else { - console.log('prev : ', prev, 'current : ', current) return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev } }, []) @@ -1072,7 +1074,6 @@ export default class QPolygon extends fabric.Group { } }, []) - console.log(leftTop, leftBottom, rightTop, rightBottom) if (leftTop.length > 0) { const hip = new QLine([leftTop.x1, leftTop.y1, ridge.x1, ridge.y1], { fontSize: this.fontSize, @@ -1081,6 +1082,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (leftBottom.length > 0) { const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x1, ridge.y1], { @@ -1090,6 +1092,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (rightTop.length > 0) { const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x2, ridge.y2], { @@ -1099,6 +1102,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (rightBottom.length > 0) { const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], { @@ -1108,10 +1112,11 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } } if (ridge.y1 !== ridge.y2 && ridge.x1 === ridge.x2) { - console.log('세로방향 마루') + // console.log('세로방향 마루') //위쪽 좌표 기준 45, 315도 방향 라인확인 leftTop = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 < ridge.y1 && Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1)) @@ -1162,6 +1167,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (rightTop.length > 0) { const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x1, ridge.y1], { @@ -1171,6 +1177,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (leftBottom.length > 0) { const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x2, ridge.y2], { @@ -1180,6 +1187,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } if (rightBottom.length > 0) { const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], { @@ -1189,6 +1197,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } } }) @@ -1218,76 +1227,110 @@ export default class QPolygon extends fabric.Group { switch (dVector) { case 45: - nearRidge = this.ridges.filter(ridge => currentLine.x1 < ridge.x1 && currentLine.y1 > ridge.y1 + nearRidge = this.ridges.filter(ridge => (currentLine.x1 < ridge.x1 && currentLine.y1 > ridge.y1) + || (currentLine.x1 < ridge.x2 && currentLine.y1 > ridge.y2) && (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) || Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2))) .reduce((prev, current) => { - if (prev.length > 0) { + if (prev !== undefined) { if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev - } - if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev + } else { + return prev } } else { - return current + if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { + return current + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + return current + } else { + return undefined + } } - }, []) + }, undefined) break case 135: - nearRidge = this.ridges.filter(ridge => currentLine.x1 < ridge.x1 && currentLine.y1 < ridge.y1 + nearRidge = this.ridges.filter(ridge => (currentLine.x1 < ridge.x1 && currentLine.y1 < ridge.y1 + || currentLine.x1 < ridge.x2 && currentLine.y1 < ridge.y2) && (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) || Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2))) .reduce((prev, current) => { - if (prev.length > 0) { + if (prev !== undefined) { if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev - } - if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev + } else { + return prev } } else { - return current + if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { + return current + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + return current + } else { + return undefined + } } - }, []) + }, undefined) break case 225: - nearRidge = this.ridges.filter(ridge => currentLine.x1 > ridge.x1 && currentLine.y1 < ridge.y1 + nearRidge = this.ridges.filter(ridge => (currentLine.x1 > ridge.x1 && currentLine.y1 < ridge.y1 + || currentLine.x1 > ridge.x2 && currentLine.y1 < ridge.y2) && (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) || Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2))) .reduce((prev, current) => { - if (prev.length > 0) { + if (prev !== undefined) { if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev - } - if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev + } else { + return prev } } else { - return current + if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { + return current + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + return current + } else { + return undefined + } } - }, []) + }, undefined) break case 315: - nearRidge = this.ridges.filter(ridge => currentLine.x1 > ridge.x1 && currentLine.y1 > ridge.y1 + nearRidge = this.ridges.filter(ridge => (currentLine.x1 > ridge.x1 && currentLine.y1 > ridge.y1 + || currentLine.x1 > ridge.x2 && currentLine.y1 > ridge.y2) && (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) || Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2))) .reduce((prev, current) => { - if (prev.length > 0) { + if (prev !== undefined) { if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev - } - if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev + } else { + return prev } } else { - return current + if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) { + return current + } else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) { + return current + } else { + return undefined + } } - }, []) + }, undefined) break } - if (nearRidge.length > 0) { + // console.log('nearRidge : ', nearRidge) + + if (nearRidge !== undefined && nearRidge.length > 0) { let endXPoint, endYPoint let minX, maxX, minY, maxY @@ -1395,6 +1438,7 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) + this.innerLines.push(hip) } } } @@ -1436,18 +1480,16 @@ export default class QPolygon extends fabric.Group { ] let acrossLine = this.getAcrossLine(currentLine, dVector) + let hypotenuse, adjacent - console.log('여기 확인') - console.log('currentLine : ', currentLine) - console.log('acrossLine : ', acrossLine) + if (this.getLineDirection(prevLine) === this.getLineDirection(nextLine)) { + hypotenuse = Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2)) + } else { + hypotenuse = Math.min(Math.round(getRoofHypotenuse(currentLine.length / 2)) + , Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2))) + } - let hypotenuse = Math.min(Math.floor(getRoofHypotenuse(currentLine.length / 2)) - , Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2))) - - let adjacent = getAdjacent(hypotenuse) - - console.log('hypotenuse : ', hypotenuse) - console.log('adjacent : ', adjacent) + adjacent = getAdjacent(hypotenuse) switch (dVector) { case 45: @@ -1475,336 +1517,12 @@ export default class QPolygon extends fabric.Group { }) this.addWithUpdate(hip) this.hips.push(hip) - + this.innerLines.push(hip) } }) - - /*let prevLine, currentLine, nextLine - this.lines.forEach( - (value, index) => { - if (index === 0) { - prevLine = this.lines[this.lines.length - 1] - } else { - prevLine = this.lines[index - 1] - } - currentLine = this.lines[index] - - if (index === this.lines.length - 1) { - nextLine = this.lines[0] - } else if (index === this.lines.length) { - nextLine = this.lines[1] - } else { - nextLine = this.lines[index + 1] - } - - if (!this.isAlreadyHip(currentLine)) { - let endXPoint, endYPoint - let dVector = this.getDirectionForDegree(prevLine, currentLine) - let linesXCoordinate = [] - - 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) - - let lineCoordinate = [ - { x: minX, y: minY }, - { x: minX, y: maxY }, - { x: maxX, y: maxY }, - { x: maxX, y: minY }, - ] - - console.log('hip dVector : ', dVector, 'lineCoordinate : ', lineCoordinate) - - let innerPointLine = this.lines.filter(line => { - if (this.getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { - return line - } - }) - - console.log('innerPointLine : ', innerPointLine) - - let lineMaxHypotenuse - if (innerPointLine.length > 0) { - lineMaxHypotenuse = Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - Math.min.apply(null, innerPointLine)))) - console.log(currentLine.x1, lineMaxHypotenuse) - } else { - lineMaxHypotenuse = Math.floor(getRoofHypotenuse(currentLine.length / 2)) - } - console.log('lineMaxHypotenuse : ', lineMaxHypotenuse) - - switch (dVector) { - case 45: - this.ridges.forEach((ridge) => { - if (currentLine.x1 < ridge.x1 && currentLine.y1 > ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 < ridge.x2 && currentLine.y1 > ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - } - }) - break - case 135: - this.ridges.forEach((ridge) => { - if (currentLine.x1 < ridge.x1 && currentLine.y1 < ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 < ridge.x2 && currentLine.y1 < ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - }) - break - case 225: - this.ridges.forEach((ridge) => { - if (currentLine.x1 > ridge.x1 && currentLine.y1 < ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 > ridge.x2 && currentLine.y1 < ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - }) - break - case 315: - this.ridges.forEach((ridge) => { - if (currentLine.x1 > ridge.x1 && currentLine.y1 > ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 > ridge.x2 && currentLine.y1 > ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - }) - break - } - - /!* - 마루와 연결 되지 않은 hip을 그린다. - *!/ - if (endXPoint === undefined || endYPoint === undefined) { - switch (dVector) { - case 45: - break - case 135: - break - case 225: - break - case 315: - break - } - } - /!*switch (dVector) { - case 45: - this.lines.forEach((line) => { - if ((currentLine.x1 < line.x1 || currentLine.x1 < line.x2) - && (line.y1 < currentLine.y1 || line.y2 < currentLine.y1)) { - if (currentLine.x1 !== line.x1) { - linesXCoordinate.push(line.x1) - } - if (currentLine.x1 !== line.x2) { - linesXCoordinate.push(line.x2) - } - } - }) - break - case 135: - this.lines.forEach((line) => { - if ((currentLine.x1 < line.x1 || currentLine.x1 < line.x2) - && (currentLine.y1 < line.y1 || currentLine.y1 < line.y2)) { - if (currentLine.x1 !== line.x1) { - linesXCoordinate.push(line.x1) - } - if (currentLine.x1 !== line.x2) { - linesXCoordinate.push(line.x2) - } - } - }) - break - case 225: - this.lines.forEach((line) => { - if ((line.x1 < currentLine.x1 || line.x2 < currentLine.x1) - && (currentLine.y1 < line.y1 || currentLine.y1 < line.y2)) { - if (currentLine.x1 !== line.x1) { - linesXCoordinate.push(line.x1) - } - if (currentLine.x1 !== line.x2) { - linesXCoordinate.push(line.x2) - } - } - }) - break - case 315: - this.lines.forEach((line) => { - if ((line.x1 < currentLine.x1 || line.x2 < currentLine.x1) - && (line.y1 < currentLine.y1 || line.y2 < currentLine.y1)) { - if (currentLine.x1 !== line.x1) { - linesXCoordinate.push(line.x1) - } - if (currentLine.x1 !== line.x2) { - linesXCoordinate.push(line.x2) - } - } - }) - break - }*!/ - // console.log('linesXCoordinate : ', linesXCoordinate) - // console.log('dVector : ', dVector) - // console.log('currentLine.x1 : ' + currentLine.x1 + ' , linesXCoordinate :', Math.min.apply(null, linesXCoordinate)) - // let lineMaxHypotenuse - // if (linesXCoordinate.length > 0) { - // lineMaxHypotenuse = Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - Math.min.apply(null, linesXCoordinate)))) - // console.log(currentLine.x1, lineMaxHypotenuse) - // } - // console.log('lineMaxHypotenuse : ', lineMaxHypotenuse) - - /!*this.ridges.forEach(ridge => { - switch (dVector) { - case 45: - if (currentLine.x1 < ridge.x1 && currentLine.y1 > ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 < ridge.x2 && currentLine.y1 > ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - break - case 135: - if (currentLine.x1 < ridge.x1 && currentLine.y1 < ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 < ridge.x2 && currentLine.y1 < ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - break - case 225: - if (currentLine.x1 > ridge.x1 && currentLine.y1 < ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 > ridge.x2 && currentLine.y1 < ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - break - case 315: - if (currentLine.x1 > ridge.x1 && currentLine.y1 > ridge.y1 - && Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - } - if (currentLine.x1 > ridge.x2 && currentLine.y1 > ridge.y2 - && Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - break - } - // console.log('getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1)) : ' + Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) + ' <= lineMaxHypotenuse : ' + lineMaxHypotenuse) - /!* - if (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1) - && Math.floor(getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x1))) <= lineMaxHypotenuse) { - endXPoint = ridge.x1 - endYPoint = ridge.y1 - // console.log('X1') - } - if (Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2) - && getRoofHypotenuse(Math.abs(currentLine.x1 - ridge.x2)) <= lineMaxHypotenuse) { - endXPoint = ridge.x2 - endYPoint = ridge.y2 - // console.log('X2') - } - *!/ - - })*!/ - // TODO [ljyoung] : 마루와 만나지 않는 hip 계산 - // console.log('endXPoint : ' + endXPoint + ' , endYPoint : ' + endYPoint) - /!*if (endXPoint === undefined || endYPoint === undefined) { - console.log('currentLine.x1 : ' + currentLine.x1 + ' , ' + - 'this.getReverseHypothenuse(lineMaxHypotenuse): ' + this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - switch (dVector) { - case 45: - endXPoint = Math.abs(currentLine.x1 + this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - endYPoint = Math.abs(currentLine.y1 - this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - break - case 135: - endXPoint = Math.abs(currentLine.x1 + this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - endYPoint = Math.abs(currentLine.y1 + this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - break - case 225: - console.log('currentLine.x1 : ' + currentLine.x1 + ' , ' + currentLine.y1 + ' , ' + this.getReverseHypotenuse(lineMaxHypotenuse)) - endXPoint = Math.abs(currentLine.x1 - this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - endYPoint = Math.abs(currentLine.y1 + this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - break - case 315: - endXPoint = Math.abs(currentLine.x1 - this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - endYPoint = Math.abs(currentLine.y1 - this.getReverseHypotenuse(lineMaxHypotenuse) / 2) - break - } - }*!/ - // console.log(currentLine) - console.log(currentLine.x1, currentLine.y1, endXPoint, endYPoint) - if (endXPoint !== undefined && endYPoint !== undefined) { - const hip = new QLine([currentLine.x1, currentLine.y1, endXPoint, endYPoint], { - fontSize: this.fontSize, - stroke: 'red', - strokeWidth: 1, - }) - this.addWithUpdate(hip) - this.hips.push(hip) - } - } - }, - )*/ - this.canvas.renderAll() + // this.canvas.renderAll() } - getRoofBaseLine(prevLine, currentLine, nextLine, dVector) { let minX = Math.min(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2) let maxX = Math.max(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2) @@ -1897,60 +1615,53 @@ export default class QPolygon extends fabric.Group { * @returns {*[]|null} */ getAcrossLine(currentLine, dVector) { - let acrossLine = null + let acrossLine switch (dVector) { case 45: - acrossLine = this.lines.filter(line => line.x1 > currentLine.x1 && line.y1 < currentLine.y1) + acrossLine = this.lines.filter(line => line.x1 > currentLine.x1 && line.y1 <= currentLine.y1) .reduce((prev, current) => { if (prev.length > 0) { - + return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev } else { return current } }, []) break case 135: + acrossLine = this.lines.filter(line => line.x1 > currentLine.x1 && line.y1 >= currentLine.y1) + .reduce((prev, current) => { + if (prev.length > 0) { + return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev + } else { + return current + } + }, []) break case 225: + acrossLine = this.lines.filter(line => line.x1 < currentLine.x1 && line.y1 >= currentLine.y1) + .reduce((prev, current) => { + if (prev.length > 0) { + return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev + } else { + return current + } + }, []) break case 315: + acrossLine = this.lines.filter(line => line.x1 < currentLine.x1 && line.y1 <= currentLine.y1) + .reduce((prev, current) => { + if (prev.length > 0) { + return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev + } else { + return current + } + }, []) break } - return acrossLine } - /* - 두 선의 교차점이 존재하는지 확인한다. - */ - findIntersection(line1, line2) { - const [x1, y1, x2, y2] = line1 // 첫 번째 선의 두 점 - const [x3, y3, x4, y4] = line2 // 두 번째 선의 두 점 - - // 선의 방정식의 계수 계산 - const A1 = y2 - y1 - const B1 = x1 - x2 - const C1 = A1 * x1 + B1 * y1 - - const A2 = y4 - y3 - const B2 = x3 - x4 - const C2 = A2 * x3 + B2 * y3 - - const determinant = A1 * B2 - A2 * B1 - - if (determinant === 0) { - // 두 선이 평행하거나 일직선일 경우 - console.log('두 직선은 평행하거나 일직선입니다.') - return null - } - - const x = (B1 * C2 - B2 * C1) / determinant - const y = (A1 * C2 - A2 * C1) / determinant - - return { x, y } - } - /* 추녀마루(hip) 중복방지를 위해 마루와 함께 그려진 추녀마루를 확인한다 */ @@ -1969,58 +1680,69 @@ export default class QPolygon extends fabric.Group { 모임지붕에서 point는 3개 이상의 라인과 접해야 함. */ connectLinePoint() { + // 연결되지 않은 모든 라인의 포인트를 구한다. let missedPoints = [] - let missedLine = [] + //마루 this.ridges.forEach(ridge => { - if (this.findConnectionLineCount(ridge.x1, ridge.y1) < 2) { + if (this.hips.filter(hip => hip.x2 === ridge.x1 && hip.y2 === ridge.y1).length < 2) { missedPoints.push({ x: ridge.x1, y: ridge.y1 }) } - if (this.findConnectionLineCount(ridge.x2, ridge.y2) < 2) { + if (this.hips.filter(hip => hip.x2 === ridge.x2 && hip.y2 === ridge.y2).length < 2) { missedPoints.push({ x: ridge.x2, y: ridge.y2 }) } }) - console.log(missedPoints) + //추녀마루 + this.hips.forEach(hip => { + let count = 0 + count += this.ridges.filter(ridge => + (ridge.x1 === hip.x2 && ridge.y1 === hip.y2) || (ridge.x2 === hip.x2 && ridge.y2 === hip.y2), + ).length + count += this.hips.filter(hip2 => + (hip2.x1 === hip.x2 && hip2.y1 === hip.y2) || (hip2.x2 === hip.x2 && hip2.y2 === hip.y2), + ).length + + if (count < 3) { + missedPoints.push({ x: hip.x2, y: hip.y2 }) + } + }) + + let missedLine = [] + + //중복포인트제거 + missedPoints = [ + ...new Set(missedPoints.map((line) => JSON.stringify(line))), + ].map((line) => JSON.parse(line)) missedPoints.forEach(p1 => { - console.log('p1 : ', p1) - let nearX, nearY, diffX, diffY, diffMinX, diffMinY - //가장 가까운 포인트를 확인 - missedPoints.forEach(p2 => { - console.log('p2 : ', p2) - diffX = Math.abs(p1.x - p2.x) - diffY = Math.abs(p1.y - p2.y) - if (diffMinX === undefined && diffMinY === undefined && diffX > 0 && diffY > 0) { - diffMinX = diffX - diffMinY = diffY + let p2 = missedPoints.filter(p => p.x !== p1.x && p.y !== p1.y).reduce((prev, current) => { + if (prev !== undefined) { + return Math.sqrt(Math.pow(Math.abs(current.x - p1.x), 2) + Math.pow(Math.abs(current.y - p1.y), 2)) + < Math.sqrt(Math.pow(Math.abs(prev.x - p1.x), 2) + Math.pow(Math.abs(prev.y - p1.y), 2)) ? current : prev + } else { + return current } - console.log(nearX, nearY, diffX, diffY, diffMinX, diffMinY) - if (diffX > 0 && diffY > 0 && (diffX === diffY) - && diffX <= diffMinX && diffY <= diffMinY) { - nearX = p2.x - nearY = p2.y - diffMinX = Math.abs(p1.x - p2.x) - diffMinY = Math.abs(p1.y - p2.y) + }, undefined) + if (p2 !== undefined) { + if (p1.x < p2.x && p1.y < p2.y) { + missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }) } - }) - console.log(nearX, nearY) - if (nearX !== undefined && nearY !== undefined) { - if (p1.x < nearX && p1.y < nearY) { - missedLine.push({ x1: p1.x, y1: p1.y, x2: nearX, y2: nearY }) - } else if (p1.x > nearX && p1.y < nearY) { - missedLine.push({ x1: nearX, y1: nearY, x2: p1.x, y2: p1.y }) - } else if (p1.x > nearX && p1.y > nearY) { - missedLine.push({ x1: nearX, y1: nearY, x2: p1.x, y2: p1.y }) - } else if (p1.x < nearX && p1.y > nearY) { - missedLine.push({ x1: nearX, y1: nearY, x2: p1.x, y2: p1.y }) + if (p1.x > p2.x && p1.y < p2.y) { + missedLine.push({ x1: p2.x, y1: p2.y, x2: p1.x, y2: p1.y }) + } + if (p1.x > p2.x && p1.y > p2.y) { + missedLine.push({ x1: p2.x, y1: p2.y, x2: p1.x, y2: p1.y }) + } + if (p1.x < p2.x && p1.y > p2.y) { + missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }) } } }) + //중복라인제거 missedLine = [ ...new Set(missedLine.map((line) => JSON.stringify(line))), ].map((line) => JSON.parse(line)) - console.log('missedLine : ', missedLine) missedLine.forEach((p, index) => { const line = new QLine([p.x1, p.y1, p.x2, p.y2], { fontSize: this.fontSize, @@ -2028,25 +1750,69 @@ export default class QPolygon extends fabric.Group { strokeWidth: 1, }) this.addWithUpdate(line) + this.innerLines.push(line) }) - this.canvas.renderAll() - } + missedPoints = [] + missedLine = [] - /* - hip은 항상 마루에 연결되고 마루에는 2개 이상의 hip이 연결된다. - hip의 시작은 처마꼭지점이며 끝은 마루이기 때문에 힙의 끝 좌표와 비교한다. - */ - findConnectionLineCount(x, y) { - // console.log(this.hips) - let count = 0 - this.hips.forEach((hip, index) => { - if (x === hip.x2 && y === hip.y2) { - count++ + this.innerLines.forEach((line, index) => { + if (this.innerLines.filter(innerLine => (line.x2 === innerLine.x1 && line.y2 === innerLine.y1) + || (line.x2 === innerLine.x2 && line.y2 === innerLine.y2)).length < 3) { + missedPoints.push({ x: line.x2, y: line.y2 }) } }) - // console.log(count) - return count + + missedPoints = [ + ...new Set(missedPoints.map((line) => JSON.stringify(line))), + ].map((line) => JSON.parse(line)) + + console.log(missedPoints) + + missedPoints.forEach(p1 => { + let p2 = missedPoints.filter(p => !(p.x === p1.x && p.y === p1.y)).reduce((prev, current) => { + console.log('current : ', current) + console.log('prev : ', prev) + if (prev !== undefined) { + return Math.abs(current.x - p1.x) + Math.abs(current.y - p1.y) < Math.abs(prev.x - p1.x) + Math.abs(prev.y - p1.y) ? current : prev + } else { + return current + } + }, undefined) + + if (p2 !== undefined) { + console.log(p1.x, p2.x, p1.y, p2.y) + if (p1.x === p2.x && p1.y < p2.y) { + missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }) + } + if (p1.x === p2.x && p1.y > p2.y) { + missedLine.push({ x1: p1.x, y1: p2.y, x2: p2.x, y2: p1.y }) + } + if (p1.x < p2.x && p1.y === p2.y) { + missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }) + } + if (p1.x > p2.x && p1.y === p2.y) { + missedLine.push({ x1: p2.x, y1: p1.y, x2: p1.x, y2: p2.y }) + } + } + }) + + //중복라인제거 + missedLine = [ + ...new Set(missedLine.map((line) => JSON.stringify(line))), + ].map((line) => JSON.parse(line)) + + console.log(missedLine) + + missedLine.forEach((p, index) => { + const line = new QLine([p.x1, p.y1, p.x2, p.y2], { + fontSize: this.fontSize, + stroke: 'purple', + strokeWidth: 1, + }) + this.addWithUpdate(line) + this.innerLines.push(line) + }) } /* diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js index a47bc306..ec926cee 100644 --- a/src/util/canvas-util.js +++ b/src/util/canvas-util.js @@ -246,7 +246,7 @@ export const getRoofHypotenuse = (base) => { * @param base 빗변 */ export const getAdjacent = (base) => { - return Math.round(Math.sqrt(Math.pow(line, 2) / 2)) + return Math.round(Math.sqrt(Math.pow(base, 2) / 2)) } /**