From 4d2b8721838f0868ce0c828f67e3c074bd51646a Mon Sep 17 00:00:00 2001 From: yscha Date: Sat, 6 Dec 2025 00:03:00 +0900 Subject: [PATCH] =?UTF-8?q?=EC=86=8C=EC=8A=A4=EC=A0=95=EB=A6=AC1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/skeleton-utils.js | 1710 +++++++++++++++++++----------------- 1 file changed, 888 insertions(+), 822 deletions(-) diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index 092254ba..4932439c 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -183,127 +183,127 @@ const movingLineFromSkeleton = (roofId, canvas) => { let newEndPoint = {...originalEndPoint}; // 위치와 방향에 따라 좌표 조정 -/* - switch (position) { - case 'left': - if (moveDirection === 'up') { - newStartPoint.x = Big(line.startPoint.x).minus(absMove).toNumber(); - newEndPoint.x = Big(line.endPoint.x).minus(absMove).toNumber(); - } else if (moveDirection === 'down') { - newStartPoint.x = Big(line.startPoint.x).plus(absMove).toNumber(); - newEndPoint.x = Big(line.endPoint.x).plus(absMove).toNumber(); - } - break; - case 'right': - if (moveDirection === 'up') { - newStartPoint.x = Big(line.startPoint.x).plus(absMove).toNumber(); - newEndPoint.x = Big(line.endPoint.x).plus(absMove).toNumber(); - } else if (moveDirection === 'down') { - newStartPoint.x = Big(line.startPoint.x).minus(absMove).toNumber(); - newEndPoint.x = Big(line.endPoint.x).minus(absMove).toNumber(); - } - break; - case 'top': - if (moveDirection === 'up') { - newStartPoint.y = Big(line.startPoint.y).minus(absMove).toNumber(); - newEndPoint.y = Big(line.endPoint.y).minus(absMove).toNumber(); - } else if (moveDirection === 'down') { - newStartPoint.y = Big(line.startPoint.y).plus(absMove).toNumber(); - newEndPoint.y = Big(line.endPoint.y).plus(absMove).toNumber(); - } - break; - case 'bottom': - if (moveDirection === 'up') { - newStartPoint.y = Big(line.startPoint.y).plus(absMove).toNumber(); - newEndPoint.y = Big(line.endPoint.y).plus(absMove).toNumber(); - } else if (moveDirection === 'down') { - newStartPoint.y = Big(line.startPoint.y).minus(absMove).toNumber(); - newEndPoint.y = Big(line.endPoint.y).minus(absMove).toNumber(); - } - break; - } -*/ + /* + switch (position) { + case 'left': + if (moveDirection === 'up') { + newStartPoint.x = Big(line.startPoint.x).minus(absMove).toNumber(); + newEndPoint.x = Big(line.endPoint.x).minus(absMove).toNumber(); + } else if (moveDirection === 'down') { + newStartPoint.x = Big(line.startPoint.x).plus(absMove).toNumber(); + newEndPoint.x = Big(line.endPoint.x).plus(absMove).toNumber(); + } + break; + case 'right': + if (moveDirection === 'up') { + newStartPoint.x = Big(line.startPoint.x).plus(absMove).toNumber(); + newEndPoint.x = Big(line.endPoint.x).plus(absMove).toNumber(); + } else if (moveDirection === 'down') { + newStartPoint.x = Big(line.startPoint.x).minus(absMove).toNumber(); + newEndPoint.x = Big(line.endPoint.x).minus(absMove).toNumber(); + } + break; + case 'top': + if (moveDirection === 'up') { + newStartPoint.y = Big(line.startPoint.y).minus(absMove).toNumber(); + newEndPoint.y = Big(line.endPoint.y).minus(absMove).toNumber(); + } else if (moveDirection === 'down') { + newStartPoint.y = Big(line.startPoint.y).plus(absMove).toNumber(); + newEndPoint.y = Big(line.endPoint.y).plus(absMove).toNumber(); + } + break; + case 'bottom': + if (moveDirection === 'up') { + newStartPoint.y = Big(line.startPoint.y).plus(absMove).toNumber(); + newEndPoint.y = Big(line.endPoint.y).plus(absMove).toNumber(); + } else if (moveDirection === 'down') { + newStartPoint.y = Big(line.startPoint.y).minus(absMove).toNumber(); + newEndPoint.y = Big(line.endPoint.y).minus(absMove).toNumber(); + } + break; + } + */ // 원본 라인 업데이트 - // newPoints 배열에서 일치하는 포인트들을 찾아서 업데이트 + // newPoints 배열에서 일치하는 포인트들을 찾아서 업데이트 console.log('absMove::', absMove); - newPoints.forEach((point, index) => { - if(position === 'bottom'){ - if (moveDirection === 'in') { - if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.y = Big(point.y).minus(absMove).toNumber(); - } - // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - // point.y = Big(point.y).minus(absMove).toNumber(); - // } - }else if (moveDirection === 'out'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.y = Big(point.y).plus(absMove).toNumber(); - } - // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - // point.y = Big(point.y).plus(absMove).toNumber(); - // } + newPoints.forEach((point, index) => { + if(position === 'bottom'){ + if (moveDirection === 'in') { + if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.y = Big(point.y).minus(absMove).toNumber(); } - - }else if (position === 'top'){ - if(moveDirection === 'in'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint)) { - point.y = Big(point.y).plus(absMove).toNumber(); - } - if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.y = Big(point.y).plus(absMove).toNumber(); - } - }else if(moveDirection === 'out'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint)) { - point.y = Big(point.y).minus(absMove).toNumber(); - } - if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.y = Big(point.y).minus(absMove).toNumber(); - } + // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + // point.y = Big(point.y).minus(absMove).toNumber(); + // } + }else if (moveDirection === 'out'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.y = Big(point.y).plus(absMove).toNumber(); } - - }else if(position === 'left'){ - if(moveDirection === 'in'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.x = Big(point.x).plus(absMove).toNumber(); - } - // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - // point.x = Big(point.x).plus(absMove).toNumber(); - // } - }else if(moveDirection === 'out'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.x = Big(point.x).minus(absMove).toNumber(); - } - // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - // point.x = Big(point.x).minus(absMove).toNumber(); - // } - } - - }else if(position === 'right'){ - if(moveDirection === 'in'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint)) { - point.x = Big(point.x).minus(absMove).toNumber(); - } - if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.x = Big(point.x).minus(absMove).toNumber(); - } - }else if(moveDirection === 'out'){ - if(isSamePoint(roof.basePoints[index], originalStartPoint)) { - point.x = Big(point.x).plus(absMove).toNumber(); - } - if (isSamePoint(roof.basePoints[index], originalEndPoint)) { - point.x = Big(point.x).plus(absMove).toNumber(); - } - } - + // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + // point.y = Big(point.y).plus(absMove).toNumber(); + // } } - }); + }else if (position === 'top'){ + if(moveDirection === 'in'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint)) { + point.y = Big(point.y).plus(absMove).toNumber(); + } + if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.y = Big(point.y).plus(absMove).toNumber(); + } + }else if(moveDirection === 'out'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint)) { + point.y = Big(point.y).minus(absMove).toNumber(); + } + if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.y = Big(point.y).minus(absMove).toNumber(); + } + } + + }else if(position === 'left'){ + if(moveDirection === 'in'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.x = Big(point.x).plus(absMove).toNumber(); + } + // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + // point.x = Big(point.x).plus(absMove).toNumber(); + // } + }else if(moveDirection === 'out'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.x = Big(point.x).minus(absMove).toNumber(); + } + // if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + // point.x = Big(point.x).minus(absMove).toNumber(); + // } + } + + }else if(position === 'right'){ + if(moveDirection === 'in'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint)) { + point.x = Big(point.x).minus(absMove).toNumber(); + } + if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.x = Big(point.x).minus(absMove).toNumber(); + } + }else if(moveDirection === 'out'){ + if(isSamePoint(roof.basePoints[index], originalStartPoint)) { + point.x = Big(point.x).plus(absMove).toNumber(); + } + if (isSamePoint(roof.basePoints[index], originalEndPoint)) { + point.x = Big(point.x).plus(absMove).toNumber(); + } + } + + } - // 원본 baseLine도 업데이트 - line.startPoint = newStartPoint; - line.endPoint = newEndPoint; }); - return newPoints; + + // 원본 baseLine도 업데이트 + line.startPoint = newStartPoint; + line.endPoint = newEndPoint; + }); + return newPoints; } } @@ -522,29 +522,29 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { } }); -/* - //2. 연결이 끊어진 스켈레톤 선을 찾아 연장합니다. - const { disconnectedLines } = findDisconnectedSkeletonLines(skeletonLines, roof.lines); + /* + //2. 연결이 끊어진 스켈레톤 선을 찾아 연장합니다. + const { disconnectedLines } = findDisconnectedSkeletonLines(skeletonLines, roof.lines); - if(disconnectedLines.length > 0) { + if(disconnectedLines.length > 0) { - disconnectedLines.forEach(dLine => { - const { index, extendedLine, p1Connected, p2Connected } = dLine; - const newPoint = extendedLine?.point; - if (!newPoint) return; - // p1이 끊어졌으면 p1을, p2가 끊어졌으면 p2를 연장된 지점으로 업데이트 - if (p1Connected) { //p2 연장 - skeletonLines[index].p2 = { ...skeletonLines[index].p2, x: newPoint.x, y: newPoint.y }; - } else if (p2Connected) {//p1 연장 - skeletonLines[index].p1 = { ...skeletonLines[index].p1, x: newPoint.x, y: newPoint.y }; - } - }); + disconnectedLines.forEach(dLine => { + const { index, extendedLine, p1Connected, p2Connected } = dLine; + const newPoint = extendedLine?.point; + if (!newPoint) return; + // p1이 끊어졌으면 p1을, p2가 끊어졌으면 p2를 연장된 지점으로 업데이트 + if (p1Connected) { //p2 연장 + skeletonLines[index].p2 = { ...skeletonLines[index].p2, x: newPoint.x, y: newPoint.y }; + } else if (p2Connected) {//p1 연장 + skeletonLines[index].p1 = { ...skeletonLines[index].p1, x: newPoint.x, y: newPoint.y }; + } + }); - //2-1 확장된 스켈레톤 선이 연장되다가 서로 만나면 만난점(접점)에서 멈추어야 된다. - trimIntersectingExtendedLines(skeletonLines, disconnectedLines); + //2-1 확장된 스켈레톤 선이 연장되다가 서로 만나면 만난점(접점)에서 멈추어야 된다. + trimIntersectingExtendedLines(skeletonLines, disconnectedLines); - } -*/ + } + */ //2. 연결이 끊어진 라인이 있을경우 찾아서 추가한다(동 이동일때) @@ -604,9 +604,9 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { }); coordinateText(skeletonLine) - canvas.add(skeletonLine); + canvas.add(skeletonLine); skeletonLine.bringToFront(); - existingLines.add(lineKey); // 추가된 라인을 추적 + existingLines.add(lineKey); // 추가된 라인을 추적 @@ -629,667 +629,667 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { } innerLines.push(skeletonLine) - canvas.renderAll(); + canvas.renderAll(); }); -if((roof.moveUpDown??0 > 0) ) { + if((roof.moveUpDown??0 > 0) ) { - // 같은 라인이 없으므로 새 다각형 라인 생성 - //라인 편집 - // let i = 0 - const currentRoofLines = canvas.getObjects().filter((obj) => obj.lineName === 'roofLine' && obj.attributes.roofId === roofId) - let roofLineRects = canvas.getObjects().filter((obj) => obj.name === 'roofLineRect' && obj.roofId === roofId) + // 같은 라인이 없으므로 새 다각형 라인 생성 + //라인 편집 + // let i = 0 + const currentRoofLines = canvas.getObjects().filter((obj) => obj.lineName === 'roofLine' && obj.attributes.roofId === roofId) + let roofLineRects = canvas.getObjects().filter((obj) => obj.name === 'roofLineRect' && obj.roofId === roofId) - roofLineRects.forEach((roofLineRect) => { - canvas.remove(roofLineRect) - canvas.renderAll() - }) + roofLineRects.forEach((roofLineRect) => { + canvas.remove(roofLineRect) + canvas.renderAll() + }) - let helpLines = canvas.getObjects().filter((obj) => obj.lineName === 'helpLine' && obj.roofId === roofId) - helpLines.forEach((helpLine) => { - canvas.remove(helpLine) - canvas.renderAll() - }) + let helpLines = canvas.getObjects().filter((obj) => obj.lineName === 'helpLine' && obj.roofId === roofId) + helpLines.forEach((helpLine) => { + canvas.remove(helpLine) + canvas.renderAll() + }) - function sortCurrentRoofLines(lines) { - return [...lines].sort((a, b) => { - // Get all coordinates in a consistent order - const getCoords = (line) => { - const x1 = line.x1 ?? line.get('x1'); - const y1 = line.y1 ?? line.get('y1'); - const x2 = line.x2 ?? line.get('x2'); - const y2 = line.y2 ?? line.get('y2'); + function sortCurrentRoofLines(lines) { + return [...lines].sort((a, b) => { + // Get all coordinates in a consistent order + const getCoords = (line) => { + const x1 = line.x1 ?? line.get('x1'); + const y1 = line.y1 ?? line.get('y1'); + const x2 = line.x2 ?? line.get('x2'); + const y2 = line.y2 ?? line.get('y2'); - // Sort points left-to-right, then top-to-bottom - return x1 < x2 || (x1 === x2 && y1 < y2) - ? [x1, y1, x2, y2] - : [x2, y2, x1, y1]; - }; + // Sort points left-to-right, then top-to-bottom + return x1 < x2 || (x1 === x2 && y1 < y2) + ? [x1, y1, x2, y2] + : [x2, y2, x1, y1]; + }; - const aCoords = getCoords(a); - const bCoords = getCoords(b); + const aCoords = getCoords(a); + const bCoords = getCoords(b); - // Compare each coordinate in order - for (let i = 0; i < 4; i++) { - if (Math.abs(aCoords[i] - bCoords[i]) > 0.1) { - return aCoords[i] - bCoords[i]; + // Compare each coordinate in order + for (let i = 0; i < 4; i++) { + if (Math.abs(aCoords[i] - bCoords[i]) > 0.1) { + return aCoords[i] - bCoords[i]; + } } - } - return 0; - }); - } - - - // function sortCurrentRoofLines(lines) { - // return [...lines].sort((a, b) => { - // const aX = a.x1 ?? a.get('x1') - // const aY = a.y1 ?? a.get('y1') - // const bX = b.x1 ?? b.get('x1') - // const bY = b.y1 ?? b.get('y1') - - // if (aX !== bX) return aX - bX - // return aY - bY - // }) - // } - - - // 각 라인 집합 정렬 - - // roofLines의 방향에 맞춰 currentRoofLines의 방향을 조정 - const alignLineDirection = (sourceLines, targetLines) => { - return sourceLines.map(sourceLine => { - // 가장 가까운 targetLine 찾기 - const nearestTarget = targetLines.reduce((nearest, targetLine) => { - const sourceCenter = { - x: (sourceLine.x1 + sourceLine.x2) / 2, - y: (sourceLine.y1 + sourceLine.y2) / 2 - }; - const targetCenter = { - x: (targetLine.x1 + targetLine.x2) / 2, - y: (targetLine.y1 + targetLine.y2) / 2 - }; - const distance = Math.hypot( - sourceCenter.x - targetCenter.x, - sourceCenter.y - targetCenter.y - ); - - return !nearest || distance < nearest.distance - ? { line: targetLine, distance } - : nearest; - }, null)?.line; - - if (!nearestTarget) return sourceLine; - - // 방향이 반대인지 확인 (벡터 내적을 사용) - const sourceVec = { - x: sourceLine.x2 - sourceLine.x1, - y: sourceLine.y2 - sourceLine.y1 - }; - const targetVec = { - x: nearestTarget.x2 - nearestTarget.x1, - y: nearestTarget.y2 - nearestTarget.y1 - }; - - const dotProduct = sourceVec.x * targetVec.x + sourceVec.y * targetVec.y; - - // 내적이 음수이면 방향이 반대이므로 뒤집기 - if (dotProduct < 0) { - return { - ...sourceLine, - x1: sourceLine.x2, - y1: sourceLine.y2, - x2: sourceLine.x1, - y2: sourceLine.y1 - }; - } - - return sourceLine; - }); - }; - - const sortedWallLines = sortCurrentRoofLines(wall.lines); - // roofLines의 방향에 맞춰 currentRoofLines 조정 후 정렬 - const alignedCurrentRoofLines = alignLineDirection(currentRoofLines, roofLines); - const sortedCurrentRoofLines = sortCurrentRoofLines(alignedCurrentRoofLines); - const sortedRoofLines = sortCurrentRoofLines(roofLines); - const sortedWallBaseLines = sortCurrentRoofLines(wall.baseLines); - - - //wall.lines 는 기본 벽 라인 - //wall.baseLine은 움직인라인 - const movedLines = [] - - - wallLines.forEach((wallLine, index) => { - - - // const roofLine = sortedRoofLines[index]; - // const currentRoofLine = sortedCurrentRoofLines[index]; - // const moveLine = sortedWallBaseLines[index] - // const wallBaseLine = sortedWallBaseLines[index] - - - const roofLine = roofLines[index]; - const currentRoofLine = currentRoofLines[index]; - const moveLine = wall.baseLines[index] - const wallBaseLine = wall.baseLines[index] - - //roofline 외곽선 설정 - - - // Check if wallBaseLine is inside the polygon formed by sortedWallLines - -/* - console.log('=== Line Coordinates ==='); - console.table({ - 'Point' : ['X', 'Y'], - 'roofLine' : [roofLine.x1, roofLine.y1], - 'currentRoofLine': [currentRoofLine.x1, currentRoofLine.y1], - 'moveLine' : [moveLine.x1, moveLine.y1], - 'wallBaseLine' : [wallBaseLine.x1, wallBaseLine.y1] - }); - console.log('End Points:'); - console.table({ - 'Point' : ['X', 'Y'], - 'roofLine' : [roofLine.x2, roofLine.y2], - 'currentRoofLine': [currentRoofLine.x2, currentRoofLine.y2], - 'moveLine' : [moveLine.x2, moveLine.y2], - 'wallBaseLine' : [wallBaseLine.x2, wallBaseLine.y2] - }); -*/ - const origin = moveLine.attributes?.originPoint - if (!origin) return - - if (isSamePoint(moveLine, wallLine)) { - - return false + return 0; + }); } - const movedStart = Math.abs(moveLine.x1 - wallLine.x1) > EPSILON || Math.abs(moveLine.y1 - origin.y1) > EPSILON - const movedEnd = Math.abs(moveLine.x2 - wallLine.x2) > EPSILON || Math.abs(moveLine.y2 - origin.y2) > EPSILON + + // function sortCurrentRoofLines(lines) { + // return [...lines].sort((a, b) => { + // const aX = a.x1 ?? a.get('x1') + // const aY = a.y1 ?? a.get('y1') + // const bX = b.x1 ?? b.get('x1') + // const bY = b.y1 ?? b.get('y1') + + // if (aX !== bX) return aX - bX + // return aY - bY + // }) + // } - const fullyMoved = movedStart && movedEnd + // 각 라인 집합 정렬 + + // roofLines의 방향에 맞춰 currentRoofLines의 방향을 조정 + const alignLineDirection = (sourceLines, targetLines) => { + return sourceLines.map(sourceLine => { + // 가장 가까운 targetLine 찾기 + const nearestTarget = targetLines.reduce((nearest, targetLine) => { + const sourceCenter = { + x: (sourceLine.x1 + sourceLine.x2) / 2, + y: (sourceLine.y1 + sourceLine.y2) / 2 + }; + const targetCenter = { + x: (targetLine.x1 + targetLine.x2) / 2, + y: (targetLine.y1 + targetLine.y2) / 2 + }; + const distance = Math.hypot( + sourceCenter.x - targetCenter.x, + sourceCenter.y - targetCenter.y + ); + + return !nearest || distance < nearest.distance + ? { line: targetLine, distance } + : nearest; + }, null)?.line; + + if (!nearestTarget) return sourceLine; + + // 방향이 반대인지 확인 (벡터 내적을 사용) + const sourceVec = { + x: sourceLine.x2 - sourceLine.x1, + y: sourceLine.y2 - sourceLine.y1 + }; + const targetVec = { + x: nearestTarget.x2 - nearestTarget.x1, + y: nearestTarget.y2 - nearestTarget.y1 + }; + + const dotProduct = sourceVec.x * targetVec.x + sourceVec.y * targetVec.y; + + // 내적이 음수이면 방향이 반대이므로 뒤집기 + if (dotProduct < 0) { + return { + ...sourceLine, + x1: sourceLine.x2, + y1: sourceLine.y2, + x2: sourceLine.x1, + y2: sourceLine.y1 + }; + } + + return sourceLine; + }); + }; + + const sortedWallLines = sortCurrentRoofLines(wall.lines); + // roofLines의 방향에 맞춰 currentRoofLines 조정 후 정렬 + const alignedCurrentRoofLines = alignLineDirection(currentRoofLines, roofLines); + const sortedCurrentRoofLines = sortCurrentRoofLines(alignedCurrentRoofLines); + const sortedRoofLines = sortCurrentRoofLines(roofLines); + const sortedWallBaseLines = sortCurrentRoofLines(wall.baseLines); + + + //wall.lines 는 기본 벽 라인 + //wall.baseLine은 움직인라인 + const movedLines = [] + + + wallLines.forEach((wallLine, index) => { + + + // const roofLine = sortedRoofLines[index]; + // const currentRoofLine = sortedCurrentRoofLines[index]; + // const moveLine = sortedWallBaseLines[index] + // const wallBaseLine = sortedWallBaseLines[index] + + + const roofLine = roofLines[index]; + const currentRoofLine = currentRoofLines[index]; + const moveLine = wall.baseLines[index] + const wallBaseLine = wall.baseLines[index] + + //roofline 외곽선 설정 + + + // Check if wallBaseLine is inside the polygon formed by sortedWallLines + + /* + console.log('=== Line Coordinates ==='); + console.table({ + 'Point' : ['X', 'Y'], + 'roofLine' : [roofLine.x1, roofLine.y1], + 'currentRoofLine': [currentRoofLine.x1, currentRoofLine.y1], + 'moveLine' : [moveLine.x1, moveLine.y1], + 'wallBaseLine' : [wallBaseLine.x1, wallBaseLine.y1] + }); + console.log('End Points:'); + console.table({ + 'Point' : ['X', 'Y'], + 'roofLine' : [roofLine.x2, roofLine.y2], + 'currentRoofLine': [currentRoofLine.x2, currentRoofLine.y2], + 'moveLine' : [moveLine.x2, moveLine.y2], + 'wallBaseLine' : [wallBaseLine.x2, wallBaseLine.y2] + }); + */ + const origin = moveLine.attributes?.originPoint + if (!origin) return + + if (isSamePoint(moveLine, wallLine)) { + + return false + } + + const movedStart = Math.abs(moveLine.x1 - wallLine.x1) > EPSILON || Math.abs(moveLine.y1 - origin.y1) > EPSILON + const movedEnd = Math.abs(moveLine.x2 - wallLine.x2) > EPSILON || Math.abs(moveLine.y2 - origin.y2) > EPSILON + + + const fullyMoved = movedStart && movedEnd //반시계 방향 - let newPStart //= {x:roofLine.x1, y:roofLine.y1} - let newPEnd //= {x:movedLines.x2, y:movedLines.y2} + let newPStart //= {x:roofLine.x1, y:roofLine.y1} + let newPEnd //= {x:movedLines.x2, y:movedLines.y2} //현재 roof는 무조건 시계방향 - const getAddLine = (p1, p2, stroke = '') => { - movedLines.push({ index, p1, p2 }) + const getAddLine = (p1, p2, stroke = '') => { + movedLines.push({ index, p1, p2 }) // Usage: - // let mergeLines = mergeMovedLines(movedLines); - //console.log("mergeLines:::::::", mergeLines); - const line = new QLine([p1.x, p1.y, p2.x, p2.y], { - parentId : roof.id, - fontSize : roof.fontSize, - stroke : stroke, - strokeWidth: 4, - name : 'eaveHelpLine', - lineName : 'eaveHelpLine', - selectable : true, - visible : true, - roofId : roofId, - attributes : { - type: 'eaveHelpLine', - isStart : true - } - }); - coordinateText(line) - canvas.add(line) - canvas.renderAll(); - return line - } + // let mergeLines = mergeMovedLines(movedLines); + //console.log("mergeLines:::::::", mergeLines); + const line = new QLine([p1.x, p1.y, p2.x, p2.y], { + parentId : roof.id, + fontSize : roof.fontSize, + stroke : stroke, + strokeWidth: 4, + name : 'eaveHelpLine', + lineName : 'eaveHelpLine', + selectable : true, + visible : true, + roofId : roofId, + attributes : { + type: 'eaveHelpLine', + isStart : true + } + }); + coordinateText(line) + canvas.add(line) + canvas.renderAll(); + return line + } - getAddLine(roofLine.startPoint, roofLine.endPoint, ) + getAddLine(roofLine.startPoint, roofLine.endPoint, ) - newPStart = { x: roofLine.x1, y: roofLine.y1 } - newPEnd = { x: roofLine.x2, y: roofLine.y2 } + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } - const getInnerLines = (lines, point) => { + const getInnerLines = (lines, point) => { - } - let isIn = false - let isOut = false + } + let isIn = false + let isOut = false //두 포인트가 변경된 라인인 - if (fullyMoved ) { - //반시계방향향 - console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd) - console.log("moveFully:::::::::::::", roofLine.direction) - const mLine = getSelectLinePosition(wall, wallBaseLine) + if (fullyMoved ) { + //반시계방향향 + console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd) + console.log("moveFully:::::::::::::", roofLine.direction) + const mLine = getSelectLinePosition(wall, wallBaseLine) - if (getOrientation(roofLine) === 'vertical') { + if (getOrientation(roofLine) === 'vertical') { - if (['left', 'right'].includes(mLine.position)) { - if(wallLine.x1 === wallBaseLine.x1) { - return false + if (['left', 'right'].includes(mLine.position)) { + if(wallLine.x1 === wallBaseLine.x1) { + return false + } + const positionType = + (mLine.position === 'left' && wallLine.x1 < wallBaseLine.x1) || + (mLine.position === 'right' && wallLine.x1 > wallBaseLine.x1) + ? 'in' : 'out'; + const condition = `${mLine.position}_${positionType}`; + let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines) + let sPoint, ePoint; + switch (condition) { + case 'left_in': + isIn = true + + if (isStartEnd.start ) { + newPEnd.y = roofLine.y2; + newPEnd.x = roofLine.x2; + + const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() + ePoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; + newPStart.y = wallBaseLine.y1 + + findPoints.push({ x: ePoint.x, y: ePoint.y }); + const newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() + const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() + const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() + let idx = (0 > index - 1)?roofLines.length:index + const pLineX = roofLines[idx-1].x1 + + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: ePoint.x, y: ePoint.y }, 'blue') + getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') + + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } + } + + if(isStartEnd.end) { + newPStart.y = roofLine.y1; + newPStart.x = roofLine.x1; + + const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() + ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; + newPEnd.y = wallBaseLine.y2 + + findPoints.push({ x: ePoint.x, y: ePoint.y }); + const newPointX = Big(roofLine.x1).plus(moveDist).toNumber() + const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() + const pLineY = Big(roofLine.y2).minus(0).abs().toNumber() + let idx = (roofLines.length < index + 1)?0:index + const pLineX = roofLines[idx+1].x2 + + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y }, 'blue') + getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange') + + if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } + //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') + } + break; + case 'left_out': + if(isStartEnd.start){ + + const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const aStartY = Big(roofLine.y1).minus(moveDist).abs().toNumber() + const bStartY = Big(wallLine.y1).minus(moveDist).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x2 }) + console.log("startLines:::::::", inLine); + const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() + newPEnd.y = aStartY + newPStart.y = Big(roofLine.y2).minus(eLineY).toNumber() + let idx = (0 >= index - 1)?roofLines.length:index + const newLine = roofLines[idx-1]; + if(inLine){ + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: roofLine.y1, x: wallLine.x1 }, 'magenta') + getAddLine({ y: newLine.y1, x: newLine.x1 }, { y: newLine.y2, x: wallLine.x2 }, 'Gray') + findPoints.push({ y: aStartY, x: newPEnd.x }); + } + } + + if(isStartEnd.end){ + const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const aStartY = Big(roofLine.y2).plus(moveDist).toNumber() + const bStartY = Big(wallLine.y2).plus(moveDist).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) + console.log("startLines:::::::", inLine); + const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber() + newPEnd.y = aStartY + newPStart.y = Big(roofLine.y1).plus(eLineY).toNumber() + let idx = (roofLines.length < index + 1)?0:index + const newLine = roofLines[idx+1]; + if(inLine){ + getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } + if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { + getAddLine({ y: bStartY, x: wallLine.x1 }, { y: roofLine.y2, x: wallLine.x2 }, 'magenta') + getAddLine({ y: newLine.y2, x: newLine.x2 }, { y: newLine.y1, x: wallLine.x1 }, 'Gray') + findPoints.push({ y: aStartY, x: newPEnd.x }); + } + + } + break; + case 'right_in': + + if (isStartEnd.start ) { + + newPEnd.y = roofLine.y2; + newPEnd.x = roofLine.x2; + + const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() + ePoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; + newPStart.y = wallBaseLine.y1 + + findPoints.push({ x: ePoint.x, y: ePoint.y }); + const newPointX = Big(roofLine.x1).minus(moveDist).abs().toNumber() + const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() + const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() + let idx = (0 >= index - 1)?roofLines.length:index + const pLineX = roofLines[idx-1].x1 + + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: ePoint.x, y: ePoint.y }, 'blue') + //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') + + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } + } + + if(isStartEnd.end) { + newPStart.y = roofLine.y1; + newPStart.x = roofLine.x1; + + const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() + ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; + newPEnd.y = wallBaseLine.y2 + + findPoints.push({ x: ePoint.x, y: ePoint.y }); + const newPointX = Big(roofLine.x1).minus(moveDist).toNumber() + const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() + const pLineY = Big(roofLine.y2).minus(0).abs().toNumber() + let idx = (roofLines.length < index + 1)?0:index + const pLineX = roofLines[idx+1].x2 + + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y }, 'blue') + getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange') + + if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') + getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') + } + getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') + } + + + + break; + case 'right_out': + + + if (isStartEnd.start ) { + const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const aStartY = Big(roofLine.y1).plus(moveDist).toNumber() + const bStartY = Big(wallLine.y1).plus(moveDist).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x2 }) + console.log("startLines:::::::", inLine); + const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() + newPEnd.y = aStartY + newPStart.y = Big(roofLine.y2).plus(eLineY).toNumber() + let idx = (0 >= index - 1)?roofLines.length:index + const newLine = roofLines[idx-1]; + if(inLine){ + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: roofLine.y1, x: wallLine.x1 }, 'magenta') + getAddLine({ y: newLine.y1, x: newLine.x1 }, { y: newLine.y2, x: wallLine.x2 }, 'Gray') + findPoints.push({ y: aStartY, x: newPEnd.x }); + } + + } + + if(isStartEnd.end){ + const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const aStartY = Big(roofLine.y2).minus(moveDist).abs().toNumber() + const bStartY = Big(wallLine.y2).minus(moveDist).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) + console.log("startLines:::::::", inLine); + const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber() + newPEnd.y = aStartY + newPStart.y = Big(roofLine.y1).minus(eLineY).toNumber() + let idx = (roofLines.length < index + 1)?0:index + const newLine = roofLines[idx+1]; + if(inLine){ + getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } + if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { + getAddLine({ y: bStartY, x: wallLine.x1 }, { y: roofLine.y2, x: wallLine.x2 }, 'magenta') + getAddLine({ y: newLine.y2, x: newLine.x2 }, { y: newLine.y1, x: wallLine.x1 }, 'Gray') + findPoints.push({ y: aStartY, x: newPEnd.x }); + } + } + break; + } } - const positionType = - (mLine.position === 'left' && wallLine.x1 < wallBaseLine.x1) || - (mLine.position === 'right' && wallLine.x1 > wallBaseLine.x1) - ? 'in' : 'out'; - const condition = `${mLine.position}_${positionType}`; - let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines) - let sPoint, ePoint; - switch (condition) { - case 'left_in': - isIn = true - if (isStartEnd.start ) { - newPEnd.y = roofLine.y2; - newPEnd.x = roofLine.x2; - const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() - ePoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; - newPStart.y = wallBaseLine.y1 + } else if (getOrientation(roofLine) === 'horizontal') { //red - findPoints.push({ x: ePoint.x, y: ePoint.y }); - const newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() - const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() - const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() - let idx = (0 > index - 1)?roofLines.length:index - const pLineX = roofLines[idx-1].x1 + if (['top', 'bottom'].includes(mLine.position)) { + if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1) { + return false + } + const positionType = + (mLine.position === 'top' && wallLine.y1 < wallBaseLine.y1) || + (mLine.position === 'bottom' && wallLine.y1 > wallBaseLine.y1) + ? 'in' : 'out'; - getAddLine({ x: newPStart.x, y: newPStart.y }, { x: ePoint.x, y: ePoint.y }, 'blue') - getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') + const condition = `${mLine.position}_${positionType}`; + let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines) - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') - } - } + let sPoint, ePoint; - if(isStartEnd.end) { - newPStart.y = roofLine.y1; - newPStart.x = roofLine.x1; + switch (condition) { + case 'top_in': - const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() - ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; - newPEnd.y = wallBaseLine.y2 + console.log("findInteriorPoint result:::::::", isStartEnd); - findPoints.push({ x: ePoint.x, y: ePoint.y }); - const newPointX = Big(roofLine.x1).plus(moveDist).toNumber() - const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() - const pLineY = Big(roofLine.y2).minus(0).abs().toNumber() - let idx = (roofLines.length < index + 1)?0:index - const pLineX = roofLines[idx+1].x2 - getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y }, 'blue') - getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange') + if (isStartEnd.start ) { + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; + newPStart.x = wallBaseLine.x1; - if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') - } - //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') - } - break; - case 'left_out': - if(isStartEnd.start){ - const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const aStartY = Big(roofLine.y1).minus(moveDist).abs().toNumber() - const bStartY = Big(wallLine.y1).minus(moveDist).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x2 }) - console.log("startLines:::::::", inLine); - const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() - newPEnd.y = aStartY - newPStart.y = Big(roofLine.y2).minus(eLineY).toNumber() - let idx = (0 >= index - 1)?roofLines.length:index - const newLine = roofLines[idx-1]; - if(inLine){ - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: roofLine.y1, x: wallLine.x1 }, 'magenta') - getAddLine({ y: newLine.y1, x: newLine.x1 }, { y: newLine.y2, x: wallLine.x2 }, 'Gray') - findPoints.push({ y: aStartY, x: newPEnd.x }); - } - } + const newPointY = Big(roofLine.y2).plus(moveDist).toNumber() - if(isStartEnd.end){ - const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const aStartY = Big(roofLine.y2).plus(moveDist).toNumber() - const bStartY = Big(wallLine.y2).plus(moveDist).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) - console.log("startLines:::::::", inLine); - const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber() - newPEnd.y = aStartY - newPStart.y = Big(roofLine.y1).plus(eLineY).toNumber() - let idx = (roofLines.length < index + 1)?0:index - const newLine = roofLines[idx+1]; - if(inLine){ - getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') - } - if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ y: bStartY, x: wallLine.x1 }, { y: roofLine.y2, x: wallLine.x2 }, 'magenta') - getAddLine({ y: newLine.y2, x: newLine.x2 }, { y: newLine.y1, x: wallLine.x1 }, 'Gray') - findPoints.push({ y: aStartY, x: newPEnd.x }); + const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() + const pLineX = Big(roofLine.x1).minus(0).abs().toNumber() + let idx = (0 >= index - 1)?roofLines.length:index + const pLineY = roofLines[idx-1].y1 + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y }); + + if(Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } + //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') } - } - break; - case 'right_in': + if(isStartEnd.end){ + const moveDist = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + sPoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } + newPEnd.x = wallBaseLine.x2 - if (isStartEnd.start ) { + const newPointY = Big(roofLine.y1).plus(moveDist).toNumber() - newPEnd.y = roofLine.y2; - newPEnd.x = roofLine.x2; + const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() + const pLineX = Big(roofLine.x2).minus(0).abs().toNumber() + let idx = roofLines.length < index + 1 ? 0 : index + const pLineY = roofLines[idx + 1].y2 + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y }) - const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() - ePoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; - newPStart.y = wallBaseLine.y1 - - findPoints.push({ x: ePoint.x, y: ePoint.y }); - const newPointX = Big(roofLine.x1).minus(moveDist).abs().toNumber() - const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() - const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() - let idx = (0 >= index - 1)?roofLines.length:index - const pLineX = roofLines[idx-1].x1 - - getAddLine({ x: newPStart.x, y: newPStart.y }, { x: ePoint.x, y: ePoint.y }, 'blue') - //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') - - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') - } - } - - if(isStartEnd.end) { - newPStart.y = roofLine.y1; - newPStart.x = roofLine.x1; - - const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() - ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; - newPEnd.y = wallBaseLine.y2 - - findPoints.push({ x: ePoint.x, y: ePoint.y }); - const newPointX = Big(roofLine.x1).minus(moveDist).toNumber() - const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber() - const pLineY = Big(roofLine.y2).minus(0).abs().toNumber() - let idx = (roofLines.length < index + 1)?0:index - const pLineX = roofLines[idx+1].x2 - - getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y }, 'blue') - getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange') - - if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') - getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink') - } - getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: newPointX, y: roofLine.y2 }, 'orange') - } - - - - break; - case 'right_out': - - - if (isStartEnd.start ) { - const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const aStartY = Big(roofLine.y1).plus(moveDist).toNumber() - const bStartY = Big(wallLine.y1).plus(moveDist).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x2 }) - console.log("startLines:::::::", inLine); - const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() - newPEnd.y = aStartY - newPStart.y = Big(roofLine.y2).plus(eLineY).toNumber() - let idx = (0 >= index - 1)?roofLines.length:index - const newLine = roofLines[idx-1]; - if(inLine){ - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: roofLine.y1, x: wallLine.x1 }, 'magenta') - getAddLine({ y: newLine.y1, x: newLine.x1 }, { y: newLine.y2, x: wallLine.x2 }, 'Gray') - findPoints.push({ y: aStartY, x: newPEnd.x }); + if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } + //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') } - } + break; + case 'top_out': + //console.log("findInteriorPoint result:::::::", isStartEnd); + if (isStartEnd.start ) { + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const aStartX = Big(roofLine.x1).plus(moveDist).toNumber() + const bStartX = Big(wallLine.x1).plus(moveDist).toNumber() + const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y }) + console.log("startLines:::::::", inLine); + const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() + newPEnd.x = Big(newPEnd.x).plus(eLineX).toNumber() + newPStart.x = aStartX + let idx = (0 > index - 1)?roofLines.length:index + const newLine = roofLines[idx-1]; + if(inLine){ + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x1, y: wallLine.y1 }, 'magenta') + getAddLine({ x: newLine.x1, y: newLine.y1 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') + findPoints.push({ x: aStartX, y: newPEnd.y }); + } + } + if(isStartEnd.end){ + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const aStartX = Big(roofLine.x2).minus(moveDist).abs().toNumber() + const bStartX = Big(wallLine.x2).minus(moveDist).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y }) + console.log("startLines:::::::", inLine); + const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber() + newPStart.x = Big(newPStart.x).minus(eLineX).abs().toNumber() + newPEnd.x = aStartX + let idx = (roofLines.length < index + 1)?0:index + const newLine = roofLines[idx+1]; + if(inLine){ + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta') + getAddLine({ x: newLine.x2, y: newLine.y2 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') + findPoints.push({ x: aStartX, y: newPEnd.y }); + } + } + break; + case 'bottom_in': - if(isStartEnd.end){ - const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const aStartY = Big(roofLine.y2).minus(moveDist).abs().toNumber() - const bStartY = Big(wallLine.y2).minus(moveDist).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) - console.log("startLines:::::::", inLine); - const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber() - newPEnd.y = aStartY - newPStart.y = Big(roofLine.y1).minus(eLineY).toNumber() - let idx = (roofLines.length < index + 1)?0:index - const newLine = roofLines[idx+1]; - if(inLine){ - getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + if (isStartEnd.start ) { + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; + newPStart.x = wallBaseLine.x1; + + + const newPointY = Big(roofLine.y2).minus(moveDist).toNumber() + + const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() + const pLineX = Big(roofLine.x1).minus(0).abs().toNumber() + let idx = (0 > index - 1)?roofLines.length:index + const pLineY = roofLines[idx-1].y1 + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y }); + + if(Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } + getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') } - if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { - getAddLine({ y: bStartY, x: wallLine.x1 }, { y: roofLine.y2, x: wallLine.x2 }, 'magenta') - getAddLine({ y: newLine.y2, x: newLine.x2 }, { y: newLine.y1, x: wallLine.x1 }, 'Gray') - findPoints.push({ y: aStartY, x: newPEnd.x }); + + if(isStartEnd.end){ + const moveDist = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + sPoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; + newPEnd.x = wallBaseLine.x2; + + + const newPointY = Big(roofLine.y1).minus(moveDist).toNumber() + + const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() + const pLineX = Big(roofLine.x2).minus(0).abs().toNumber() + let idx = (roofLines.length < index + 1)?0:index + const pLineY = roofLines[idx+1].y2 + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y }); + + if(Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { + getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') + getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') + } + getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') + } - } - break; - } - } - - - } else if (getOrientation(roofLine) === 'horizontal') { //red - - if (['top', 'bottom'].includes(mLine.position)) { - if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1) { - return false - } - const positionType = - (mLine.position === 'top' && wallLine.y1 < wallBaseLine.y1) || - (mLine.position === 'bottom' && wallLine.y1 > wallBaseLine.y1) - ? 'in' : 'out'; - - const condition = `${mLine.position}_${positionType}`; - let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines) - - let sPoint, ePoint; - - switch (condition) { - case 'top_in': - - console.log("findInteriorPoint result:::::::", isStartEnd); - - - if (isStartEnd.start ) { - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; - newPStart.x = wallBaseLine.x1; - - - const newPointY = Big(roofLine.y2).plus(moveDist).toNumber() - - const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() - const pLineX = Big(roofLine.x1).minus(0).abs().toNumber() - let idx = (0 >= index - 1)?roofLines.length:index - const pLineY = roofLines[idx-1].y1 - getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') - findPoints.push({ x: sPoint.x, y: sPoint.y }); - - if(Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') - } - //getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') - } - - if(isStartEnd.end){ - const moveDist = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() - sPoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } - newPEnd.x = wallBaseLine.x2 - - const newPointY = Big(roofLine.y1).plus(moveDist).toNumber() - - const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() - const pLineX = Big(roofLine.x2).minus(0).abs().toNumber() - let idx = roofLines.length < index + 1 ? 0 : index - const pLineY = roofLines[idx + 1].y2 - getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') - findPoints.push({ x: sPoint.x, y: sPoint.y }) - - if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') - } - //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') - } - - break; - case 'top_out': - //console.log("findInteriorPoint result:::::::", isStartEnd); - if (isStartEnd.start ) { - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const aStartX = Big(roofLine.x1).plus(moveDist).toNumber() - const bStartX = Big(wallLine.x1).plus(moveDist).toNumber() - const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y }) - console.log("startLines:::::::", inLine); - const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() - newPEnd.x = Big(newPEnd.x).plus(eLineX).toNumber() - newPStart.x = aStartX - let idx = (0 > index - 1)?roofLines.length:index - const newLine = roofLines[idx-1]; - if(inLine){ - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x1, y: wallLine.y1 }, 'magenta') - getAddLine({ x: newLine.x1, y: newLine.y1 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') - findPoints.push({ x: aStartX, y: newPEnd.y }); - } - } - if(isStartEnd.end){ - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const aStartX = Big(roofLine.x2).minus(moveDist).abs().toNumber() - const bStartX = Big(wallLine.x2).minus(moveDist).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y }) - console.log("startLines:::::::", inLine); - const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber() - newPStart.x = Big(newPStart.x).minus(eLineX).abs().toNumber() - newPEnd.x = aStartX - let idx = (roofLines.length < index + 1)?0:index - const newLine = roofLines[idx+1]; - if(inLine){ - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta') - getAddLine({ x: newLine.x2, y: newLine.y2 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') - findPoints.push({ x: aStartX, y: newPEnd.y }); - } - } - break; - case 'bottom_in': - - if (isStartEnd.start ) { - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1}; - newPStart.x = wallBaseLine.x1; - - - const newPointY = Big(roofLine.y2).minus(moveDist).toNumber() - - const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() - const pLineX = Big(roofLine.x1).minus(0).abs().toNumber() - let idx = (0 > index - 1)?roofLines.length:index - const pLineY = roofLines[idx-1].y1 - getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') - findPoints.push({ x: sPoint.x, y: sPoint.y }); - - if(Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') - } - getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange') - } - - if(isStartEnd.end){ - const moveDist = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() - sPoint = {x: wallBaseLine.x2, y: wallBaseLine.y2}; - newPEnd.x = wallBaseLine.x2; - - - const newPointY = Big(roofLine.y1).minus(moveDist).toNumber() - - const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber() - const pLineX = Big(roofLine.x2).minus(0).abs().toNumber() - let idx = (roofLines.length < index + 1)?0:index - const pLineY = roofLines[idx+1].y2 - getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') - findPoints.push({ x: sPoint.x, y: sPoint.y }); - - if(Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - getAddLine({ x: pLineX, y: pLineY }, { x: pLineX, y: newPointY }, 'green') - getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink') - } - getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') - - } - - break; - case 'bottom_out': - - if (isStartEnd.start ) { - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const aStartX = Big(roofLine.x1).minus(moveDist).abs().toNumber() - const bStartX = Big(wallLine.x1).minus(moveDist).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 }) - console.log("startLines:::::::", inLine); - const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() - newPEnd.x = Big(roofLine.x2).minus(eLineX).toNumber() - newPStart.x = aStartX - let idx = (0 > index - 1)?roofLines.length:index - const newLine = roofLines[idx-1]; - - if(inLine){ - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x1, y: wallLine.y1 }, 'magenta') - getAddLine({ x: newLine.x1, y: newLine.y1 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') - findPoints.push({ x: aStartX, y: newPEnd.y }); - } - } - - if(isStartEnd.end){ - const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() - const aStartX = Big(roofLine.x2).plus(moveDist).toNumber() - const bStartX = Big(wallLine.x2).plus(moveDist).toNumber() - const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 }) - console.log("startLines:::::::", inLine); - const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber() - newPEnd.x = aStartX - newPStart.x = Big(roofLine.x1).plus(eLineX).toNumber() - let idx = (0 > index - 1)?roofLines.length:index - const newLine = roofLines[idx-1]; - if(inLine){ - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } - if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta') - getAddLine({ x: newLine.x2, y: newLine.y2 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') - findPoints.push({ x: aStartX, y: newPEnd.y }); - } - } - break; + + break; + case 'bottom_out': + + if (isStartEnd.start ) { + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const aStartX = Big(roofLine.x1).minus(moveDist).abs().toNumber() + const bStartX = Big(wallLine.x1).minus(moveDist).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 }) + console.log("startLines:::::::", inLine); + const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() + newPEnd.x = Big(roofLine.x2).minus(eLineX).toNumber() + newPStart.x = aStartX + let idx = (0 > index - 1)?roofLines.length:index + const newLine = roofLines[idx-1]; + + if(inLine){ + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x1, y: wallLine.y1 }, 'magenta') + getAddLine({ x: newLine.x1, y: newLine.y1 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') + findPoints.push({ x: aStartX, y: newPEnd.y }); + } + } + + if(isStartEnd.end){ + const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const aStartX = Big(roofLine.x2).plus(moveDist).toNumber() + const bStartX = Big(wallLine.x2).plus(moveDist).toNumber() + const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 }) + console.log("startLines:::::::", inLine); + const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber() + newPEnd.x = aStartX + newPStart.x = Big(roofLine.x1).plus(eLineX).toNumber() + let idx = (0 > index - 1)?roofLines.length:index + const newLine = roofLines[idx-1]; + if(inLine){ + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } + if(Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta') + getAddLine({ x: newLine.x2, y: newLine.y2 }, { x: newLine.x1, y: wallLine.y1 }, 'Gray') + findPoints.push({ x: aStartX, y: newPEnd.y }); + } + } + break; + } } } + getAddLine(newPStart, newPEnd, 'red') } - getAddLine(newPStart, newPEnd, 'red') - } - canvas.renderAll() - }); -} + canvas.renderAll() + }); + } if (findPoints.length > 0) { // 모든 점에 대해 라인 업데이트를 누적 @@ -1321,8 +1321,8 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) { ); if(!outerLine) { - outerLine = findMatchingLine(edgeResult.Polygon, roof, roof.points); - console.log('Has matching line:', outerLine); + outerLine = findMatchingLine(edgeResult.Polygon, roof, roof.points); + console.log('Has matching line:', outerLine); } let pitch = outerLine?.attributes?.pitch??0 @@ -1357,7 +1357,7 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) { //console.log('clipped line', clippedLine.p1, clippedLine.p2); const isOuterLine = isOuterEdge(clippedLine.p1, clippedLine.p2, [edgeResult.Edge]) addRawLine(roof.id, skeletonLines, clippedLine.p1, clippedLine.p2, 'ridge', '#1083E3', 4, pitch, isOuterLine); - // } + // } } } @@ -2017,6 +2017,7 @@ export { + /** * Finds the opposite line in a polygon based on the given line * @param {Array} edges - The polygon edges from canvas.skeleton.Edges @@ -2102,19 +2103,19 @@ function getLinePosition(line, referenceLine) { // 대상선의 중점 const lineMidX = (line.start.x + line.end.x) / 2; const lineMidY = (line.start.y + line.end.y) / 2; - + // 참조선의 중점 const refMidX = (referenceLine.start.x + referenceLine.end.x) / 2; const refMidY = (referenceLine.start.y + referenceLine.end.y) / 2; - + // 단순히 좌표 차이로 판단 const deltaX = lineMidX - refMidX; const deltaY = lineMidY - refMidY; - + // 참조선의 기울기 const refDeltaX = referenceLine.end.x - referenceLine.start.x; const refDeltaY = referenceLine.end.y - referenceLine.start.y; - + // 참조선이 더 수평인지 수직인지 판단 if (Math.abs(refDeltaX) > Math.abs(refDeltaY)) { // 수평선에 가까운 경우 - Y 좌표로 판단 @@ -2187,7 +2188,7 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) { // p1이 다각형 내부에 있는지 확인 const p1Inside = isPointInsidePolygon(p1, roofLines); - + // p2가 다각형 내부에 있는지 확인 const p2Inside = isPointInsidePolygon(p2, roofLines); @@ -2204,7 +2205,7 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) { // 선분과 다각형 경계선의 교차점들을 찾음 const intersections = []; - + for (const line of roofLines) { const lineP1 = { x: line.x1, y: line.y1 }; const lineP2 = { x: line.x2, y: line.y2 }; @@ -2267,7 +2268,6 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) { } - function isPointInsidePolygon(point, roofLines) { // 1. 먼저 경계선 위에 있는지 확인 (방향 무관) if (isOnBoundaryDirectionIndependent(point, roofLines)) { @@ -2338,14 +2338,14 @@ function isPointOnLineSegmentDirectionIndependent(point, line, tolerance) { * 선분 위의 점에 대한 매개변수 t를 계산합니다. * p = p1 + t * (p2 - p1)에서 t 값을 구합니다. * @param {Object} p1 - 선분의 시작점 - * @param {Object} p2 - 선분의 끝점 + * @param {Object} p2 - 선분의 끝점 * @param {Object} point - 선분 위의 점 * @returns {number} 매개변수 t (0이면 p1, 1이면 p2) */ function getParameterT(p1, p2, point) { const dx = p2.x - p1.x; const dy = p2.y - p1.y; - + // x 좌표가 더 큰 변화를 보이면 x로 계산, 아니면 y로 계산 if (Math.abs(dx) > Math.abs(dy)) { return dx === 0 ? 0 : (point.x - p1.x) / dx; @@ -2387,6 +2387,81 @@ function getLineDirection(p1, p2) { +/** + * 점이 선분 위에 있는지 확인하는 헬퍼 함수 + * @param {Object} point - 확인할 점 {x, y} + * @param {Object} lineStart - 선분의 시작점 {x, y} + * @param {Object} lineEnd - 선분의 끝점 {x, y} + * @param {number} epsilon - 허용 오차 + * @returns {boolean} + */ +// function isPointOnLineSegment(point, lineStart, lineEnd, epsilon = 0.1) { +// const dx = lineEnd.x - lineStart.x; +// const dy = lineEnd.y - lineStart.y; +// const length = Math.sqrt(dx * dx + dy * dy); +// +// if (length === 0) { +// // 선분의 길이가 0이면 시작점과의 거리만 확인 +// return Math.abs(point.x - lineStart.x) < epsilon && Math.abs(point.y - lineStart.y) < epsilon; +// } +// +// // 점에서 선분의 시작점까지의 벡터 +// const toPoint = { x: point.x - lineStart.x, y: point.y - lineStart.y }; +// +// // 선분 방향으로의 투영 길이 +// const t = (toPoint.x * dx + toPoint.y * dy) / (length * length); +// +// // t가 0과 1 사이에 있어야 선분 위에 있음 +// if (t < 0 || t > 1) { +// return false; +// } +// +// // 선분 위의 가장 가까운 점 +// const closestPoint = { +// x: lineStart.x + t * dx, +// y: lineStart.y + t * dy +// }; +// +// // 점과 가장 가까운 점 사이의 거리 +// const dist = Math.sqrt( +// Math.pow(point.x - closestPoint.x, 2) + +// Math.pow(point.y - closestPoint.y, 2) +// ); +// +// return dist < epsilon; +// } + +// selectLine과 baseLines 비교하여 방향 찾기 +function findLineDirection(selectLine, baseLines) { + for (const baseLine of baseLines) { + // baseLine의 시작점과 끝점 + const baseStart = baseLine.startPoint; + const baseEnd = baseLine.endPoint; + + // selectLine의 시작점과 끝점 + const selectStart = selectLine.startPoint; + const selectEnd = selectLine.endPoint; + + // 정방향 또는 역방향으로 일치하는지 확인 + if ((isSamePoint(baseStart, selectStart) && isSamePoint(baseEnd, selectEnd)) || + (isSamePoint(baseStart, selectEnd) && isSamePoint(baseEnd, selectStart))) { + + // baseLine의 방향 계산 + const dx = baseEnd.x - baseStart.x; + const dy = baseEnd.y - baseStart.y; + + // 기울기를 바탕으로 방향 판단 + if (Math.abs(dx) > Math.abs(dy)) { + return dx > 0 ? 'right' : 'left'; + } else { + return dy > 0 ? 'down' : 'up'; + } + } + } + + return null; // 일치하는 라인이 없는 경우 +} + /** * baseLines를 연결하여 다각형 순서로 정렬된 점들 반환 @@ -2709,89 +2784,54 @@ const analyzeLineOrientation = (x1, y1, x2, y2, epsilon = 0.5) => { }; }; -function extendLineToBoundary(p1, p2, roofLines) { - // 1. Calculate line direction and length - const dx = p2.x - p1.x; - const dy = p2.y - p1.y; - const length = Math.sqrt(dx * dx + dy * dy); - if (length === 0) return { p1: { ...p1 }, p2: { ...p2 } }; - // 2. Get all polygon points - const points = []; - const seen = new Set(); +// 점에서 선분까지의 최단 거리를 계산하는 도우미 함수 +function pointToLineDistance(point, lineP1, lineP2) { + const A = point.x - lineP1.x; + const B = point.y - lineP1.y; + const C = lineP2.x - lineP1.x; + const D = lineP2.y - lineP1.y; - for (const line of roofLines) { - const p1 = { x: line.x1, y: line.y1 }; - const p2 = { x: line.x2, y: line.y2 }; + const dot = A * C + B * D; + const lenSq = C * C + D * D; + let param = -1; - const key1 = `${p1.x},${p1.y}`; - const key2 = `${p2.x},${p2.y}`; - - if (!seen.has(key1)) { - points.push(p1); - seen.add(key1); - } - if (!seen.has(key2)) { - points.push(p2); - seen.add(key2); - } + if (lenSq !== 0) { + param = dot / lenSq; } - // 3. Find the bounding box - let minX = Infinity, minY = Infinity; - let maxX = -Infinity, maxY = -Infinity; + let xx, yy; - for (const p of points) { - minX = Math.min(minX, p.x); - minY = Math.min(minY, p.y); - maxX = Math.max(maxX, p.x); - maxY = Math.max(maxY, p.y); + if (param < 0) { + xx = lineP1.x; + yy = lineP1.y; + } else if (param > 1) { + xx = lineP2.x; + yy = lineP2.y; + } else { + xx = lineP1.x + param * C; + yy = lineP1.y + param * D; } - // 4. Extend line to bounding box - const bboxLines = [ - { x1: minX, y1: minY, x2: maxX, y2: minY }, // top - { x1: maxX, y1: minY, x2: maxX, y2: maxY }, // right - { x1: maxX, y1: maxY, x2: minX, y2: maxY }, // bottom - { x1: minX, y1: maxY, x2: minX, y2: minY } // left - ]; - - const intersections = []; - - // 5. Find intersections with bounding box - for (const line of bboxLines) { - const intersect = getLineIntersection( - p1, p2, - { x: line.x1, y: line.y1 }, - { x: line.x2, y: line.y2 } - ); - - if (intersect) { - const t = ((intersect.x - p1.x) * dx + (intersect.y - p1.y) * dy) / (length * length); - if (t >= 0 && t <= 1) { - intersections.push({ x: intersect.x, y: intersect.y, t }); - } - } - } - - // 6. If we have two intersections, use them - if (intersections.length >= 2) { - // Sort by t value - intersections.sort((a, b) => a.t - b.t); - return { - p1: { x: intersections[0].x, y: intersections[0].y }, - p2: { - x: intersections[intersections.length - 1].x, - y: intersections[intersections.length - 1].y - } - }; - } - - // 7. Fallback to original points - return { p1: { ...p1 }, p2: { ...p2 } }; + const dx = point.x - xx; + const dy = point.y - yy; + return Math.sqrt(dx * dx + dy * dy); } +const getOrientation = (line, eps = 0.1) => { + const x1 = line.get('x1') + const y1 = line.get('y1') + const x2 = line.get('x2') + const y2 = line.get('y2') + const dx = Math.abs(x2 - x1) + const dy = Math.abs(y2 - y1) + + if (dx < eps && dy >= eps) return 'vertical' + if (dy < eps && dx >= eps) return 'horizontal' + if (dx < eps && dy < eps) return 'point' + return 'diagonal' +} @@ -2975,9 +3015,35 @@ function updateAndAddLine(innerLines, targetPoint) { +/** + * 점이 선분 위에 있는지 확인 + * @param {Object} point - 확인할 점 {x, y} + * @param {Object} lineStart - 선분의 시작점 {x, y} + * @param {Object} lineEnd - 선분의 끝점 {x, y} + * @param {number} tolerance - 오차 허용 범위 + * @returns {boolean} - 점이 선분 위에 있으면 true, 아니면 false + */ +function isPointOnLineSegment2(point, lineStart, lineEnd, tolerance = 0.1) { + const { x: px, y: py } = point; + const { x: x1, y: y1 } = lineStart; + const { x: x2, y: y2 } = lineEnd; + // 선분의 길이 + const lineLength = Math.hypot(x2 - x1, y2 - y1); + // 점에서 선분의 양 끝점까지의 거리 + const dist1 = Math.hypot(px - x1, py - y1); + const dist2 = Math.hypot(px - x2, py - y2); + // 점이 선분 위에 있는지 확인 (오차 허용 범위 내에서) + const isOnSegment = Math.abs((dist1 + dist2) - lineLength) <= tolerance; + + if (isOnSegment) { + console.log(`점 (${px}, ${py})은 선분 [(${x1}, ${y1}), (${x2}, ${y2})] 위에 있습니다.`); + } + + return isOnSegment; +} /** * 세 점(p1 -> p2 -> p3)의 방향성을 계산합니다. (2D 외적)