From ca1830cb5fb957aa4ce65b4305ea8db171cbed6b Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Tue, 6 Aug 2024 10:38:36 +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=EA=B3=84=EC=82=B0=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 31 +-- src/hooks/useMode.js | 218 ++++++++++------- src/util/qpolygon-utils.js | 465 +++++++++++++++++++++++++++---------- 3 files changed, 488 insertions(+), 226 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index eefef60e..feeb6059 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -252,22 +252,27 @@ export default function Roof2() { { x: 1000, y: 100 }, ] - const diagonalType = [ - { x: 300, y: 100 }, - { x: 100, y: 600 }, - // { x: 250, y: 600 }, - // { x: 250, y: 450 }, - // { x: 400, y: 450 }, - // { x: 400, y: 600 }, - { x: 600, y: 600 }, - { x: 600, y: 100 }, + const testType = [ + { x: 500, y: 400 }, + { x: 650, y: 550 }, + { x: 575, y: 625 }, + { x: 325, y: 625 }, + { x: 100, y: 400 }, + ] + + const testType2 = [ + { x: 100, y: 400 }, + { x: 325, y: 625 }, + { x: 575, y: 625 }, + { x: 650, y: 550 }, + { x: 500, y: 400 }, ] const triangleType = [ { x: 100, y: 100 }, { x: 100, y: 600 }, { x: 600, y: 600 }, - { x: 300, y: 100 }, + { x: 600, y: 100 }, ] const twelvePoint = [ @@ -287,7 +292,7 @@ export default function Roof2() { const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint] - const polygon = new QPolygon(diagonalType, { + const polygon = new QPolygon(eightPoint3, { fill: 'transparent', stroke: 'green', strokeWidth: 1, @@ -297,9 +302,9 @@ export default function Roof2() { }) canvas?.add(polygon) - drawRoofPolygon(polygon) + // drawRoofPolygon(polygon) - // handleOuterlinesTest2(polygon) + handleOuterlinesTest2(polygon) // const lines = togglePolygonLine(polygon) // togglePolygonLine(lines[0]) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index f4ac1c5a..170a38e6 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from 'react' import QRect from '@/components/fabric/QRect' -import { findTopTwoIndexesByDistance, getCenterPoint, getDirection, getStartIndex, rearrangeArray } from '@/util/canvas-util' +import { findTopTwoIndexesByDistance, getCenterPoint, getDirection, getDirectionByPoint, getStartIndex, rearrangeArray } from '@/util/canvas-util' import { useRecoilState } from 'recoil' import { @@ -1178,9 +1178,7 @@ export function useMode() { const drawRoofPolygon = (wall, offset = 50) => { console.log(wall) - const offsetPoints = [] - let lines = wall.lines, - points = wall.points, + let points = wall.points, expandedPoints = [] let minX = points[0].x, @@ -1195,47 +1193,59 @@ export function useMode() { if (point.y > maxY) maxY = point.y }) - wall.lines.forEach((currentWall, index) => { - let prevWall = wall.lines[index === 0 ? wall.lines.length - 1 : index - 1] - let nextWall = wall.lines[index === wall.lines.length - 1 ? 0 : index + 1] - let isStartPointIn = minX < currentWall.x1 && currentWall.x1 < maxX && minY < currentWall.y1 && currentWall.y1 < maxY - let isEndPointIn = minX < currentWall.x2 && currentWall.x2 < maxX && minY < currentWall.y2 && currentWall.y2 < maxY + console.log(points) + points.forEach((point, index) => { + const prevIndex = index === 0 ? points.length - 1 : index - 1 + const nextIndex = index === points.length - 1 ? 0 : index + 1 + point.direction = getDirectionByPoint(point, points[nextIndex]) + point.length = Math.abs(point.x - points[nextIndex].x) === 0 ? Math.abs(point.y - points[nextIndex].y) : Math.abs(point.x - points[nextIndex].x) + // point.degree = Math.round(getDegreeBetweenTwoLines(points[prevIndex], point, points[nextIndex])) + }) + console.log('points : ', points) + + points.forEach((currentWall, index) => { + let prevWall = points[index === 0 ? points.length - 1 : index - 1] + let nextWall = points[index === points.length - 1 ? 0 : index + 1] + let isStartPointIn = minX < currentWall.x && currentWall.x < maxX && minY < currentWall.y && currentWall.y < maxY + // let isEndPointIn = minX < currentWall.x2 && currentWall.x2 < maxX && minY < currentWall.y2 && currentWall.y2 < maxY if (prevWall.direction !== nextWall.direction) { - console.log('if ::::') - console.log('currentWall.direction : ', currentWall.direction, currentWall.length) if (currentWall.direction === 'top') { console.log('prevWall degree : ', 45) if (prevWall.direction === 'right') { - let addLength = getLineOffsetPoint(prevWall, currentWall, offset) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) expandedPoints.push({ - x1: currentWall.x1 + offset + addLength, - y1: currentWall.y1 + offset, + x: currentWall.x + addLength, + y: currentWall.y + addLength, }) } if (prevWall.direction === 'left') { console.log('prevWall degree : ', 225) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } } if (currentWall.direction === 'bottom') { if (prevWall.direction === 'right') { console.log('prevWall degree : ', 45) - console.log('angle : ', getDegreeBetweenTwoLines(prevWall, currentWall)) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) + console.log(currentWall.x, '-', offset, '+', addLength) + console.log('addLength : ', addLength) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + addLength, + y: currentWall.y - addLength, }) } if (prevWall.direction === 'left') { console.log('prevWall degree : ', 315) - let addLength = getLineOffsetPoint(prevWall, currentWall, offset) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) + console.log(currentWall.x, '-', offset, '+', addLength) + console.log('addLength : ', addLength) expandedPoints.push({ - x1: currentWall.x1 - offset + addLength, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } } @@ -1244,14 +1254,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 135) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 + offset, + x: currentWall.x + offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 315) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } } @@ -1260,16 +1270,16 @@ export function useMode() { console.log('prevWall degree : ', 45) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } else { console.log('prevWall degree : ', 225) - let addLength = getLineOffsetPoint(prevWall, currentWall, offset) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) console.log('addLength : ', addLength) expandedPoints.push({ - x1: currentWall.x1 - offset - addLength, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } } @@ -1278,20 +1288,20 @@ export function useMode() { if (prevWall.direction === 'top') { if (isStartPointIn) { console.log('prevWall degree : ', 225) - let addLength = getLineOffsetPoint(prevWall, currentWall, offset) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) console.log('addLength : ', addLength) expandedPoints.push({ - x1: currentWall.x1 - offset - addLength, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 45) - let addLength = getLineOffsetPoint(prevWall, currentWall, offset) + let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) expandedPoints.push({ - x1: currentWall.x1 + offset - addLength, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } } @@ -1299,14 +1309,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 315) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } else { console.log('prevWall degree : ', 135) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 + offset, + x: currentWall.x + offset, + y: currentWall.y + offset, }) } } @@ -1318,14 +1328,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 315) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } else { console.log('prevWall degree : ', 135) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 + offset, + x: currentWall.x + offset, + y: currentWall.y + offset, }) } } @@ -1333,14 +1343,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 45) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } else { console.log('prevWall degree : ', 225) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } } @@ -1350,14 +1360,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 225) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 45) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } } @@ -1367,14 +1377,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 135) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 + offset, + x: currentWall.x + offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 315) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } } @@ -1382,14 +1392,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 225) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 45) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } } @@ -1399,14 +1409,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 225) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 + offset, + x: currentWall.x - offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 45) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 - offset, + x: currentWall.x + offset, + y: currentWall.y - offset, }) } } @@ -1414,14 +1424,14 @@ export function useMode() { if (isStartPointIn) { console.log('prevWall degree : ', 135) expandedPoints.push({ - x1: currentWall.x1 + offset, - y1: currentWall.y1 + offset, + x: currentWall.x + offset, + y: currentWall.y + offset, }) } else { console.log('prevWall degree : ', 315) expandedPoints.push({ - x1: currentWall.x1 - offset, - y1: currentWall.y1 - offset, + x: currentWall.x - offset, + y: currentWall.y - offset, }) } } @@ -1429,9 +1439,19 @@ export function useMode() { } }) - const roof = makePolygon(expandedPoints) - roof.setWall(wall) - setRoof(roof) + console.log('expandedPoints : ', expandedPoints) + + /*const roof = new fabric.Polygon(expandedPoints, { + fill: 'transparent', + stroke: 'red', + strokeWidth: 1, + selectable: true, + fontSize: fontSize, + name: 'QPolygon1', + }) + + roof.wall = wall + canvas?.add(roof)*/ // roof.drawHelpLine() } @@ -1440,37 +1460,62 @@ export function useMode() { * 구하려는 라인의 x1,y1좌표가 기준 * @param line1 이전 라인 * @param line2 현재 라인 + * @param line3 다음 라인 * @param offset * @returns {number} */ - const getLineOffsetPoint = (line1, line2, offset) => { - if (line1.x1 !== line2.x1 && line1.y1 !== line2.y1) { - } + const getLineOffsetPoint = (line1, line2, line3, offset) => { //밑변 - let a = Math.abs(line1.x1 - line2.x1) + let a = Math.abs(line1.x - line2.x) //빗변 - let c = Math.sqrt(Math.abs(line1.x1 - line2.x2) ** 2 + Math.abs(line1.y1 - line2.y2) ** 2) + let c = Math.sqrt(Math.abs(line1.x - line2.x) ** 2 + Math.abs(line1.y - line2.y) ** 2) + + console.log(a, c) //밑변과 빗변사이의 각도 - let alphaDegree = getDegreeBetweenTwoLines(line1, line2) + let alphaDegree = getDegreeBetweenTwoLines(line1, line2, line3) alphaDegree = alphaDegree <= 90 ? alphaDegree : 180 - alphaDegree alphaDegree = 90 - alphaDegree + console.log('alphaDegree : ', alphaDegree) - return Math.round(offset * Math.tan(alphaDegree * (Math.PI / 180))) + // console.log('Math.tan(alphaDegree * (Math.PI / 180)) : ', Math.tan(alphaDegree * (Math.PI / 180))) + console.log(Math.round(offset * Math.tan(alphaDegree * (Math.PI / 180)))) + + const angle = getDegreeBetweenTwoLines(line1, line2, line3) + const side1 = line1.length + const side2 = line2.length + const side3 = Math.sqrt(side1 ** 2 + side2 ** 2 - 2 * side1 * side2 * Math.cos(angle * (Math.PI / 180))) + const beta = Math.round(Math.asin((side2 * Math.sin(angle * (Math.PI / 180))) / side3) * (180 / Math.PI) * 10) / 10 + const alpha = 180 - angle - beta + + console.log('angle : ', angle, 'alpha : ', alpha, 'beta : ', beta) + + const h = side2 * Math.sin(alpha * (Math.PI / 180)) + const h_new = h + offset + console.log('빗변까지 길이 : ', h, 'offset 적용된 빗변까지 길이 : ', h_new) + const newAdjacent = h_new / Math.sin(angle * (Math.PI / 180)) + console.log('offset 적용된 밑변 : ', newAdjacent) + + // offset = Math.sqrt(diffAdjacent ** 2 + diffAdjacent ** 2) / 2 + console.log('offset : ', offset) + return offset } /** * 구하려는 라인의 x1,y1좌표가 기준 * @param line1 이전 라인 * @param line2 현재 라인 + * @param line3 다음 라인 * @returns {number} */ - const getDegreeBetweenTwoLines = (line1, line2) => { - let x1 = line1.x1, - x2 = line2.x1, - x3 = line2.x2 - let y1 = line1.y1, - y2 = line2.y1, - y3 = line2.y2 + const getDegreeBetweenTwoLines = (line1, line2, line3) => { + console.log('getDegreeBetweenTwoLines 확인 ==========') + console.log(line1, line2, line3) + let x1 = line1.x, + x2 = line2.x, + x3 = line3.x + let y1 = line1.y, + y2 = line2.y, + y3 = line3.y // 각 점 사이의 벡터 계산 const vector1 = { x: x1 - x2, y: y1 - y2 } @@ -1489,6 +1534,7 @@ export function useMode() { // 라디안에서 도 단위로 변환 angle = angle * (180 / Math.PI) + console.log('angel : ', angle) return angle } diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 5742396e..7aefb07b 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1,6 +1,6 @@ import { fabric } from 'fabric' import { QLine } from '@/components/fabric/QLine' -import { distanceBetweenPoints, findClosestPoint, getRoofHypotenuse } from '@/util/canvas-util' +import { distanceBetweenPoints, findClosestPoint, getAdjacent, getRoofHypotenuse } from '@/util/canvas-util' export const defineQPloygon = () => { fabric.QPolygon = fabric.util.createClass(fabric.Group, {}) @@ -384,7 +384,8 @@ const calculateTriangleArea = (point1, point2, point3) => { export const drawHippedRoof = (polygon, chon) => { drawRoofRidge(polygon) - drawHips(polygon) + // drawHips(polygon) + // connectLinePoint(polygon) } /*마루 그리기 외벽의 모양이 돌출된 ㄷ의 형태일때 @@ -394,244 +395,450 @@ export const drawHippedRoof = (polygon, chon) => { 다만 마루의 길이는 나머지 나머지 두 지붕의 길이중 짧은선의 길이를 넘어갈수 없다. */ const drawRoofRidge = (polygon) => { - let prevLine, currentLine, nextLine, prevWall, currentWall, nextWall - let startXPoint, startYPoint, endXPoint, endYPoint - let dVector, ridgeMaxLength, ridgeMinLength, ridgeRun - + const lines = polygon.wall.lines polygon.lines.forEach((value, index) => { + let currentLine, prevWall, currentWall, nextWall + let startXPoint, startYPoint, endXPoint, endYPoint if (index === 0) { - prevLine = polygon.lines[polygon.lines.length - 1] prevWall = polygon.wall.lines[polygon.wall.lines.length - 1] } else { - prevLine = polygon.lines[index - 1] prevWall = polygon.wall.lines[index - 1] } currentLine = polygon.lines[index] currentWall = polygon.wall.lines[index] if (index === polygon.lines.length - 1) { - nextLine = polygon.lines[0] nextWall = polygon.wall.lines[0] } else if (index === polygon.lines.length) { - nextLine = polygon.lines[1] nextWall = polygon.wall.lines[1] } else { - nextLine = polygon.lines[index + 1] nextWall = polygon.wall.lines[index + 1] } - console.log(polygon.lines) - // let ridgeBaseLine = polygon.lines.filter((line) => line.idx === currentLine.idx)[0] - - // if (this.getLineDirection(prevLine) !== this.getLineDirection(nextLine) && currentWall.length < currentLine.length) { if (getLineDirection(prevWall) !== getLineDirection(nextWall) && currentWall.length < currentLine.length) { - dVector = getDirectionForDegree(prevWall, currentWall) - let { minLineLength, currentLineLength, maxLineLength } = getRoofBaseLine(polygon, prevWall, currentWall, nextWall, dVector) + 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) - console.log('currentLine.length : ' + currentWall.length) - // 마루는 세개의 벽중에서 가장 길 수 없다. - console.log('currentLineLength : ', currentLineLength, 'minLineLength : ', minLineLength, 'maxLineLength : ', maxLineLength) - console.log('minLineLength <= currentLineLength <= maxLineLength', minLineLength <= currentLineLength && currentLineLength <= maxLineLength) + let lineCoordinate = [ + { x: minX, y: minY }, + { x: minX, y: maxY }, + { x: maxX, y: maxY }, + { x: maxX, y: minY }, + ] - if (currentLineLength <= maxLineLength) { - // console.log('currentLine.length : ' + currentLine.length) - ridgeMaxLength = Math.min(minLineLength, maxLineLength) - ridgeMinLength = Math.max(minLineLength, maxLineLength) - currentLineLength - ridgeRun = Math.min(ridgeMinLength, ridgeMaxLength) - // console.log(ridgeRun) - switch (dVector) { - case 45: - startXPoint = currentWall.x1 + currentLineLength / 2 - startYPoint = currentWall.y1 - currentLineLength / 2 - endXPoint = startXPoint - endYPoint = startYPoint - ridgeRun - break - case 135: - startXPoint = currentWall.x1 + currentLineLength / 2 - startYPoint = currentWall.y1 + currentLineLength / 2 - endXPoint = startXPoint + ridgeRun - endYPoint = startYPoint - break - case 225: - startXPoint = currentWall.x1 - currentLineLength / 2 - startYPoint = currentWall.y1 + currentLineLength / 2 - endXPoint = startXPoint - endYPoint = startYPoint + ridgeRun - break - case 315: - startXPoint = currentWall.x1 - currentLineLength / 2 - startYPoint = currentWall.y1 - currentLineLength / 2 - endXPoint = startXPoint - ridgeRun - endYPoint = startYPoint - break - } - - let isDuplicate = false - polygon.ridges.forEach((ridge) => { - if ( - ridge.x1 === Math.min(startXPoint, endXPoint) && - ridge.y1 === Math.min(startYPoint, endYPoint) && - ridge.x2 === Math.max(startXPoint, endXPoint) && - ridge.y2 === Math.max(startYPoint, endYPoint) - ) { - isDuplicate = true + let innerPointLine = lines + .filter((line) => { + if (getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { + return line } }) + .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) - if (!isDuplicate && polygon.ridges.length < getMaxRidge(polygon.lines.length)) { - const ridge = new QLine( - [Math.min(startXPoint, endXPoint), Math.min(startYPoint, endYPoint), Math.max(startXPoint, endXPoint), Math.max(startYPoint, endYPoint)], - { - fontSize: polygon.fontSize, - stroke: 'blue', - strokeWidth: 1, - }, - ) - polygon.canvas.add(ridge) - polygon.ridges.push(ridge) - polygon.innerLines.push(ridge) + let acrossLine = lines + .filter((line) => { + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + return line.direction === 'top' || line.direction === 'bottom' + } + 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 (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 + } + } + if (currentWall.direction === 'left' || currentWall.direction === 'right') { + 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 + } + } + return prev + } else { + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + 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 (prevWall.direction === 'top' && currentWall.y1 < current.y1) { + return current + } + if (prevWall.direction === 'bottom' && currentWall.y1 > current.y1) { + return current + } + } + } + }, undefined) + + let ridgeLengthToWall, ridgeBaseLength, ridgeLengthToAcrossLine, ridgeMaxLength + + if (innerPointLine !== undefined) { + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + if (innerPointLine.y1 === innerPointLine.y2) { + 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, Math.abs(currentWall.x1 - acrossLine.x1)) - ridgeBaseLength + 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)) + } + 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 = currentWall.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 === 'right' || currentWall.direction === 'left') { + 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) + 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)) + } + 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 { + ridgeBaseLength = currentWall.length + ridgeLengthToWall = Math.min(prevWall.length, nextWall.length) + ridgeMaxLength = Math.max(prevWall.length, nextWall.length) + if (currentWall.direction === 'top' || currentWall.direction === 'bottom') { + ridgeLengthToAcrossLine = Math.abs(acrossLine.x1 - currentWall.x1) - ridgeBaseLength + 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 + 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 ( + // polygon.ridges.length < getMaxRidge(lines.length) && + ridgeBaseLength <= ridgeMaxLength && + 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)], + { + fontSize: polygon.fontSize, + stroke: 'blue', + strokeWidth: 1, + }, + ) + polygon.canvas.add(ridge) + polygon.ridges.push(ridge) + polygon.innerLines.push(ridge) } } }) + //중복 제거 + polygon.ridges = polygon.ridges.filter((ridge, index, self) => index === self.findIndex((t) => t.x1 === ridge.x1 && t.y1 === ridge.y1)) } - 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.x1 !== ridge.x2 && ridge.y1 === ridge.y2) { - // console.log('가로방향 마루') + 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)) .reduce((prev, current) => { - if (prev <= 0) { + if (prev === undefined) { return current } else { return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev } - }, []) + }, undefined) leftBottom = polygon.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) { + if (prev === undefined) { return current } else { return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev } - }, []) + }, undefined) //오른쪽 좌표 기준 45, 135도 방향 라인확인 rightTop = polygon.lines .filter((line) => line.x1 > ridge.x2 && line.y1 < ridge.y2 && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) .reduce((prev, current) => { - if (prev <= 0) { + if (prev === undefined) { return current } else { return Math.min(current.x1 - ridge.x2) < Math.min(prev.x1 - ridge.x2) ? current : prev } - }, []) + }, undefined) rightBottom = polygon.lines .filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2 && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) .reduce((prev, current) => { - if (prev <= 0) { + if (prev === undefined) { return current } else { return Math.min(current.x1 - ridge.x2) < Math.min(prev.x1 - ridge.x2) ? current : prev } - }, []) - - if (leftTop.length > 0) { + }, undefined) + if (leftTop !== undefined) { const hip = new QLine([leftTop.x1, leftTop.y1, ridge.x1, ridge.y1], { fontSize: polygon.fontSize, stroke: 'red', strokeWidth: 1, }) - this.addWithUpdate(hip) - this.hips.push(hip) - this.innerLines.push(hip) + polygon.canvas.add(hip) + polygon.hips.push(hip) + polygon.innerLines.push(hip) } - if (leftBottom.length > 0) { + if (leftBottom !== undefined) { const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x1, ridge.y1], { fontSize: polygon.fontSize, stroke: 'red', strokeWidth: 1, }) polygon.canvas.add(hip) - this.hips.push(hip) - this.innerLines.push(hip) + polygon.hips.push(hip) + polygon.innerLines.push(hip) } - if (rightTop.length > 0) { + if (rightTop !== undefined) { const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x2, ridge.y2], { fontSize: polygon.fontSize, stroke: 'red', strokeWidth: 1, }) polygon.canvas.add(hip) - this.hips.push(hip) - this.innerLines.push(hip) + polygon.hips.push(hip) + polygon.innerLines.push(hip) } - if (rightBottom.length > 0) { + if (rightBottom !== undefined) { const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], { fontSize: polygon.fontSize, stroke: 'red', strokeWidth: 1, }) polygon.canvas.add(hip) - this.hips.push(hip) - this.innerLines.push(hip) + polygon.hips.push(hip) + polygon.innerLines.push(hip) } } - if (ridge.y1 !== ridge.y2 && ridge.x1 === ridge.x2) { - // console.log('세로방향 마루') + if (ridge.x1 === ridge.x2) { + console.log('세로방향 마루') //위쪽 좌표 기준 45, 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)) .reduce((prev, current) => { - if (prev <= 0) { + if (prev === undefined) { return current } else { return Math.min(ridge.y1 - current.y1) < Math.min(ridge.y1 - prev.y1) ? current : prev } - }, []) + }, undefined) rightTop = polygon.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) { + if (prev === undefined) { return current } else { return Math.min(ridge.y1 - current.y1) < Math.min(ridge.y1 - prev.y1) ? current : prev } - }, []) + }, undefined) //아래쪽 좌표 기준 135, 225도 방향 라인확인 leftBottom = polygon.lines .filter((line) => line.x1 < ridge.x2 && line.y1 > ridge.y2 && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) .reduce((prev, current) => { - if (prev <= 0) { + if (prev === undefined) { return current } else { return Math.min(current.y1 - ridge.y2) < Math.min(prev.y1 - ridge.y2) ? current : prev } - }, []) + }, undefined) rightBottom = polygon.lines .filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2 && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) .reduce((prev, current) => { - if (prev.length <= 0) { + if (prev === undefined) { return current } else { return Math.min(current.y1 - ridge.y2) < Math.min(prev.y1 - ridge.y2) ? current : prev } - }, []) + }, undefined) - if (leftTop.length > 0) { + if (leftTop !== undefined) { const hip = new QLine([leftTop.x1, leftTop.y1, ridge.x1, ridge.y1], { fontSize: polygon.fontSize, stroke: 'red', @@ -641,9 +848,9 @@ const drawHips = (polygon) => { polygon.hips.push(hip) polygon.innerLines.push(hip) } - if (rightTop.length > 0) { + if (rightTop !== undefined) { const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x1, ridge.y1], { - fontSize: this.fontSize, + fontSize: polygon.fontSize, stroke: 'red', strokeWidth: 1, }) @@ -651,7 +858,7 @@ const drawHips = (polygon) => { polygon.hips.push(hip) polygon.innerLines.push(hip) } - if (leftBottom.length > 0) { + if (leftBottom !== undefined) { const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x2, ridge.y2], { fontSize: polygon.fontSize, stroke: 'red', @@ -661,7 +868,7 @@ const drawHips = (polygon) => { polygon.hips.push(hip) polygon.innerLines.push(hip) } - if (rightBottom.length > 0) { + if (rightBottom !== undefined) { const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], { fontSize: polygon.fontSize, stroke: 'red', @@ -674,6 +881,8 @@ const drawHips = (polygon) => { } }) + console.log('polygon.hips : ', polygon.hips) + // 가장 가까운 마루를 확인하여 그릴 수 있는 라인이 존재하면 먼저 그린다. let prevLine, currentLine, nextLine polygon.lines.forEach((value, index) => { @@ -1058,6 +1267,8 @@ const getRoofBaseLine = (polygon, prevLine, currentLine, nextLine, dVector) => { let coordinateLength let innerPointX + console.log('innerPointLine : ', innerPointLine) + if (innerPointLine.length > 0) { innerPointX = innerPointLine.reduce((a, b) => { return a.x1 < b.x1 ? a : b @@ -1207,19 +1418,19 @@ const connectLinePoint = (polygon) => { // 연결되지 않은 모든 라인의 포인트를 구한다. let missedPoints = [] //마루 - this.ridges.forEach((ridge) => { - if (this.hips.filter((hip) => hip.x2 === ridge.x1 && hip.y2 === ridge.y1).length < 2) { + polygon.ridges.forEach((ridge) => { + if (polygon.hips.filter((hip) => hip.x2 === ridge.x1 && hip.y2 === ridge.y1).length < 2) { missedPoints.push({ x: ridge.x1, y: ridge.y1 }) } - if (this.hips.filter((hip) => hip.x2 === ridge.x2 && hip.y2 === ridge.y2).length < 2) { + if (polygon.hips.filter((hip) => hip.x2 === ridge.x2 && hip.y2 === ridge.y2).length < 2) { missedPoints.push({ x: ridge.x2, y: ridge.y2 }) } }) //추녀마루 - this.hips.forEach((hip) => { + polygon.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 + count += polygon.ridges.filter((ridge) => (ridge.x1 === hip.x2 && ridge.y1 === hip.y2) || (ridge.x2 === hip.x2 && ridge.y2 === hip.y2)).length + count += polygon.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 }) @@ -1265,20 +1476,20 @@ const connectLinePoint = (polygon) => { missedLine.forEach((p, index) => { const line = new QLine([p.x1, p.y1, p.x2, p.y2], { - fontSize: this.fontSize, + fontSize: polygon.fontSize, stroke: 'green', strokeWidth: 1, }) polygon.canvas.add(line) - this.innerLines.push(line) + polygon.innerLines.push(line) }) missedPoints = [] missedLine = [] - this.innerLines.forEach((line, index) => { + polygon.innerLines.forEach((line, index) => { if ( - this.innerLines.filter( + polygon.innerLines.filter( (innerLine) => (line.x2 === innerLine.x1 && line.y2 === innerLine.y1) || (line.x2 === innerLine.x2 && line.y2 === innerLine.y2), ).length < 3 ) { @@ -1327,12 +1538,12 @@ const connectLinePoint = (polygon) => { missedLine.forEach((p, index) => { const line = new QLine([p.x1, p.y1, p.x2, p.y2], { - fontSize: this.fontSize, + fontSize: polygon.fontSize, stroke: 'purple', strokeWidth: 1, }) polygon.canvas.add(line) - this.innerLines.push(line) + polygon.innerLines.push(line) }) }