From 9be2c65b329d1d191ff0089c70d6b83904f2390b Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Thu, 1 Aug 2024 14:02:14 +0900 Subject: [PATCH] add dev --- src/util/qpolygon-utils.js | 1205 ++++++++++++++++++------------------ 1 file changed, 618 insertions(+), 587 deletions(-) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 5fe55ecd..8ac91eed 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1,15 +1,14 @@ import { fabric } from 'fabric' -import QPolygon from '@/components/fabric/QPolygon3' import { QLine } from '@/components/fabric/QLine' -import { calculateIntersection2, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' +import { distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util' export const defineQPloygon = () => { fabric.QPolygon = fabric.util.createClass(fabric.Group, {}) // fromObject 메서드를 QLine 클래스에 직접 추가 - fabric.QPolygon.fromObject = function(object, callback) { + fabric.QPolygon.fromObject = function (object, callback) { const { initOption, initPoints, initLengthTxt } = object - fabric.util.enlivenObjects(object.objects, function(enlivenedObjects) { + fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) { return callback(new QPolygon(initPoints, object, initLengthTxt)) }) } @@ -17,275 +16,237 @@ export const defineQPloygon = () => { export const drawHelpLineInHexagon = (polygon, chon) => { const centerLines = drawCenterLines(polygon) + let helpLines = [] + const interSectionPoints = [] + const tempInterSectionPoints = [] + const ridgeStartPoints = [] const ridgeEndPoints = [] const centerInterSectionPoints = [] - let maxLength = 0 - - polygon.lines = polygon.lines.sort((a, b) => a.length - b.length) + // polygon.lines = polygon.lines.sort((a, b) => a.length - b.length) polygon.wall.lines = getOneSideLines(polygon.wall) - // 짧은 라인 순서대로 삼각 지붕을 그린다. - polygon.lines.forEach((line, index) => { - if (line.length > maxLength) { - maxLength = line.length - } - const wallLine = polygon.wall.lines.filter((wallLine) => wallLine.idx === line.idx)[0] + const maxLength = Math.max(...polygon.lines.map((line) => line.length)) - const checkPoint1 = polygon.points.filter((point) => point.x === line.x1 && point.y === line.y1)[0] - const checkPoint2 = polygon.points.filter((point) => point.x === line.x2 && point.y === line.y2)[0] - - if (checkPoint1.alreadyIntersected || checkPoint2.alreadyIntersected) { - return - } - - const angle1 = Math.atan2(wallLine.y1 - line.y1, wallLine.x1 - line.x1) - const angle2 = Math.atan2(wallLine.y2 - line.y2, wallLine.x2 - line.x2) - - // line을 이등변 삼각형의 밑변으로 보고 높이를 구한다. - - const helpLineLength = Math.sqrt(2 * Math.pow(line.length / 2, 2)) - - const firstX2 = Math.floor(line.x1 + helpLineLength * Math.cos(angle1)) - const firstY2 = Math.floor(line.y1 + helpLineLength * Math.sin(angle1)) - - const secondX2 = Math.floor(line.x2 + helpLineLength * Math.cos(angle2)) - const secondY2 = Math.floor(line.y2 + helpLineLength * Math.sin(angle2)) - - const firstHelpLine = new QLine([line.x1, line.y1, firstX2, firstY2], { - fontSize: polygon.fontSize, - stroke: 'skyblue', - }) - - const secondHelpLine = new QLine([line.x2, line.y2, secondX2, secondY2], { - fontSize: polygon.fontSize, - stroke: 'skyblue', - }) - - const interSectionPoint = calculateIntersection2(firstHelpLine, secondHelpLine) - - if (interSectionPoint) { - if (polygon.inPolygon(interSectionPoint) && polygon.wall.inPolygon(interSectionPoint)) { - checkPoint1.alreadyIntersected = true - checkPoint2.alreadyIntersected = true - - const helpLine1 = new QLine([line.x1, line.y1, interSectionPoint.x, interSectionPoint.y], { - fontSize: polygon.fontSize, - stroke: 'skyblue', - }) - - const helpLine2 = new QLine([line.x2, line.y2, interSectionPoint.x, interSectionPoint.y], { - fontSize: polygon.fontSize, - stroke: 'skyblue', - }) - - helpLines.push(helpLine1) - helpLines.push(helpLine2) - - polygon.canvas.add(helpLine1) - polygon.canvas.add(helpLine2) - - ridgeStartPoints.push(interSectionPoint) - } - } - - polygon.canvas.renderAll() - }) - // points를 순회하면서 이미 그려진 점이 아닌 경우 centerLine과 만나는 점을 찾는다. polygon.points.forEach((point, index) => { - if (point.alreadyIntersected) { - return - } - const wallPoint = polygon.wall.points[index] const angle = Math.atan2(wallPoint.y - point.y, wallPoint.x - point.x) - const newX2 = Math.floor(point.x + (maxLength / 2 + 50) * Math.cos(angle)) - const newY2 = Math.floor(point.y + (maxLength / 2 + 50) * Math.sin(angle)) + const degree = fabric.util.radiansToDegrees(angle) + + const newX2 = Math.floor(point.x + maxLength * Math.cos(angle)) + const newY2 = Math.floor(point.y + maxLength * Math.sin(angle)) const helpLine = new QLine([point.x, point.y, newX2, newY2], { fontSize: polygon.fontSize, stroke: 'green', + startPoint: point, + degree: degree, + idx: index, }) - const relatedPoints = [] + // polygon.canvas?.add(helpLine) - centerLines.forEach((centerLine) => { - const interSectionPoint = calculateIntersection2(helpLine, centerLine) - - if (interSectionPoint) { - if (polygon.inPolygon(interSectionPoint) && polygon.wall.inPolygon(interSectionPoint)) { - relatedPoints.push(interSectionPoint) - - centerInterSectionPoints.push(interSectionPoint) - } - } - }) - - helpLine.set({ relatedPoints: relatedPoints }) helpLines.push(helpLine) }) - helpLines = helpLines.filter((line) => line.relatedPoints?.length > 0) + helpLines.forEach((line, index) => { + for (let i = index + 1; i < helpLines.length; i++) { + const nextLine = helpLines[i] + if (!line.connectedPoint) { + line.connectedPoint = null + line.connectedPoints = [] + } + if (!nextLine.connectedPoint) { + nextLine.connectedPoint = null + nextLine.connectedPoints = [] + } - ridgeStartPoints.forEach((point) => { - point.alreadyIntersected = false - // x 혹은 y가 같으면서 가장 가까운 점을 찾는다. - let arrivalPoint - let hipLine - let distance = Infinity - let startPoint - helpLines.forEach((line) => { - line.relatedPoints.forEach((relatedPoint) => { - if (Math.abs(point.x - relatedPoint.x) <= 2 || Math.abs(point.y - relatedPoint.y) <= 2) { - if (distanceBetweenPoints(point, relatedPoint) < distance) { - startPoint = point - distance = distanceBetweenPoints(point, relatedPoint) - hipLine = line - arrivalPoint = relatedPoint - } + const interSectionPoint = calculateIntersection(line, nextLine) + + if ( + interSectionPoint && + polygon.inPolygon(interSectionPoint) && + polygon.wall.inPolygon(interSectionPoint) && + Math.abs(distanceBetweenPoints(line.startPoint, interSectionPoint) - distanceBetweenPoints(nextLine.startPoint, interSectionPoint)) < 2 + ) { + const area = calculateTriangleArea(line.startPoint, nextLine.startPoint, interSectionPoint) + const currentLineConnectedPoint = line.connectedPoint + const nextLineConnectedPoint = nextLine.connectedPoint + + if (area <= 1) { + return } - }) - }) - if (arrivalPoint) { - hipLine.relatedPoints.forEach((relatedPoint) => { - if (relatedPoint.x !== arrivalPoint.x && relatedPoint.y !== arrivalPoint.y) { - centerInterSectionPoints.splice(centerInterSectionPoints.indexOf(relatedPoint), 1) + if (currentLineConnectedPoint && currentLineConnectedPoint.area < area) { + return } - }) - helpLines.splice(helpLines.indexOf(hipLine), 1) + //startPoint는 line의 startPoint와 nextLine의 startPoint를 비교하여 x가 같은경우 y가 더 작은 값, y가 같은경우 x가 더 작은 값을 선택한다. + const startPoint = + line.startPoint.x === nextLine.startPoint.x + ? line.startPoint.y < nextLine.startPoint.y + ? line.startPoint + : nextLine.startPoint + : line.startPoint.x < nextLine.startPoint.x + ? line.startPoint + : nextLine.startPoint - const helpLine = new QLine([hipLine.x1, hipLine.y1, arrivalPoint.x, arrivalPoint.y], { - fontSize: polygon.fontSize, - stroke: 'red', - }) - const ridge = new QLine([startPoint.x, startPoint.y, arrivalPoint.x, arrivalPoint.y], { - stroke: 'green', - fontSize: polygon.fontSize, - }) + const endPoint = + line.startPoint.x === nextLine.startPoint.x + ? line.startPoint.y > nextLine.startPoint.y + ? line.startPoint + : nextLine.startPoint + : line.startPoint.x > nextLine.startPoint.x + ? line.startPoint + : nextLine.startPoint - polygon.canvas.add(helpLine) - polygon.canvas.add(ridge) - - polygon.canvas.renderAll() - ridgeEndPoints.push(arrivalPoint) - - point.alreadyIntersected = true + line.connectedPoint = { interSectionPoint, area, startPoint, endPoint } + line.connectedPoints.push(interSectionPoint) + nextLine.connectedPoint = { interSectionPoint, area, startPoint, endPoint } + nextLine.connectedPoints.push(interSectionPoint) + } } }) - /** - * 안쓰는 점 제거 - */ - - const ridgeEndRemainingPoints = [...ridgeEndPoints] - - const uniqueInterSectionPoints = Array.from(new Set(centerInterSectionPoints.map((point) => `${point.x},${point.y}`))).map((key) => { - const [x, y] = key.split(',').map(Number) - return { x, y } + helpLines.forEach((line) => { + if (line.connectedPoint) { + tempInterSectionPoints.push(line.connectedPoint) + } }) - while (ridgeEndRemainingPoints.length > 0) { - const point = ridgeEndRemainingPoints.shift() - let isExist = false - uniqueInterSectionPoints.forEach((uniquePoint) => { - const degree = calculateAngle(point, uniquePoint) + // interSectionPoints에서 interSectionPoint가 중복인 값이 있는 경우만 선택한다. + tempInterSectionPoints.forEach((point) => { + // intersectionPoint가 중복인 경우 + const isDuplicated = + tempInterSectionPoints.filter((p) => p.interSectionPoint.x === point.interSectionPoint.x && p.interSectionPoint.y === point.interSectionPoint.y) + .length > 1 + if (isDuplicated) { + interSectionPoints.push(point) + } + }) - if (Math.abs(45 - Math.abs(degree)) <= 5 || Math.abs(135 - Math.abs(degree)) <= 5) { - const line = new QLine([point.x, point.y, uniquePoint.x, uniquePoint.y], { - stroke: 'purple', - fontSize: polygon.fontSize, - }) + // interSectionPoints에서 interSectionPoint 기준으로 중복을 제거한다. + const uniqueInterSectionPoints = Array.from( + new Set(interSectionPoints.map((point) => `${point.interSectionPoint.x},${point.interSectionPoint.y}`)), + ).map((key) => { + const { interSectionPoint, area, startPoint, endPoint } = interSectionPoints.find( + (point) => `${point.interSectionPoint.x},${point.interSectionPoint.y}` === key, + ) + return { interSectionPoint, area, startPoint, endPoint } + }) - ridgeEndPoints.push(uniquePoint) + uniqueInterSectionPoints.forEach((point) => { + ridgeStartPoints.push(point.interSectionPoint) - ridgeEndPoints.splice(ridgeEndPoints.indexOf(point), 1) - - isExist = true - - polygon.canvas.add(line) - polygon.canvas.renderAll() - } - - if (isExist) { - return - } - }) - } - - const ridgeEndRemainingPoints2 = [...ridgeEndPoints] - - while (ridgeEndRemainingPoints2.length > 0) { - // 남아있는 점끼리 연결한다. - const point = ridgeEndRemainingPoints2.shift() - const closestPoint = findClosestPoint(point, ridgeEndRemainingPoints2) - if (!closestPoint) continue - const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], { + const line = new QLine([point.startPoint.x, point.startPoint.y, point.interSectionPoint.x, point.interSectionPoint.y], { stroke: 'purple', fontSize: polygon.fontSize, + name: 'hip', }) + const line2 = new QLine([point.endPoint.x, point.endPoint.y, point.interSectionPoint.x, point.interSectionPoint.y], { + stroke: 'purple', + fontSize: polygon.fontSize, + name: 'hip', + }) + + polygon.hips.push(line) + polygon.hips.push(line2) + polygon.canvas.add(line) - polygon.canvas.renderAll() - } + polygon.canvas.add(line2) + }) + + const removedIdx = [] - // ridgeEndPoints와 가까운 centerInterSectionPoints를 찾아서 연결한다. - const remainingPoints = centerInterSectionPoints - /* helpLines.forEach((line) => { - remainingPoints.forEach((point) => { - if (line.relatedPoints.includes(point)) { - const hip = new QLine([line.x1, line.y1, point.x, point.y], { - stroke: 'red', - fontSize: polygon.fontSize, - }) + const connectedPoints = line.connectedPoints + connectedPoints.forEach((connectedPoint) => { + uniqueInterSectionPoints.forEach((point) => { + const interSectionPoint = point.interSectionPoint - polygon.canvas.add(hip) - polygon.canvas.renderAll() + if (connectedPoint.x === interSectionPoint.x && connectedPoint.y === interSectionPoint.y) { + removedIdx.push(line.idx) + } + }) + }) + }) + + const notIntersectedLines = helpLines.filter((line) => !removedIdx.includes(line.idx)) + + notIntersectedLines.forEach((line) => { + centerLines.forEach((centerLine) => { + const interSectionPoint = calculateIntersection(line, centerLine) + + if (interSectionPoint && polygon.inPolygon(interSectionPoint) && polygon.wall.inPolygon(interSectionPoint)) { + centerInterSectionPoints.push(interSectionPoint) } }) }) + // centerInterSectionPoints에서 ridgeStartPoints와 x가 같거나 y가 같은것중 가장 가까운 점들을 찾는다. + ridgeStartPoints.forEach((point) => { + const xPoints = centerInterSectionPoints.filter((centerPoint) => Math.abs(centerPoint.x - point.x) < 2) + const yPoints = centerInterSectionPoints.filter((centerPoint) => Math.abs(centerPoint.y - point.y) < 2) + let closestPoint + if (xPoints.length === 0) { + closestPoint = findClosestPoint(point, yPoints) + } else { + closestPoint = findClosestPoint(point, xPoints) + } + if (closestPoint) { + const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], { + stroke: 'purple', + fontSize: polygon.fontSize, + name: 'ridge', + }) + polygon.ridges.push(line) + polygon.canvas.add(line) + ridgeEndPoints.push(closestPoint) + } + }) + + // ridgeEndPoints끼리 이어준다. + const remainingPoints = ridgeEndPoints + + remainingPoints.forEach((ridgePoint) => { + polygon.points.forEach((point) => { + const degree = calculateAngle(ridgePoint, point) + + if (Math.abs(degree) % 45 < 1) { + const line = new QLine([ridgePoint.x, ridgePoint.y, point.x, point.y], { + stroke: 'purple', + fontSize: polygon.fontSize, + name: 'hip', + }) + + polygon.hips.push(line) + polygon.canvas.add(line) + } + }) + }) - // centerInterSectionPoints에 남아있는 점들을 가까운 점끼리 연결한다. while (remainingPoints.length > 0) { const point = remainingPoints.shift() const closestPoint = findClosestPoint(point, remainingPoints) if (!closestPoint) continue + // 마루끼리 연결 const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], { stroke: 'purple', fontSize: polygon.fontSize, + name: 'connectRidge', }) + polygon.connectRidges.push(line) polygon.canvas.add(line) - polygon.canvas.renderAll() } - - const notIntersectedRidgeStartPoints = ridgeStartPoints.filter((point) => !point.alreadyIntersected) - // 만나지 않은 마루 시작점 - while (notIntersectedRidgeStartPoints.length > 0) { - const point = notIntersectedRidgeStartPoints.shift() - const closestPoint = findClosestPoint(point, notIntersectedRidgeStartPoints) - if (!closestPoint) continue - const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], { - stroke: 'purple', - fontSize: polygon.fontSize, - }) - - polygon.canvas.add(line) - polygon.canvas.renderAll() - }*/ -} - -export const drawHelpLineInHexagon2 = (polygon, chon) => { } export const drawCenterLines = (polygon) => { @@ -386,10 +347,39 @@ const calculateAngle = (point1, point2) => { return angleInRadians * (180 / Math.PI) } -export const drawHippedRoof = (polygon, chon) => { - drawRoofRidge(polygon, chon) - // drawHips(polygon, chon) - // connectLinePoint() +/** + * 3개의 점을 이용해 직각 이등변 삼각형인지 확인 + * @param point1 + * @param point2 + * @param point3 + * @returns {boolean} + */ +const isRightIsoscelesTriangle = (point1, point2, point3) => { + const distance = (p1, p2) => Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2)) + + const d1 = distance(point1, point2) + const d2 = distance(point2, point3) + const d3 = distance(point3, point1) + + const distances = [d1, d2, d3].sort((a, b) => a - b) + + // Check if the two smaller distances are equal and the largest distance is the hypotenuse + return distances[0] === distances[1] && Math.abs(Math.pow(distances[0], 2) * 2 - Math.pow(distances[2], 2)) < 1 +} + +/** + * 세개의 점으로 삼각형의 넓이를 구한다. + * @param point1 + * @param point2 + * @param point3 + * @returns {number} + */ +const calculateTriangleArea = (point1, point2, point3) => { + const { x: x1, y: y1 } = point1 + const { x: x2, y: y2 } = point2 + const { x: x3, y: y3 } = point3 + + return Math.abs(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)) / 2 } /*마루 그리기 @@ -404,100 +394,102 @@ const drawRoofRidge = (polygon) => { let startXPoint, startYPoint, endXPoint, endYPoint let dVector, ridgeMaxLength, ridgeMinLength, ridgeRun - polygon.lines.forEach( - (value, index) => { - 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] + polygon.lines.forEach((value, index) => { + 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] - } + 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] + 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) + // 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) - console.log('currentLine.length : ' + currentWall.length) - // 마루는 세개의 벽중에서 가장 길 수 없다. - console.log('currentLineLength : ', currentLineLength, 'minLineLength : ', minLineLength, 'maxLineLength : ', maxLineLength) - console.log('minLineLength <= currentLineLength <= maxLineLength', (minLineLength <= currentLineLength && currentLineLength <= maxLineLength)) + console.log('currentLine.length : ' + currentWall.length) + // 마루는 세개의 벽중에서 가장 길 수 없다. + 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) - 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 + 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 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 - } - }) - - 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)], { + 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) - } + }, + ) + polygon.canvas.add(ridge) + polygon.ridges.push(ridge) + polygon.innerLines.push(ridge) } } - }, - ) + } + }) } const drawHips = (polygon) => { @@ -509,8 +501,8 @@ const drawHips = (polygon) => { if (ridge.x1 !== ridge.x2 && ridge.y1 === ridge.y2) { // 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)) + 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) { return current @@ -519,20 +511,19 @@ const drawHips = (polygon) => { } }, []) - leftBottom = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 > ridge.y1 - && Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1)) + leftBottom = 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) { return current } else { return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev } - }, []) //오른쪽 좌표 기준 45, 135도 방향 라인확인 - rightTop = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 < ridge.y2 - && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) + rightTop = this.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) { return current @@ -541,8 +532,8 @@ const drawHips = (polygon) => { } }, []) - rightBottom = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2 - && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) + rightBottom = this.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) { return current @@ -595,8 +586,8 @@ const drawHips = (polygon) => { if (ridge.y1 !== ridge.y2 && ridge.x1 === ridge.x2) { // 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)) + 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) { return current @@ -605,8 +596,8 @@ const drawHips = (polygon) => { } }, []) - rightTop = this.lines.filter((line) => line.x1 > ridge.x1 && line.y1 < ridge.y1 - && Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1)) + rightTop = 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) { return current @@ -616,8 +607,8 @@ const drawHips = (polygon) => { }, []) //아래쪽 좌표 기준 135, 225도 방향 라인확인 - leftBottom = this.lines.filter((line) => line.x1 < ridge.x2 && line.y1 > ridge.y2 - && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) + leftBottom = this.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) { return current @@ -626,8 +617,8 @@ const drawHips = (polygon) => { } }, []) - rightBottom = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2 - && Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2)) + rightBottom = this.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) { return current @@ -681,245 +672,282 @@ const drawHips = (polygon) => { // 가장 가까운 마루를 확인하여 그릴 수 있는 라인이 존재하면 먼저 그린다. 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] + 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 (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 dVector = this.getDirectionForDegree(prevLine, currentLine) + let nearRidge + + switch (dVector) { + case 45: + 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 !== 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 + } 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 { + 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) || (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 !== 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 + } 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 { + 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) || (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 !== 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 + } 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 { + 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) || (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 !== 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 + } 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 { + 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 (!this.isAlreadyHip(currentLine)) { - let dVector = this.getDirectionForDegree(prevLine, currentLine) - let nearRidge + // console.log('nearRidge : ', nearRidge) + + if (nearRidge !== undefined && nearRidge.length > 0) { + let endXPoint, endYPoint + let minX, maxX, minY, maxY switch (dVector) { case 45: - 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 !== 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 - } 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 { - 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) + if ( + currentLine.x1 < nearRidge.x1 && + currentLine.y1 > nearRidge.y1 && + Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1) + ) { + endXPoint = nearRidge.x1 + endYPoint = nearRidge.y1 + minX = Math.min(currentLine.x1, nearRidge.x1) + minY = Math.min(currentLine.y1, nearRidge.y1) + maxX = Math.max(currentLine.x1, nearRidge.x1) + maxY = Math.max(currentLine.y1, nearRidge.y1) + } + if ( + currentLine.x1 < nearRidge.x2 && + currentLine.y1 > nearRidge.y2 && + Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2) + ) { + endXPoint = nearRidge.x2 + endYPoint = nearRidge.y2 + minX = Math.min(currentLine.x1, nearRidge.x2) + minY = Math.min(currentLine.y1, nearRidge.y2) + maxX = Math.max(currentLine.x1, nearRidge.x2) + maxY = Math.max(currentLine.y1, nearRidge.y2) + } break case 135: - 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 !== 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 - } 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 { - 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) + if ( + currentLine.x1 < nearRidge.x1 && + currentLine.y1 < nearRidge.y1 && + Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1) + ) { + endXPoint = nearRidge.x1 + endYPoint = nearRidge.y1 + minX = Math.min(currentLine.x1, nearRidge.x1) + minY = Math.min(currentLine.y1, nearRidge.y1) + maxX = Math.max(currentLine.x1, nearRidge.x1) + maxY = Math.max(currentLine.y1, nearRidge.y1) + } + if ( + currentLine.x1 < nearRidge.x2 && + currentLine.y1 < nearRidge.y2 && + Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2) + ) { + endXPoint = nearRidge.x2 + endYPoint = nearRidge.y2 + minX = Math.min(currentLine.x1, nearRidge.x2) + minY = Math.min(currentLine.y1, nearRidge.y2) + maxX = Math.max(currentLine.x1, nearRidge.x2) + maxY = Math.max(currentLine.y1, nearRidge.y2) + } break case 225: - 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 !== 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 - } 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 { - 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) + if ( + currentLine.x1 > nearRidge.x1 && + currentLine.y1 < nearRidge.y1 && + Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1) + ) { + endXPoint = nearRidge.x1 + endYPoint = nearRidge.y1 + minX = Math.min(currentLine.x1, nearRidge.x1) + minY = Math.min(currentLine.y1, nearRidge.y1) + maxX = Math.max(currentLine.x1, nearRidge.x1) + maxY = Math.max(currentLine.y1, nearRidge.y1) + } + if ( + currentLine.x1 > nearRidge.x2 && + currentLine.y1 < nearRidge.y2 && + Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2) + ) { + endXPoint = nearRidge.x2 + endYPoint = nearRidge.y2 + minX = Math.min(currentLine.x1, nearRidge.x2) + minY = Math.min(currentLine.y1, nearRidge.y2) + maxX = Math.max(currentLine.x1, nearRidge.x2) + maxY = Math.max(currentLine.y1, nearRidge.y2) + } break case 315: - 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 !== 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 - } 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 { - 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) + if ( + currentLine.x1 > nearRidge.x1 && + currentLine.y1 > nearRidge.y1 && + Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1) + ) { + endXPoint = nearRidge.x1 + endYPoint = nearRidge.y1 + minX = Math.min(currentLine.x1, nearRidge.x1) + minY = Math.min(currentLine.y1, nearRidge.y1) + maxX = Math.max(currentLine.x1, nearRidge.x1) + maxY = Math.max(currentLine.y1, nearRidge.y1) + } + if ( + currentLine.x1 > nearRidge.x2 && + currentLine.y1 > nearRidge.y2 && + Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2) + ) { + endXPoint = nearRidge.x2 + endYPoint = nearRidge.y2 + minX = Math.min(currentLine.x1, nearRidge.x2) + minY = Math.min(currentLine.y1, nearRidge.y2) + maxX = Math.max(currentLine.x1, nearRidge.x2) + maxY = Math.max(currentLine.y1, nearRidge.y2) + } break } - // console.log('nearRidge : ', nearRidge) + let lineCoordinate = [ + { x: minX, y: minY }, + { x: minX, y: maxY }, + { x: maxX, y: maxY }, + { x: maxX, y: minY }, + ] - if (nearRidge !== undefined && nearRidge.length > 0) { - let endXPoint, endYPoint - let minX, maxX, minY, maxY - - switch (dVector) { - case 45: - if (currentLine.x1 < nearRidge.x1 && currentLine.y1 > nearRidge.y1 - && Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) { - endXPoint = nearRidge.x1 - endYPoint = nearRidge.y1 - minX = Math.min(currentLine.x1, nearRidge.x1) - minY = Math.min(currentLine.y1, nearRidge.y1) - maxX = Math.max(currentLine.x1, nearRidge.x1) - maxY = Math.max(currentLine.y1, nearRidge.y1) - } - if (currentLine.x1 < nearRidge.x2 && currentLine.y1 > nearRidge.y2 - && Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) { - endXPoint = nearRidge.x2 - endYPoint = nearRidge.y2 - minX = Math.min(currentLine.x1, nearRidge.x2) - minY = Math.min(currentLine.y1, nearRidge.y2) - maxX = Math.max(currentLine.x1, nearRidge.x2) - maxY = Math.max(currentLine.y1, nearRidge.y2) - } - break - case 135: - if (currentLine.x1 < nearRidge.x1 && currentLine.y1 < nearRidge.y1 - && Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) { - endXPoint = nearRidge.x1 - endYPoint = nearRidge.y1 - minX = Math.min(currentLine.x1, nearRidge.x1) - minY = Math.min(currentLine.y1, nearRidge.y1) - maxX = Math.max(currentLine.x1, nearRidge.x1) - maxY = Math.max(currentLine.y1, nearRidge.y1) - } - if (currentLine.x1 < nearRidge.x2 && currentLine.y1 < nearRidge.y2 - && Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) { - endXPoint = nearRidge.x2 - endYPoint = nearRidge.y2 - minX = Math.min(currentLine.x1, nearRidge.x2) - minY = Math.min(currentLine.y1, nearRidge.y2) - maxX = Math.max(currentLine.x1, nearRidge.x2) - maxY = Math.max(currentLine.y1, nearRidge.y2) - } - break - case 225: - if (currentLine.x1 > nearRidge.x1 && currentLine.y1 < nearRidge.y1 - && Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) { - endXPoint = nearRidge.x1 - endYPoint = nearRidge.y1 - minX = Math.min(currentLine.x1, nearRidge.x1) - minY = Math.min(currentLine.y1, nearRidge.y1) - maxX = Math.max(currentLine.x1, nearRidge.x1) - maxY = Math.max(currentLine.y1, nearRidge.y1) - } - if (currentLine.x1 > nearRidge.x2 && currentLine.y1 < nearRidge.y2 - && Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) { - endXPoint = nearRidge.x2 - endYPoint = nearRidge.y2 - minX = Math.min(currentLine.x1, nearRidge.x2) - minY = Math.min(currentLine.y1, nearRidge.y2) - maxX = Math.max(currentLine.x1, nearRidge.x2) - maxY = Math.max(currentLine.y1, nearRidge.y2) - } - break - case 315: - if (currentLine.x1 > nearRidge.x1 && currentLine.y1 > nearRidge.y1 - && Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) { - endXPoint = nearRidge.x1 - endYPoint = nearRidge.y1 - minX = Math.min(currentLine.x1, nearRidge.x1) - minY = Math.min(currentLine.y1, nearRidge.y1) - maxX = Math.max(currentLine.x1, nearRidge.x1) - maxY = Math.max(currentLine.y1, nearRidge.y1) - } - if (currentLine.x1 > nearRidge.x2 && currentLine.y1 > nearRidge.y2 - && Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) { - endXPoint = nearRidge.x2 - endYPoint = nearRidge.y2 - minX = Math.min(currentLine.x1, nearRidge.x2) - minY = Math.min(currentLine.y1, nearRidge.y2) - maxX = Math.max(currentLine.x1, nearRidge.x2) - maxY = Math.max(currentLine.y1, nearRidge.y2) - } - break + let innerPoint = this.lines.filter((line) => { + if (this.getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { + return line } + }) - let lineCoordinate = [ - { x: minX, y: minY }, - { x: minX, y: maxY }, - { x: maxX, y: maxY }, - { x: maxX, y: minY }, - ] - - let innerPoint = this.lines.filter(line => { - if (this.getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { - return line - } + if (innerPoint <= 0) { + const hip = new QLine([currentLine.x1, currentLine.y1, endXPoint, endYPoint], { + fontSize: this.fontSize, + stroke: 'red', + strokeWidth: 1, }) - - if (innerPoint <= 0) { - 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.innerLines.push(hip) - } + this.addWithUpdate(hip) + this.hips.push(hip) + this.innerLines.push(hip) } } - }) + } + }) // 마루와 연결되지 않은 hip을 그린다. console.log('마루와 연결되지 않은 hip') @@ -962,8 +990,10 @@ const drawHips = (polygon) => { 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))) + hypotenuse = Math.min( + Math.round(getRoofHypotenuse(currentLine.length / 2)), + Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2)), + ) } adjacent = getAdjacent(hypotenuse) @@ -1013,7 +1043,7 @@ const getRoofBaseLine = (polygon, prevLine, currentLine, nextLine, dVector) => { { x: maxX, y: minY }, ] - let innerPointLine = polygon.lines.filter(line => { + let innerPointLine = polygon.lines.filter((line) => { if (getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) { return line } @@ -1096,7 +1126,8 @@ const getAcrossLine = (currentLine, dVector) => { 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 @@ -1106,7 +1137,8 @@ const getAcrossLine = (currentLine, dVector) => { }, []) break case 135: - 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 @@ -1116,7 +1148,8 @@ const getAcrossLine = (currentLine, dVector) => { }, []) break case 225: - 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 @@ -1126,7 +1159,8 @@ const getAcrossLine = (currentLine, dVector) => { }, []) break case 315: - 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 @@ -1144,7 +1178,7 @@ const getAcrossLine = (currentLine, dVector) => { */ const isAlreadyHip = (line) => { let isAlreadyHip = false - this.hips.forEach(hip => { + this.hips.forEach((hip) => { if (line.x1 === hip.x1 && line.y1 === hip.y1) { isAlreadyHip = true } @@ -1160,23 +1194,19 @@ const connectLinePoint = () => { // 연결되지 않은 모든 라인의 포인트를 구한다. let missedPoints = [] //마루 - this.ridges.forEach(ridge => { - if (this.hips.filter(hip => hip.x2 === ridge.x1 && hip.y2 === ridge.y1).length < 2) { + this.ridges.forEach((ridge) => { + 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.hips.filter(hip => hip.x2 === ridge.x2 && hip.y2 === ridge.y2).length < 2) { + if (this.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 => { + 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 + 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 }) @@ -1186,19 +1216,21 @@ const connectLinePoint = () => { let missedLine = [] //중복포인트제거 - missedPoints = [ - ...new Set(missedPoints.map((line) => JSON.stringify(line))), - ].map((line) => JSON.parse(line)) + missedPoints = [...new Set(missedPoints.map((line) => JSON.stringify(line)))].map((line) => JSON.parse(line)) - missedPoints.forEach(p1 => { - 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 - } - }, undefined) + missedPoints.forEach((p1) => { + 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 + } + }, 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 }) @@ -1216,9 +1248,7 @@ const connectLinePoint = () => { }) //중복라인제거 - missedLine = [ - ...new Set(missedLine.map((line) => JSON.stringify(line))), - ].map((line) => JSON.parse(line)) + missedLine = [...new Set(missedLine.map((line) => JSON.stringify(line)))].map((line) => JSON.parse(line)) missedLine.forEach((p, index) => { const line = new QLine([p.x1, p.y1, p.x2, p.y2], { @@ -1234,28 +1264,31 @@ const connectLinePoint = () => { missedLine = [] 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) { + 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 }) } }) - missedPoints = [ - ...new Set(missedPoints.map((line) => JSON.stringify(line))), - ].map((line) => JSON.parse(line)) + 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) + 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) @@ -1275,9 +1308,7 @@ const connectLinePoint = () => { }) //중복라인제거 - missedLine = [ - ...new Set(missedLine.map((line) => JSON.stringify(line))), - ].map((line) => JSON.parse(line)) + missedLine = [...new Set(missedLine.map((line) => JSON.stringify(line)))].map((line) => JSON.parse(line)) console.log(missedLine) @@ -1296,7 +1327,7 @@ const connectLinePoint = () => { 최대 생성 마루 갯수 */ const getMaxRidge = (length) => { - return ((length - 4) / 2) + 1 + return (length - 4) / 2 + 1 } /* @@ -1313,22 +1344,22 @@ const getDirectionForDegree = (line1, line2) => { case 'br': vector = 45 break - case 'lb': + case 'lb': vector = 135 break - case 'bl': + case 'bl': vector = 135 break - case 'lt': + case 'lt': vector = 225 break case 'tl': vector = 225 break - case 'rt': + case 'rt': vector = 315 break - case 'tr': + case 'tr': vector = 315 break } @@ -1363,4 +1394,4 @@ const getLineDirection = (line) => { return 'l' } } -} \ No newline at end of file +}