diff --git a/src/hooks/roofcover/useMovementSetting.js b/src/hooks/roofcover/useMovementSetting.js index 558113ff..fc667ec3 100644 --- a/src/hooks/roofcover/useMovementSetting.js +++ b/src/hooks/roofcover/useMovementSetting.js @@ -7,6 +7,7 @@ import { useEvent } from '@/hooks/useEvent' import { useSwal } from '@/hooks/useSwal' import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' import Big from 'big.js' +import { calcLinePlaneSize } from '@/util/qpolygon-utils' //동선이동 형 올림 내림 export function useMovementSetting(id) { @@ -107,6 +108,7 @@ export function useMovementSetting(id) { addCanvasMouseEventListener('mouse:move', mouseMoveEvent) addCanvasMouseEventListener('mouse:down', mouseDownEvent) return () => { + canvas.discardActiveObject() if (FOLLOW_LINE_REF.current != null) { canvas.remove(FOLLOW_LINE_REF.current) FOLLOW_LINE_REF.current = null @@ -366,7 +368,7 @@ export function useMovementSetting(id) { if (target.y1 === target.y2) { checkPoint = { x: midX.toNumber(), y: midY.plus(10).times(value.s).toNumber() } } else { - checkPoint = { x: midX.plus(10).toNumber().times(value.s), y: midY.toNumber() } + checkPoint = { x: midX.plus(10).times(value.s).toNumber(), y: midY.toNumber() } } const inPolygon = wall.inPolygon(checkPoint) @@ -400,18 +402,29 @@ export function useMovementSetting(id) { startPoint: { x: currentLine.x1 + deltaX, y: currentLine.y1 + deltaY }, endPoint: { x: currentLine.x2 + deltaX, y: currentLine.y2 + deltaY }, }) + const currentSize = calcLinePlaneSize({ x1: currentLine.x1, y1: currentLine.y1, x2: currentLine.x2, y2: currentLine.y2 }) + currentLine.attributes.planeSize = currentSize + currentLine.attributes.actualSize = currentSize + const nextOldActualSize = nextLine.attributes.planeSize nextLine.set({ x1: nextLine.x1 + deltaX, y1: nextLine.y1 + deltaY, startPoint: { x: nextLine.x1 + deltaX, y: nextLine.y1 + deltaY }, }) + const nextSize = calcLinePlaneSize({ x1: nextLine.x1, y1: nextLine.y1, x2: nextLine.x2, y2: nextLine.y2 }) + nextLine.attributes.planeSize = nextSize + nextLine.attributes.actualSize = nextSize + const prevOldActualSize = prevLine.attributes.planeSize prevLine.set({ x2: prevLine.x2 + deltaX, y2: prevLine.y2 + deltaY, endPoint: { x: prevLine.x2 + deltaX, y: prevLine.y2 + deltaY }, }) + const prevSize = calcLinePlaneSize({ x1: prevLine.x1, y1: prevLine.y1, x2: prevLine.x2, y2: prevLine.y2 }) + prevLine.attributes.planeSize = prevSize + prevLine.attributes.actualSize = prevSize canvas.renderAll() }) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 788f9d22..8615f7ca 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1915,6 +1915,7 @@ export function useMode() { parentId: roof.id, name: 'baseLine', }) + baseLine.attributes.originPoint = { x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 } roof.wall.baseLines.push(baseLine) canvas.add(baseLine) }) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 17b97840..07ca86e2 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -756,20 +756,43 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { // const eaves = roof.lines.filter((line) => eavesType.includes(line.attributes?.type)) // const gables = roof.lines.filter((line) => gableType.includes(line.attributes?.type)) - /** - * 외벽선 - */ - - const baseLines = wall.baseLines - const wallLines = wall.lines - console.log('wallLines :', wallLines) + /** 외벽선 */ + const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0) const baseLinePoints = baseLines.map((line) => ({ x: line.x1, y: line.y1 })) - console.log('지붕 마루 갯수 확인 : ', getMaxRidge(baseLines.length), baseLinePoints) - - /** - * baseLine을 기준으로 확인용 polygon 작성 + /** 모양 판단을 위한 라인 처리. + * 평행한 라인이 나누어져 있는 경우 하나의 선으로 판단 한다. */ + const drawBaseLines = [] + baseLines.forEach((currentLine, index) => { + let nextLine = baseLines[(index + 1) % baseLines.length] + let prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length] + const currentAngle = calculateAngle(currentLine.startPoint, currentLine.endPoint) + const nextAngle = calculateAngle(nextLine.startPoint, nextLine.endPoint) + const prevAngle = calculateAngle(prevLine.startPoint, prevLine.endPoint) + + let { x1, y1, x2, y2 } = currentLine + + if (currentAngle !== prevAngle) { + if (currentAngle === nextAngle) { + let nextIndex = baseLines.findIndex((line) => line === nextLine) + while (nextIndex !== index) { + const checkNextLine = baseLines[(nextIndex + 1 + baseLines.length) % baseLines.length] + const checkAngle = calculateAngle(checkNextLine.startPoint, checkNextLine.endPoint) + if (currentAngle !== checkAngle) { + x2 = checkNextLine.x1 + y2 = checkNextLine.y1 + break + } else { + nextIndex = nextIndex + 1 + } + } + } + drawBaseLines.push({ x1, y1, x2, y2, line: currentLine, size: calcLinePlaneSize({ x1, y1, x2, y2 }) }) + } + }) + + /** baseLine을 기준으로 확인용 polygon 작성 */ const checkWallPolygon = new QPolygon(baseLinePoints, {}) /** @@ -790,23 +813,24 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const drawEavesFirstLines = [] const drawEavesSecondLines = [] - /** - * 모양을 판단하여 그린다. - */ - baseLines.forEach((currentLine, index) => { - /** - * 현재 라인이 처마유형일 경우 - */ + /** 모양을 판단한다. */ + drawBaseLines.forEach((currentBaseLine, index) => { + let prevBaseLine = drawBaseLines[(index - 1 + drawBaseLines.length) % drawBaseLines.length] + let nextBaseLine = drawBaseLines[(index + 1) % drawBaseLines.length] + console.log('currentLine :', currentBaseLine) + console.log('prevLine :', prevBaseLine) + console.log('nextLine :', nextBaseLine) + const currentLine = currentBaseLine.line + const prevLine = prevBaseLine.line + const nextLine = nextBaseLine.line + /** 현재 라인이 처마유형일 경우 */ if (eavesType.includes(currentLine.attributes?.type)) { - const nextLine = baseLines[(index + 1) % baseLines.length] - const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length] - /** - * 현재 라인이 처마인 경우 - */ if (eavesType.includes(nextLine.attributes?.type)) { + /** + * 현재 라인이 처마인 경우 + */ const prevAngle = calculateAngle(prevLine.startPoint, prevLine.endPoint) const nextAngle = calculateAngle(nextLine.startPoint, nextLine.endPoint) - console.log('prevAngle :', prevAngle, 'nextAngle :', nextAngle) /** * 이전, 다음 라인이 처마일때 라인의 방향이 반대면 ㄷ 모양으로 판단한다. @@ -831,26 +855,24 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { y: currentMidY.plus(checkScale.times(Math.sign(yVector.toNumber()))).toNumber(), } - // const checkMidLine = new fabric.Line([currentMidX, currentMidY, checkPoints.x, checkPoints.y], { - // stroke: 'blue', - // strokeWidth: 2, - // }) - // canvas.add(checkMidLine) - // canvas.renderAll() - if (checkWallPolygon.inPolygon(checkPoints)) { - drawEavesFirstLines.push({ currentLine, prevLine, nextLine, size: currentLine.attributes.planeSize }) + drawEavesFirstLines.push({ currentBaseLine, prevBaseLine, nextBaseLine }) } else { - drawEavesSecondLines.push({ currentLine, prevLine, nextLine, size: currentLine.attributes.planeSize }) + drawEavesSecondLines.push({ currentBaseLine, prevBaseLine, nextBaseLine }) } } else { - drawEavesSecondLines.push({ currentLine, prevLine, nextLine, size: currentLine.attributes.planeSize }) + drawEavesSecondLines.push({ currentBaseLine, prevBaseLine, nextBaseLine }) } } } }) - drawEavesFirstLines.sort((a, b) => a.size - b.size) + drawEavesFirstLines.sort((a, b) => a.currentBaseLine.size - b.currentBaseLine.size) + console.log('drawEavesFirstLines :', drawEavesFirstLines) + console.log( + 'drawEavesFirstLines :', + drawEavesFirstLines.map((line) => line.currentBaseLine.size), + ) /** 추녀마루 */ let baseHipLines = [] @@ -862,14 +884,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { /** ⨆ 모양 처마에 추녀마루를 그린다. */ drawEavesFirstLines.forEach((current) => { // 확인용 라인, 포인트 제거 - /*canvas - .getObjects() - .filter((obj) => obj.name === 'checkPoint' || obj.name === 'checkLine') - .forEach((obj) => canvas.remove(obj)) - canvas.renderAll() -*/ - const { currentLine, prevLine, nextLine } = current - let { x1, x2, y1, y2 } = currentLine + const { currentBaseLine, prevBaseLine, nextBaseLine } = current + const currentLine = currentBaseLine.line + const prevLine = prevBaseLine.line + const nextLine = nextBaseLine.line + let { x1, x2, y1, y2, size } = currentBaseLine let beforePrevLine, afterNextLine /** 이전 라인의 경사 */ @@ -878,12 +897,12 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const currentDegree = currentLine.attributes.pitch > 0 ? getDegreeByChon(currentLine.attributes.pitch) : currentLine.attributes.degree /** 이전 라인의 전라인, 다음 라인의 다음라인을 찾는다 */ - baseLines.forEach((line, index) => { - if (line === prevLine) { - beforePrevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length] + drawBaseLines.forEach((line, index) => { + if (line === prevBaseLine) { + beforePrevLine = drawBaseLines[(index - 1 + drawBaseLines.length) % drawBaseLines.length] } - if (line === nextLine) { - afterNextLine = baseLines[(index + 1) % baseLines.length] + if (line === nextBaseLine) { + afterNextLine = drawBaseLines[(index + 1) % drawBaseLines.length] } }) @@ -898,16 +917,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const currentAngle = calculateAngle(currentLine.startPoint, currentLine.endPoint) const prevAngle = calculateAngle(prevLine.startPoint, prevLine.endPoint) const nextAngle = calculateAngle(nextLine.startPoint, nextLine.endPoint) - const beforePrevAngle = calculateAngle(beforePrevLine.startPoint, beforePrevLine.endPoint) - const afterNextAngle = calculateAngle(afterNextLine.startPoint, afterNextLine.endPoint) + const beforePrevAngle = calculateAngle(beforePrevLine.line.startPoint, beforePrevLine.line.endPoint) + const afterNextAngle = calculateAngle(afterNextLine.line.startPoint, afterNextLine.line.endPoint) /** 현재 라인의 길이 추녀마루 길이의 기준이 된다. */ - let currentSize = Big(x2) - .minus(Big(x1)) - .plus(Big(y2).minus(Big(y1))) - .abs() - - // console.log('currentLine : ', currentLine.attributes.planeSize) + let currentSize = Big(size).div(10) /** 이전 라인과의 사이 추녀마루의 각도를 확인한다, 각도가 지붕안쪽으로 향하지 않을때 반대로 처리한다.*/ const prevCheckPoint = { @@ -934,7 +948,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { * 현재 라인에서 2번째 전 라인과 2번째 후 라인의 각도가 같을때 -_- 와 같은 형태로 판단하고 * 맞은 편 외벽선까지의 거리를 확인후 currentSize 를 조정한다. */ - if (currentAngle === beforePrevAngle && currentAngle === afterNextAngle) { + if (beforePrevLine === afterNextLine || (currentAngle === beforePrevAngle && currentAngle === afterNextAngle)) { const xVector = Big(nextLine.x2).minus(Big(nextLine.x1)) const yVector = Big(nextLine.y2).minus(Big(nextLine.y1)) const currentMidX = Big(x1).plus(Big(x2)).div(2) @@ -970,6 +984,8 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { if (currentAngle !== beforePrevAngle && currentAngle !== afterNextAngle && beforePrevLine !== afterNextLine) { console.log('4각 아님') // console.log('currentLine : ', currentLine.attributes.planeSize) + // console.log('beforePrevLine : ', beforePrevLine) + // console.log('afterNextLine : ', afterNextLine) const beforePrevX1 = beforePrevLine.x1, beforePrevY1 = beforePrevLine.y1, beforePrevX2 = beforePrevLine.x2, @@ -988,6 +1004,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { ).length > 0 /** 6각 */ + // console.log('isConnect :', isConnect) if (isConnect) { const checkScale = currentSize.pow(2).plus(currentSize.pow(2)).sqrt() const intersectBaseLine = [] @@ -1493,10 +1510,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { // console.log('startPoint : ', startPoint, 'currentSize : ', currentSize.toNumber()) /** 이전, 다음 라인중 길이가 짧은 길이*/ - const lineMinSize = + /*const lineMinSize = prevLine.attributes.planeSize < nextLine.attributes.planeSize ? Big(prevLine.attributes.planeSize).div(10) - : Big(nextLine.attributes.planeSize).div(10) + : Big(nextLine.attributes.planeSize).div(10)*/ + const lineMinSize = prevBaseLine.size < nextBaseLine.size ? Big(prevBaseLine.size).div(10) : Big(nextBaseLine.size).div(10) /** 마루의 길이는 이전 다음 라인중 짧은것의 길이와 현재라인부터 맞은편 라인까지의 길이에서 현재 라인의 길이를 뺀 것중 짧은 길이 */ const ridgeSize = Big(Math.min(oppositeSize, lineMinSize)) @@ -1505,7 +1523,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { if (ridgeSize.gt(0)) { baseRidgeCount = baseRidgeCount + 1 - console.log('baseRidgeCount : ', baseRidgeCount) + // console.log('baseRidgeCount : ', baseRidgeCount) const points = [ startPoint.x, startPoint.y, @@ -1559,6 +1577,12 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { nextHipLine.fire('modified') } } + + canvas + .getObjects() + .filter((obj) => obj.name === 'checkPoint' || obj.name === 'checkLine') + .forEach((obj) => canvas.remove(obj)) + canvas.renderAll() }) /** 중복제거 */ @@ -1586,12 +1610,14 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { }) }) - console.log('drawEavesSecondLines : ', drawEavesSecondLines) + // console.log('drawEavesSecondLines : ', drawEavesSecondLines) /** ㄴ 모양 처마에 추녀마루를 그린다. */ drawEavesSecondLines.forEach((current) => { - const { currentLine, prevLine, nextLine } = current - let { x1, x2, y1, y2 } = currentLine - let beforePrevLine, afterNextLine + const { currentBaseLine, prevBaseLine, nextBaseLine } = current + const currentLine = currentBaseLine.line + const prevLine = prevBaseLine.line + const nextLine = nextBaseLine.line + let { x1, x2, y1, y2, size } = currentBaseLine /** 이전 라인의 경사 */ const prevDegree = prevLine.attributes.pitch > 0 ? getDegreeByChon(prevLine.attributes.pitch) : prevLine.attributes.degree @@ -1723,16 +1749,16 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { { vertex1: { x: x1, y: y1 }, vertex2: prevEndPoint }, { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }, ) - const checkLine = new fabric.Line([x1, y1, prevEndPoint.x, prevEndPoint.y], { + /*const checkLine = new fabric.Line([x1, y1, prevEndPoint.x, prevEndPoint.y], { stroke: 'red', strokeWidth: 2, parentId: roof.id, name: 'checkLine', }) canvas.add(checkLine) - canvas.renderAll() + canvas.renderAll()*/ - if (intersection) { + /* if (intersection) { const intersectCircle = new fabric.Circle({ left: intersection.x - 2, top: intersection.y - 2, @@ -1743,7 +1769,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { }) canvas.add(intersectCircle) canvas.renderAll() - } + }*/ if (intersection && !intersection.isIntersectionOutside) { intersectRidgeLine.push({ intersection, @@ -1776,14 +1802,14 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { vertex2: prevEndPoint, } - const checkLine = new fabric.Line([hipEdge.vertex1.x, hipEdge.vertex1.y, hipEdge.vertex2.x, hipEdge.vertex2.y], { + /* const checkLine = new fabric.Line([hipEdge.vertex1.x, hipEdge.vertex1.y, hipEdge.vertex2.x, hipEdge.vertex2.y], { stroke: 'yellow', strokeWidth: 2, parentId: roof.id, name: 'checkLine', }) canvas.add(checkLine) - canvas.renderAll() + canvas.renderAll()*/ let intersectPoints = [] /** 외벽선에서 추녀 마루가 겹치는 경우에 대한 확인*/ @@ -2313,7 +2339,6 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } } - console.log('hipSize : ', hipSize.toNumber()) if (hipSize.eq(0)) { const ridge = current.line basePoints = baseHipLines @@ -2324,6 +2349,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } hipSize = hipSize.pow(2).div(2).sqrt().round().div(10).toNumber() + // console.log('hipSize : ', hipSize.toNumber()) /** 현재 라인을 기준으로 45, 135, 225, 315 방향을 확인하기 위한 좌표, hip은 45도 방향으로만 그린다. */ const checkEdge45 = { vertex1: { x: current.x, y: current.y }, vertex2: { x: current.x + hipSize, y: current.y - hipSize } } @@ -2382,7 +2408,36 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { intersectPoints.forEach((is) => { const points = [current.x, current.y, is.x, is.y] - const hipLine = drawHipLine(points, canvas, roof, textMode, null, prevDegree, currentDegree) + const pointEdge = { vertex1: { x: points[0], y: points[1] }, vertex2: { x: points[2], y: points[3] } } + const vectorX = Math.sign(Big(points[2]).minus(Big(points[0])).toNumber()) + const vectorY = Math.sign(Big(points[3]).minus(Big(points[1])).toNumber()) + const roofIntersections = [] + roof.lines.forEach((line) => { + const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } + const intersection = edgesIntersection(pointEdge, lineEdge) + if (intersection) { + const vectorIntersectionX = Math.sign(Big(intersection.x).minus(Big(points[0])).toNumber()) + const vectorIntersectionY = Math.sign(Big(intersection.y).minus(Big(points[1])).toNumber()) + if (vectorIntersectionX === vectorX && vectorIntersectionY === vectorY) { + roofIntersections.push({ + x: intersection.x, + y: intersection.y, + size: calcLinePlaneSize({ x1: points[0], y1: points[1], x2: intersection.x, y2: intersection.y }), + }) + } + } + }) + roofIntersections.sort((a, b) => a.size - b.size) + + const hipLine = drawHipLine( + [points[0], points[1], roofIntersections[0].x, roofIntersections[0].y], + canvas, + roof, + textMode, + null, + prevDegree, + currentDegree, + ) baseHipLines.push({ x1: points[0], y1: points[1], x2: points[2], y2: points[3], line: hipLine }) current.cnt = current.cnt + 1 }) @@ -2405,7 +2460,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { ) noRidgeHipPoints.forEach((current) => { - const checkPoint = new fabric.Circle({ + /* const checkPoint = new fabric.Circle({ left: current.x2, top: current.y2, radius: 4, @@ -2415,9 +2470,9 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { }) canvas.add(checkPoint) canvas.renderAll() - console.log('noRidgeHipPoints current : ', current.x1, current.y1, current.x2, current.y2) + console.log('noRidgeHipPoints current : ', current.x1, current.y1, current.x2, current.y2)*/ const orthogonalPoints = noRidgeHipPoints.filter((point) => { - const checkPoint1 = new fabric.Circle({ + /*const checkPoint1 = new fabric.Circle({ left: point.x2, top: point.y2, radius: 4, @@ -2437,14 +2492,14 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { current.x2 !== point.x2 && current.y2 === point.y2, ) canvas.remove(checkPoint1) - canvas.renderAll() + canvas.renderAll()*/ if (point !== current && ((current.x2 === point.x2 && current.y2 !== point.y2) || (current.x2 !== point.x2 && current.y2 === point.y2))) { return true } }) - canvas.remove(checkPoint) - canvas.renderAll() + // canvas.remove(checkPoint) + // canvas.renderAll() /** 직교 하는 포인트가 존재 할때 마루를 그린다. */ if (orthogonalPoints.length > 0) { @@ -2691,28 +2746,28 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { if (!linePoint) return const hipStartPoint = [hipPoint.x2, hipPoint.y2, linePoint.intersection.x, linePoint.intersection.y] - console.log('hipStartPoint : ', hipStartPoint) + // console.log('hipStartPoint : ', hipStartPoint) /** 직선인 경우 마루를 그린다.*/ if ( (hipStartPoint[0] === hipStartPoint[2] && hipStartPoint[1] !== hipStartPoint[3]) || (hipStartPoint[0] !== hipStartPoint[2] && hipStartPoint[1] === hipStartPoint[3]) ) { - console.log('릿지1') + // console.log('릿지1') const ridgeLine = drawRidgeLine(hipStartPoint, canvas, roof, textMode) baseRidgeCount = baseRidgeCount + 1 baseRidgeLines.push(ridgeLine) noRidgeHipPoints = noRidgeHipPoints.filter((hip) => hip !== hipPoint) } - console.log( - Big(hipStartPoint[0]).minus(Big(hipStartPoint[2])).abs().toNumber(), - Big(hipStartPoint[1]).minus(Big(hipStartPoint[3])).abs().toNumber(), - Big(hipStartPoint[0]) - .minus(Big(hipStartPoint[2])) - .abs() - .minus(Big(hipStartPoint[1]).minus(Big(hipStartPoint[3])).abs()) - .abs() - .lt(1), - ) + // console.log( + // Big(hipStartPoint[0]).minus(Big(hipStartPoint[2])).abs().toNumber(), + // Big(hipStartPoint[1]).minus(Big(hipStartPoint[3])).abs().toNumber(), + // Big(hipStartPoint[0]) + // .minus(Big(hipStartPoint[2])) + // .abs() + // .minus(Big(hipStartPoint[1]).minus(Big(hipStartPoint[3])).abs()) + // .abs() + // .lt(1), + // ) /** 대각선인경우 hip을 그린다. */ if ( Big(hipStartPoint[0]) @@ -2722,7 +2777,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { .abs() .lt(1) ) { - console.log('힙1') + // console.log('힙1') const hipLine = drawHipLine(hipStartPoint, canvas, roof, textMode, null, prevDegree, currentDegree) baseHipLines.push({ x1: hipStartPoint[0], y1: hipStartPoint[1], x2: hipStartPoint[2], y2: hipStartPoint[3], line: hipLine }) noRidgeHipPoints = noRidgeHipPoints.filter((hip) => hip !== hipPoint) @@ -2743,8 +2798,8 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { baseRidgeLines.push(ridgeLine) } - console.log('isStartPoint : ', isStartPoint) - console.log(Big(isStartPoint[0]).minus(Big(isStartPoint[2])).toNumber()) + // console.log('isStartPoint : ', isStartPoint) + // console.log(Big(isStartPoint[0]).minus(Big(isStartPoint[2])).toNumber()) if ( Big(isStartPoint[0]) .minus(Big(isStartPoint[2])) @@ -2762,7 +2817,227 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const ridgeAllPoints = [] baseRidgeLines.forEach((line) => ridgeAllPoints.push({ x: line.x1, y: line.y1 }, { x: line.x2, y: line.y2 })) - console.log('ridge count', baseRidgeCount, getMaxRidge(baseLines.length)) + // console.log('ridge count', baseRidgeCount, getMaxRidge(baseLines.length)) + + console.log('baseLinePoints : ', baseLinePoints) + /** hip 중에 지붕의 라인과 만나지 않은 선을 확인.*/ + baseHipLines + .filter( + (hip) => baseLinePoints.filter((point) => (point.x === hip.x1 && point.y === hip.y1) || (point.x === hip.x2 && point.y === hip.y2)).length > 0, + ) + .filter((hip) => { + const hipEdge = { vertex1: { x: hip.line.x1, y: hip.line.y1 }, vertex2: { x: hip.line.x2, y: hip.line.y2 } } + const hipVectorX = Math.sign(Big(hip.x1).minus(Big(hip.x2))) + const hipVectorY = Math.sign(Big(hip.y1).minus(Big(hip.y2))) + let isIntersect = false + roof.lines.forEach((line) => { + const edge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } + const intersection = edgesIntersection(edge, hipEdge) + if (intersection && !intersection.isIntersectionOutside) { + const isVectorX = Math.sign(Big(intersection.x).minus(Big(hip.x2))) + const isVectorY = Math.sign(Big(intersection.y).minus(Big(hip.y2))) + if (isVectorX === hipVectorX && isVectorY === hipVectorY) { + isIntersect = true + } + } + }) + return !isIntersect + }) + .forEach((hip) => { + console.log('hip : ', hip) + const checkLine = new fabric.Line([hip.line.x1, hip.line.y1, hip.line.x2, hip.line.y2], { + stroke: 'red', + strokeWidth: 4, + parentId: roofId, + name: 'checkLine', + }) + canvas.add(checkLine) + canvas.renderAll() + const hipLine = hip.line + if (hipLine) { + const hipVectorX = Big(hipLine.x2).plus(Big(hipLine.attributes.planeSize).times(Big(hipLine.x1).minus(Big(hipLine.x2)).neg().s)) + const hipVectorY = Big(hipLine.y2).plus(Big(hipLine.attributes.planeSize).times(Big(hipLine.y1).minus(Big(hipLine.y2)).neg().s)) + const overlapLineX = roof.lines + .filter((roofLine) => roofLine.x1 !== roofLine.x2 && roofLine.y1 === hipLine.y2 && roofLine.y2 === hipLine.y2) + .filter((roofLine) => { + const minX = Math.min(roofLine.x1, roofLine.x2, hipLine.x2) + const maxX = Math.max(roofLine.x1, roofLine.x2, hipLine.x2) + const checkLineEdge = { vertex1: { x: minX, y: hipLine.y2 }, vertex2: { x: maxX, y: hipLine.y2 } } + let isIntersect = false + baseHipLines.forEach((baseHipLine) => { + const edge = { vertex1: { x: baseHipLine.x1, y: baseHipLine.y1 }, vertex2: { x: baseHipLine.x2, y: baseHipLine.y2 } } + const intersection = edgesIntersection(edge, checkLineEdge) + if (intersection && !intersection.isIntersectionOutside) { + const isVectorX = Math.sign(Big(intersection.x).minus(Big(baseHipLine.x2))) + const isVectorY = Math.sign(Big(intersection.y).minus(Big(baseHipLine.y2))) + if (isVectorX === hipVectorX && isVectorY === hipVectorY) { + isIntersect = true + } + } + }) + baseRidgeLines.forEach((baseRidgeLine) => { + const edge = { vertex1: { x: baseRidgeLine.x1, y: baseRidgeLine.y1 }, vertex2: { x: baseRidgeLine.x2, y: baseRidgeLine.y2 } } + const intersection = edgesIntersection(edge, checkLineEdge) + if (intersection && !intersection.isIntersectionOutside) { + const isVectorX = Math.sign(Big(intersection.x).minus(Big(hipLine.x2))) + const isVectorY = Math.sign(Big(intersection.y).minus(Big(hipLine.y2))) + if (isVectorX === hipVectorX && isVectorY === hipVectorY) { + isIntersect = true + } + } + }) + return !isIntersect + }) + const overlapLineY = roof.lines + .filter((roofLine) => roofLine.y1 !== roofLine.y2 && roofLine.x1 === hipLine.x2 && roofLine.x2 === hipLine.x2) + .filter((roofLine) => { + const minY = Math.min(roofLine.y1, roofLine.y2, hipLine.y2) + const maxY = Math.max(roofLine.y1, roofLine.y2, hipLine.y2) + const checkLineEdge = { vertex1: { x: hipLine.x2, y: minY }, vertex2: { x: hipLine.x2, y: maxY } } + let isIntersect = false + baseHipLines.forEach((baseHipLine) => { + const edge = { vertex1: { x: baseHipLine.x1, y: baseHipLine.y1 }, vertex2: { x: baseHipLine.x2, y: baseHipLine.y2 } } + const intersection = edgesIntersection(edge, checkLineEdge) + if (intersection && !intersection.isIntersectionOutside) { + const isVectorX = Math.sign(Big(intersection.x).minus(Big(hipLine.x2))) + const isVectorY = Math.sign(Big(intersection.y).minus(Big(hipLine.y2))) + if (isVectorX === hipVectorX && isVectorY === hipVectorY) { + isIntersect = true + } + } + }) + baseRidgeLines.forEach((baseRidgeLine) => { + const edge = { vertex1: { x: baseRidgeLine.x1, y: baseRidgeLine.y1 }, vertex2: { x: baseRidgeLine.x2, y: baseRidgeLine.y2 } } + const intersection = edgesIntersection(edge, checkLineEdge) + if (intersection && !intersection.isIntersectionOutside) { + const isVectorX = Math.sign(Big(intersection.x).minus(Big(hipLine.x2))) + const isVectorY = Math.sign(Big(intersection.y).minus(Big(hipLine.y2))) + if (isVectorX === hipVectorX && isVectorY === hipVectorY) { + isIntersect = true + } + } + }) + return !isIntersect + }) + + overlapLineX.reduce((prev, current) => { + const prevDistance = Big(prev.x1) + .minus(Big(hipLine.x2)) + .abs() + .lt(Big(prev.x2).minus(Big(hipLine.x2)).abs()) + ? Big(prev.x1).minus(Big(hipLine.x2)).abs() + : Big(prev.x2).minus(Big(hipLine.x2)).abs() + const currentDistance = Big(current.x1) + .minus(Big(hipLine.x2)) + .abs() + .lt(Big(current.x2).minus(Big(hipLine.x2)).abs()) + ? Big(current.x1).minus(Big(hipLine.x2)).abs() + : Big(current.x2).minus(Big(hipLine.x2)).abs() + + return prevDistance.lt(currentDistance) ? prev : current + }, overlapLineX[0]) + + overlapLineY.reduce((prev, current) => { + const prevDistance = Big(prev.y1) + .minus(Big(hipLine.y2)) + .abs() + .lt(Big(prev.y2).minus(Big(hipLine.y2)).abs()) + ? Big(prev.y1).minus(Big(hipLine.y2)).abs() + : Big(prev.y2).minus(Big(hipLine.y2)).abs() + const currentDistance = Big(current.y1) + .minus(Big(hipLine.y2)) + .abs() + .lt(Big(current.y2).minus(Big(hipLine.y2)).abs()) + ? Big(current.y1).minus(Big(hipLine.y2)).abs() + : Big(current.y2).minus(Big(hipLine.y2)).abs() + return prevDistance.lt(currentDistance) ? prev : current + }, overlapLineY[0]) + + if (overlapLineX.length > 0) { + const overlapLine = overlapLineX[0] + const maxX = Math.max(overlapLine.x1, overlapLine.x2) + const point = [hipLine.x2, hipLine.y2, maxX, hipLine.y2] + const addLine = drawHipLine(point, canvas, roof, textMode, null, prevDegree, currentDegree) + baseHipLines.push({ x1: point[0], y1: point[1], x2: point[2], y2: point[3], line: addLine }) + } + if (overlapLineY.length > 0) { + const overlapLine = overlapLineY[0] + const maxY = Math.max(overlapLine.y1, overlapLine.y2) + const point = [hipLine.x2, hipLine.y2, hipLine.x2, maxY] + const addLine = drawHipLine(point, canvas, roof, textMode, null, prevDegree, currentDegree) + baseHipLines.push({ x1: point[0], y1: point[1], x2: point[2], y2: point[3], line: addLine }) + } + } + + const modifiedBaseLine = baseLines.filter((line) => (hip.x2 === line.x1 && hip.y2 === line.y1) || (hip.x2 === line.x2 && hip.y2 === line.y2)) + console.log('modifiedBaseLine : ', modifiedBaseLine) + if (modifiedBaseLine.length === 0) return + const verticalLine = modifiedBaseLine.find( + (line) => + (hip.x2 === line.attributes.originPoint.x1 && hip.x2 === line.attributes.originPoint.x2) || + (hip.y2 === line.attributes.originPoint.y1 && hip.y2 === line.attributes.originPoint.y2), + ) + const horizonLine = modifiedBaseLine.find((line) => line !== verticalLine) + + console.log('verticalLine', verticalLine) + console.log('horizonLine : ', horizonLine) + const horizonRoof = roof.lines.find((line) => { + const originPoint = horizonLine.attributes.originPoint + if (originPoint.y1 === originPoint.y2) { + return ( + line.y1 === line.y2 && + Math.sign(originPoint.x1 - originPoint.x2) === Math.sign(line.x1 - line.x2) && + Big(originPoint.y1).minus(Big(line.y1)).abs().minus(horizonLine.attributes.offset).abs().lt(1) + ) + } else { + return ( + line.x1 === line.x2 && + Math.sign(originPoint.y1 - originPoint.y2) === Math.sign(line.y1 - line.y2) && + Big(originPoint.x1).minus(Big(line.x1)).abs().minus(horizonLine.attributes.offset).abs().lt(1) + ) + } + }) + + if (horizonRoof) { + let horizonPoint + if (horizonRoof.y1 === horizonRoof.y2) { + const minX = Math.min(horizonRoof.x1, horizonRoof.x2, horizonLine.attributes.originPoint.x1, horizonLine.attributes.originPoint.x2) + const maxX = Math.max(horizonRoof.x1, horizonRoof.x2, horizonLine.attributes.originPoint.x1, horizonLine.attributes.originPoint.x2) + horizonPoint = [minX, horizonRoof.y1, maxX, horizonRoof.y1] + } else { + const minY = Math.min(horizonRoof.y1, horizonRoof.y2, horizonLine.attributes.originPoint.y1, horizonLine.attributes.originPoint.y2) + const maxY = Math.max(horizonRoof.y1, horizonRoof.y2, horizonLine.attributes.originPoint.y1, horizonLine.attributes.originPoint.y2) + horizonPoint = [horizonRoof.x1, minY, horizonRoof.x1, maxY] + } + let addLine + const alreadyHorizonLines = baseHipLines.find( + (hipLine) => + hipLine.x1 === horizonPoint[0] && hipLine.y1 === horizonPoint[1] && hipLine.x2 === horizonPoint[2] && hipLine.y2 === horizonPoint[3], + ) + console.log('alreadyHorizonLines : ', alreadyHorizonLines) + if (!alreadyHorizonLines) { + addLine = drawHipLine(horizonPoint, canvas, roof, textMode, null, prevDegree, currentDegree) + baseHipLines.push({ x1: horizonPoint[0], y1: horizonPoint[1], x2: horizonPoint[2], y2: horizonPoint[3], line: addLine }) + } else { + addLine = alreadyHorizonLines + } + + let verticalPoint + if (addLine.y1 === addLine.y2) { + verticalPoint = [hip.x2, hip.y2, hip.x2, addLine.y1] + } else { + verticalPoint = [hip.x2, hip.y2, addLine.x1, hip.y2] + } + const alreadyVerticalLine = baseHipLines.find( + (hipLine) => + hipLine.x1 === verticalPoint[0] && hipLine.y1 === verticalPoint[1] && hipLine.x2 === verticalPoint[2] && hipLine.y2 === verticalPoint[3], + ) + if (!alreadyVerticalLine) { + addLine = drawHipLine(verticalPoint, canvas, roof, textMode, null, prevDegree, currentDegree) + baseHipLines.push({ x1: verticalPoint[0], y1: verticalPoint[1], x2: verticalPoint[2], y2: verticalPoint[3], line: addLine }) + } + } + }) ridgeAllPoints.forEach((current) => { ridgeAllPoints @@ -2871,6 +3146,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { }) }) + /** 중복 제거 */ + baseHipLines.forEach((hipLine) => { + baseHipLines.filter((hipLine2) => hipLine !== hipLine2).forEach((hipLine2) => {}) + }) + roof.innerLines = [...baseRidgeLines, ...baseHipLines.map((line) => line.line)] /** 확인용 라인, 포인트 제거 */