From 1870b866ea69882405c007f8bc6c8d49d93e788d Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Mon, 12 Aug 2024 13:16:55 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A4=EA=B0=81=ED=98=95=20=EB=AA=A8?= =?UTF-8?q?=EC=9E=84=EC=A7=80=EB=B6=95=20=EC=9E=91=EC=97=85=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 2 +- src/components/fabric/QPolygon.js | 4 +- src/util/qpolygon-utils.js | 237 ++++++++++++++++++++---------- 3 files changed, 160 insertions(+), 83 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 922215a5..974aeabd 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -301,7 +301,7 @@ export default function Roof2() { { x: 450, y: 850 }, ] - const polygon = new QPolygon(twelvePoint, { + const polygon = new QPolygon(twelvePoint2, { fill: 'transparent', stroke: 'green', strokeWidth: 1, diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 706d2e7a..089ed8bc 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -2,7 +2,7 @@ import { fabric } from 'fabric' import { v4 as uuidv4 } from 'uuid' import { QLine } from '@/components/fabric/QLine' import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util' -import { calculateAngle, dividePolygon, drawHelpLineInHexagon, splitPolygonWithLines , drawHippedRoof} from '@/util/qpolygon-utils' +import { calculateAngle, drawHippedRoof } from '@/util/qpolygon-utils' export const QPolygon = fabric.util.createClass(fabric.Polygon, { type: 'QPolygon', @@ -452,6 +452,6 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { }) }, divideLine() { - splitPolygonWithLines(this) + // splitPolygonWithLines(this) }, }) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 85ad4204..25cebfef 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1120,8 +1120,8 @@ function calculateAngleBetweenLines(line1, line2) { export const drawHippedRoof = (polygon, chon) => { drawRoofRidge(polygon) - drawHips(polygon) - connectLinePoint(polygon) + // drawHips(polygon) + // connectLinePoint(polygon) } /*마루 그리기 외벽의 모양이 돌출된 ㄷ의 형태일때 @@ -1132,6 +1132,7 @@ export const drawHippedRoof = (polygon, chon) => { */ 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 @@ -1165,79 +1166,101 @@ const drawRoofRidge = (polygon) => { { x: maxX, y: minY }, ] - let innerPointLine = lines - .filter((line) => { - if (getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { - return line + 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 } - }) - .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 - } + 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 } - }, undefined) + } else { + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + return current + } + if (currentWall.direction === 'left' || currentWall.direction === 'right') { + return current + } + } + }, undefined) + console.log('innerPointLine : ', innerPointLine) console.log('여기 확인 ===== currentWall : ', currentWall) - let acrossLine = lines - .filter((line) => { - /*let minAcrossX, maxAcrossX, minAcrossY, maxAcrossY - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - minAcrossX = Math.min(currentWall.x1, line.x1) - maxAcrossX = Math.max(currentWall.x1, line.x1) - minAcrossY = Math.min(currentWall.y1, currentWall.y2) - maxAcrossY = Math.max(currentWall.y1, currentWall.y2) + let acrossLine = lines.filter((line) => { + if (currentWall.direction === 'top') { + if (prevWall.direction === 'right' && currentWall.x1 > line.x1 && line.direction === 'bottom') { + return line } - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - minAcrossX = Math.min(currentWall.x1, currentWall.x2) - maxAcrossX = Math.max(currentWall.x1, currentWall.x2) - minAcrossY = Math.min(currentWall.y1, line.y1) - maxAcrossY = Math.max(currentWall.y1, line.y1) + if (prevWall.direction === 'left' && currentWall.x1 < line.x1 && line.direction === 'bottom') { + return line } - let coordinate = [ - { x: minAcrossX, y: minAcrossY }, - { x: minAcrossX, y: maxAcrossY }, - { x: maxAcrossX, y: maxAcrossY }, - { x: maxAcrossX, y: minAcrossY }, - ] - console.log('coordinate : ', coordinate) - let isPointInLine = false - lines.forEach((l) => { - if (getPointInPolygon(coordinate, { x: l.x1, y: l.y1 }, true)) { - isPointInLine = true + } + 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 (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, + } } - }) - console.log('line : ', line) - console.log('isPointInLine : ', isPointInLine)*/ - // if (!isPointInLine && (currentWall.direction === 'top' || currentWall.direction === 'bottom')) { - if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - return line.direction === 'top' || line.direction === 'bottom' } - // if (!isPointInLine && (currentWall.direction === 'left' || currentWall.direction === 'right')) { - if (currentWall.direction === 'left' || currentWall.direction === 'right') { - return line.direction === 'left' || line.direction === 'right' - } - }) - .reduce((prev, current) => { 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 } @@ -1246,6 +1269,10 @@ const drawRoofRidge = (polygon) => { } } 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 } @@ -1256,6 +1283,9 @@ const drawRoofRidge = (polygon) => { 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 } @@ -1264,6 +1294,9 @@ const drawRoofRidge = (polygon) => { } } 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 } @@ -1273,17 +1306,22 @@ const drawRoofRidge = (polygon) => { } } }, 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) + console.log('currentWall : ', currentWall.length) + console.log('innerPointLine : ', innerPointLine) if (innerPointLine !== undefined) { if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { - // console.log('currentWall : ', currentWall) - // console.log('acrossLine : ', acrossLine) + console.log('currentWall : ', currentWall) + console.log('acrossLine : ', acrossLine) if (innerPointLine.y1 === innerPointLine.y2) { - // console.log('innerPointLine : ', innerPointLine) + 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( @@ -1306,7 +1344,7 @@ const drawRoofRidge = (polygon) => { ridgeLengthToAcrossLine = Math.abs(acrossLine.x1 - innerPointLine.x1) ridgeMaxLength = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.x1 - acrossLine.x1)) } - /*console.log( + console.log( 'ridgeBaseLength : ', ridgeBaseLength, ' ridgeLengthToWall : ', @@ -1315,7 +1353,7 @@ const drawRoofRidge = (polygon) => { ridgeLengthToAcrossLine, 'ridgeMaxLength : ', ridgeMaxLength, - )*/ + ) if (ridgeBaseLength > 0) { if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { if (nextWall.direction === 'right') { @@ -1371,14 +1409,14 @@ const drawRoofRidge = (polygon) => { ridgeLengthToAcrossLine = Math.abs(acrossLine.y1 - innerPointLine.y1) ridgeMaxLength = Math.max(prevWall.length, nextWall.length, Math.abs(currentWall.y1 - acrossLine.y1)) } - /*console.log( + console.log( 'ridgeBaseLength : ', ridgeBaseLength, ' ridgeLengthToWall : ', ridgeLengthToWall, ' ridgeLengthToAcrossLine : ', ridgeLengthToAcrossLine, - )*/ + ) if (ridgeBaseLength > 0) { if (ridgeLengthToWall <= ridgeLengthToAcrossLine) { if (nextWall.direction === 'top') { @@ -1410,12 +1448,13 @@ const drawRoofRidge = (polygon) => { } } } else { - // console.log('여기부터 확인 currentWall : ', currentWall.length) - // console.log('acrossLine : ', acrossLine) + 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) + 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)) @@ -1479,8 +1518,8 @@ const drawRoofRidge = (polygon) => { } } } - // console.log('ridgeLengthToAcrossLine : ', ridgeLengthToAcrossLine) - // console.log(startXPoint, startYPoint, endXPoint, endYPoint) + console.log('ridgeLengthToAcrossLine : ', ridgeLengthToAcrossLine) + console.log(startXPoint, startYPoint, endXPoint, endYPoint) if ( // polygon.ridges.length < getMaxRidge(lines.length) && ridgeBaseLength <= ridgeMaxLength && @@ -1500,6 +1539,7 @@ const drawRoofRidge = (polygon) => { polygon.canvas.add(ridge) polygon.ridges.push(ridge) polygon.innerLines.push(ridge) + polygon.canvas.renderAll() } } }) @@ -1537,6 +1577,44 @@ const drawRoofRidge = (polygon) => { } }) }) + console.log('polygon.ridges : ', polygon.ridges) +} + +/** + * ridge 계산시 line 1과 line2 사이에 다른 라인이 있는지 확인 + * @param lines 전체 라인 + * @param baseLine1 currentWall + * @param baseLine2 acrossLine + */ +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 + } + }) + } + 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 } /** @@ -2509,7 +2587,6 @@ const connectLinePoint = (polygon) => { let missedRidge = [] polygon.ridges.forEach((ridge) => { let lineCheck1 = polygon.innerLines.filter((line) => { - console.log(!(line.x1 !== ridge.x1 && line.y1 !== ridge.y1 && line.x2 !== ridge.x2 && line.y2 !== ridge.y2)) if ( !(line.x1 === ridge.x1 && line.y1 === ridge.y1 && line.x2 === ridge.x2 && line.y2 === ridge.y2) && ((line.x1 === ridge.x1 && line.y1 === ridge.y1) || (line.x2 === ridge.x1 && line.y2 === ridge.y1))