From 8289f7feef2e795f9ab759e414137cec57d7c1a4 Mon Sep 17 00:00:00 2001 From: yscha Date: Sun, 21 Dec 2025 00:15:18 +0900 Subject: [PATCH] =?UTF-8?q?skt=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/skeleton-utils.js | 1790 ++++++++++++++++++------------------ 1 file changed, 906 insertions(+), 884 deletions(-) diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index 32d8bd9e..1599bd84 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -494,29 +494,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { } }); - /* - //2. 연결이 끊어진 스켈레톤 선을 찾아 연장합니다. - const { disconnectedLines } = findDisconnectedSkeletonLines(skeletonLines, roof.lines); - 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 }; - } - }); - - //2-1 확장된 스켈레톤 선이 연장되다가 서로 만나면 만난점(접점)에서 멈추어야 된다. - trimIntersectingExtendedLines(skeletonLines, disconnectedLines); - - } - */ //2. 연결이 끊어진 라인이 있을경우 찾아서 추가한다(동 이동일때) @@ -549,17 +527,6 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { { x: sktLine.p2.x, y: sktLine.p2.y } ); - //그림을 그릴때 idx 가 필요함 roof는 왼쪽부터 시작됨 - 그림그리는 순서가 필요함 - - - // roofLines.forEach((roofLine) => { - // - // if (isSameLine(p1.x, p1.y, p2.x, p2.y, roofLine) || isSameLine(p2.x, p2.y, p1.x, p1.y, roofLine)) { - // roofIdx = roofLine.idx; - // console.log("roofIdx::::::", roofIdx) - // return false; // forEach 중단 - // } - // }); const skeletonLine = new QLine([p1.x, p1.y, p2.x, p2.y], { @@ -607,657 +574,651 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { if (Math.abs(roof.moveUpDown ?? 0) > 0 || Math.abs(roof.moveFlowLine ?? 0) > 0) { const getMoveUpDownLine = () => { - // 같은 라인이 없으므로 새 다각형 라인 생성 - //라인 편집 - // 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]; - } - } - return 0; - }); - } - - - // 각 라인 집합 정렬 - - // 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 - }; + // 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 + }) } - return sourceLine; - }); - }; + // 각 라인 집합 정렬 + const sortWallLines = ensureCounterClockwiseLines(wallLines) + const sortWallBaseLines = ensureCounterClockwiseLines(wall.baseLines) + const sortRoofLines = ensureCounterClockwiseLines(roofLines) - console.log("wallBaseLines", wall.baseLines) - // 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) - // const sortedBaseLines = sortBaseLinesByWallLines(wall.baseLines, wallLines); - const sortRoofLines = sortBaseLinesByWallLines(roofLines, wallLines); + // 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) - // 원본 wallLines를 복사하여 사용 - const sortedWallLines = [...wallLines]; - const sortedBaseLines = sortBaseLinesByWallLines(wall.baseLines, sortedWallLines); - const sortedRoofLines = sortBaseLinesByWallLines(roofLines, sortedWallLines); + return !nearest || distance < nearest.distance ? { line: targetLine, distance } : nearest + }, null)?.line - //wall.lines 는 기본 벽 라인 - //wall.baseLine은 움직인라인 - const movedLines = [] + if (!nearestTarget) return sourceLine - // 조건에 맞는 라인들만 필터링 - const validWallLines = [...wallLines] - .sort((a, b) => a.idx - b.idx) - .filter((wallLine, index) => wallLine.idx - 1 === index); + // 방향이 반대인지 확인 (벡터 내적을 사용) + const sourceVec = { + x: sourceLine.x2 - sourceLine.x1, + y: sourceLine.y2 - sourceLine.y1, + } + const targetVec = { + x: nearestTarget.x2 - nearestTarget.x1, + y: nearestTarget.y2 - nearestTarget.y1, + } - wallLines.length > 3 && wallLines.forEach((wallLine, index) => { - const originalIndex = wallLines.indexOf(wallLine) - const roofLine = sortRoofLines[originalIndex] - const currentRoofLine = currentRoofLines[originalIndex] - const moveLine = wall.baseLines[originalIndex] - const wallBaseLine = wall.baseLines[originalIndex] + const dotProduct = sourceVec.x * targetVec.x + sourceVec.y * targetVec.y - // const roofLine = sortRoofLines[index]; + // 내적이 음수이면 방향이 반대이므로 뒤집기 + if (dotProduct < 0) { + return { + ...sourceLine, + x1: sourceLine.x2, + y1: sourceLine.y2, + x2: sourceLine.x1, + y2: sourceLine.y1, + } + } - // if (roofLine.attributes.wallLine !== wallLine.id || (roofLine.idx - 1) !== index) { - // console.log("wallLine2::::", wallLine.id) - // console.log('roofLine:::', roofLine.attributes.wallLine) - // console.log("w:::", wallLine.startPoint, wallLine.endPoint) - // console.log("R:::", roofLine.startPoint, roofLine.endPoint) - // console.log("not matching roofLine", roofLine); - // return false - // }//roofLines.find(line => line.attributes.wallLineId === wallLine.attributes.wallId); + return sourceLine + }) + } - // const currentRoofLine = currentRoofLines[index]; - // const moveLine = wall.baseLines[index] - // const wallBaseLine = wall.baseLines[index] - //console.log("wallBaseLine", wallBaseLine); + console.log('wallBaseLines', wall.baseLines) - //roofline 외곽선 설정 - console.log('index::::', index) - console.log('roofLine:::', roofLine) - console.log('wallLine', wallLine) - console.log('wallBaseLine', wallBaseLine) + //wall.baseLine은 움직인라인 + let movedLines = [] - const origin = moveLine.attributes?.originPoint - if (!origin) return + // 조건에 맞는 라인들만 필터링 + const validWallLines = [...wallLines].sort((a, b) => a.idx - b.idx).filter((wallLine, index) => wallLine.idx - 1 === index) - console.log('moveLine:', moveLine.x1, moveLine.y1, moveLine.x2, moveLine.y2) - console.log('wallLine:', wallLine.x1, wallLine.y1, wallLine.x2, wallLine.y2) - console.log('isSamePoint result:', isSameLine2(moveLine, wallLine)) + console.log('', sortRoofLines, sortWallLines, sortWallBaseLines) + sortWallLines.length > 3 && + sortWallLines.forEach((wallLine, index) => { - if (isSameLine2(moveLine, wallLine)) { - return - } + const roofLine = sortRoofLines[index] + const wallBaseLine = sortWallBaseLines[index] - 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 + //roofline 외곽선 설정 - const fullyMoved = movedStart && movedEnd + console.log('index::::', index) + console.log('roofLine:', roofLine.x1, roofLine.y1, roofLine.x2, roofLine.y2) + console.log('wallLine:', wallLine.x1, wallLine.y1, wallLine.x2, wallLine.y2) + console.log('wallBaseLine:', wallBaseLine.x1, wallBaseLine.y1, wallBaseLine.x2, wallBaseLine.y2) + console.log('isSamePoint result:', isSameLine2(wallBaseLine, wallLine)) - //반시계 방향 - let newPStart //= {x:roofLine.x1, y:roofLine.y1} - let newPEnd //= {x:movedLines.x2, y:movedLines.y2} + if (isSameLine2(wallBaseLine, wallLine)) { + return + } - //현재 roof는 무조건 시계방향 + const movedStart = Math.abs(wallBaseLine.x1 - wallLine.x1) > EPSILON || Math.abs(wallBaseLine.y1 - wallLine.y1) > EPSILON + const movedEnd = Math.abs(wallBaseLine.x2 - wallLine.x2) > EPSILON || Math.abs(wallBaseLine.y2 - wallLine.y2) > EPSILON - const getAddLine = (p1, p2, stroke = '') => { - movedLines.push({ index, p1, p2 }) + const fullyMoved = movedStart && movedEnd - // 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: 'black', - strokeWidth: 4, - name: 'eaveHelpLine', - lineName: 'eaveHelpLine', - visible: true, - roofId: roofId, - selectable: true, - hoverCursor: 'pointer', - attributes: { - type: 'eaveHelpLine', - isStart: true, - pitch: wallLine.attributes.pitch, - }, - }) + //반시계 방향 + let newPStart //= {x:roofLine.x1, y:roofLine.y1} + let newPEnd //= {x:movedLines.x2, y:movedLines.y2} - coordinateText(line) - canvas.add(line) - line.bringToFront() - canvas.renderAll() - return line - } + //현재 roof는 무조건 시계방향 - //getAddLine(roofLine.startPoint, roofLine.endPoint, ) //외곽선을 그린다 + const getAddLine = (p1, p2, stroke = '') => { + movedLines.push({ index, p1, p2 }) - newPStart = { x: roofLine.x1, y: roofLine.y1 } - newPEnd = { x: roofLine.x2, y: roofLine.y2 } + //console.log("mergeLines:::::::", mergeLines); + const line = new QLine([p1.x, p1.y, p2.x, p2.y], { + parentId: roof.id, + fontSize: roof.fontSize, + stroke: 'black', + strokeWidth: 4, + name: 'eaveHelpLine', + lineName: 'eaveHelpLine', + visible: true, + roofId: roofId, + selectable: true, + hoverCursor: 'pointer', + attributes: { + type: 'eaveHelpLine', + isStart: true, + pitch: wallLine.attributes.pitch, + }, + }) - const getInnerLines = (lines, point) => {} - let isIn = false - let isOut = false + coordinateText(line) + canvas.add(line) + line.bringToFront() + canvas.renderAll() + return line + } - //두 포인트가 변경된 라인인 - if (fullyMoved) { - //반시계방향향 + //getAddLine(roofLine.startPoint, roofLine.endPoint, ) //외곽선을 그린다 - const mLine = getSelectLinePosition(wall, wallBaseLine) + newPStart = { x: roofLine.x1, y: roofLine.y1 } + newPEnd = { x: roofLine.x2, y: roofLine.y2 } - if (getOrientation(roofLine) === 'vertical') { - if (['left', 'right'].includes(mLine.position)) { - if (Math.abs(wallLine.x1 - wallBaseLine.x1) < 0.1 || Math.abs(wallLine.x2 - wallBaseLine.x2) < 0.1) { - return false - } - const isLeftPosition = mLine.position === 'left' - const isRightPosition = mLine.position === 'right' - const isInPosition = - (isLeftPosition && wallLine.x1 < wallBaseLine.x1) || - (isRightPosition && wallLine.x1 > wallBaseLine.x1) || - (isLeftPosition && wallLine.x2 < wallBaseLine.x2) || - (isRightPosition && wallLine.x2 > wallBaseLine.x2) + const getInnerLines = (lines, point) => {} + let isIn = false + let isOut = false - const positionType = isInPosition ? 'in' : 'out' + //두 포인트가 변경된 라인인 + if (fullyMoved) { + //반시계방향향 - const condition = `${mLine.position}_${positionType}` - let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines) - let sPoint, ePoint - if (condition === 'left_in') { - isIn = true + const mLine = getSelectLinePosition(wall, wallBaseLine) - 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, position: 'left_in_start' }) - const newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() - const pDist = Big(wallLine.x1).minus(roofLine.x1).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 (getOrientation(roofLine) === 'vertical') { + if (['left', 'right'].includes(mLine.position)) { + if (Math.abs(wallLine.x1 - wallBaseLine.x1) < 0.1 || Math.abs(wallLine.x2 - wallBaseLine.x2) < 0.1) { + return false } + const isLeftPosition = mLine.position === 'left' + const isRightPosition = mLine.position === 'right' + const isInPosition = + (isLeftPosition && wallLine.x1 < wallBaseLine.x1) || + (isRightPosition && wallLine.x1 > wallBaseLine.x1) || + (isLeftPosition && wallLine.x2 < wallBaseLine.x2) || + (isRightPosition && wallLine.x2 > wallBaseLine.x2) - if (isStartEnd.end) { - newPStart.y = roofLine.y1 - newPStart.x = roofLine.x1 + const positionType = isInPosition ? 'in' : 'out' - const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() - ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } - newPEnd.y = wallBaseLine.y2 + const condition = `${mLine.position}_${positionType}` + let isStartEnd = findInteriorPoint(wallBaseLine, sortWallBaseLines) + let sPoint, ePoint + if (condition === 'left_in') { + isIn = true - findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'left_in_end' }) - 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).toNumber() - let idx = roofLines.length < index + 1 ? 0 : index - const pLineX = roofLines[idx + 1].x2 + if (isStartEnd.start) { + newPEnd.y = roofLine.y2 + newPEnd.x = roofLine.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') + const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() + ePoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } + newPStart.y = wallBaseLine.y1 - 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') - } - } else if (condition === 'left_out') { - console.log('left_out::::isStartEnd:::::', isStartEnd) - 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 }) + findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'left_in_start' }) + const newPointX = Big(roofLine.x1).plus(moveDist).abs().toNumber() + const pDist = Big(wallLine.x1).minus(roofLine.x1).toNumber() + const pLineY = Big(roofLine.y1).minus(0).abs().toNumber() + // let idx = 0 > index - 1 ? sortRoofLines.length : index + // const pLineX = sortRoofLines[idx - 1].x1 - const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() - newPStart.y = aStartY - newPEnd.y = roofLine.y2 //Big(roofLine.y2).minus(eLineY).toNumber() - let idx = 0 >= index - 1 ? roofLines.length : index - const newLine = roofLines[idx - 1] + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineX = sortRoofLines[prevIndex].x1 - if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - if (inLine) { - if (inLine.x1 < inLine.x2) { - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') - } else { - getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: bStartY, x: wallLine.x2 }, 'pink') - } + 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') } - 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: newPStart.x, position: 'left_out_start' }) - } else { - const cLineY = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() - newPStart.y = Big(newPStart.y).minus(cLineY).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) - if (inLine) { - if (inLine.x1 < inLine.x2) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + + 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, position: 'left_in_end' }) + 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).toNumber() + // let idx = sortRoofLines.length < index + 1 ? 0 : index + // const pLineX = sortRoofLines[idx + 1].x2 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineX = sortRoofLines[nextIndex].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') + } + } else if (condition === 'left_out') { + console.log('left_out::::isStartEnd:::::', isStartEnd) + 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 }) + + const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() + newPStart.y = aStartY + newPEnd.y = roofLine.y2 //Big(roofLine.y2).minus(eLineY).toNumber() + // let idx = 0 >= index - 1 ? sortRoofLines.length : index + // const newLine = sortRoofLines[idx - 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const newLine = sortRoofLines[prevIndex] + + if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + if (inLine) { + if (inLine.x1 < inLine.x2) { + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } else { + getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: bStartY, x: wallLine.x2 }, 'pink') + } } + 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: newPStart.x, position: 'left_out_start' }) } else { - //newPStart.y = wallLine.y1; - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() - newPStart.y = Big(wallBaseLine.y1).minus(rLineM).abs().toNumber() + const cLineY = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() + newPStart.y = Big(newPStart.y).minus(cLineY).toNumber() const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) if (inLine) { - if (inLine.x2 > inLine.x1) { + if (inLine.x1 < inLine.x2) { getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + } else { + //newPStart.y = wallLine.y1; + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() + newPStart.y = Big(wallBaseLine.y1).minus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.x2 > inLine.x1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } } } } } - } - 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 = roofLine.y1 //Big(roofLine.y1).plus(eLineY).toNumber() - let idx = roofLines.length < index + 1 ? 0 : index - const newLine = roofLines[idx + 1] + 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 = roofLine.y1 //Big(roofLine.y1).plus(eLineY).toNumber() + // let idx = sortRoofLines.length < index + 1 ? 0 : index + // const newLine = sortRoofLines[idx + 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[nextIndex] + + + if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { + if (inLine) { + if (inLine.x1 < inLine.x2) { + getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: bStartY, x: wallLine.x1 }, 'pink') + } + } + 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, position: 'left_out_end' }) + } else { + const cLineY = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() + newPEnd.y = Big(newPEnd.y).plus(cLineY).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.x1 < inLine.x2) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } + } else { + // newPEnd.y = wallLine.y2 + + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() + newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.x2 > inLine.x1) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } + } + } + } + findPoints.push({ y: newPStart.y, x: newPEnd.x, position: 'left_out_end' }) + } + } else if (condition === '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, position: 'right_in_start' }) + 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 ? sortRoofLines.length : index + // const pLineX = sortRoofLines[idx - 1].x1 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineX = sortRoofLines[prevIndex].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, position: 'right_in_end' }) + 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 = sortRoofLines.length < index + 1 ? 0 : index + // const pLineX = sortRoofLines[idx + 1].x2 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineX = sortRoofLines[nextIndex].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') + } + } else if (condition === 'right_out') { + console.log('right_out::::isStartEnd:::::', isStartEnd) + if (isStartEnd.start) { + //x1 inside + const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const aStartY = Big(roofLine.y1).plus(moveDist).abs().toNumber() + const bStartY = Big(wallLine.y1).plus(moveDist).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) + console.log('startLines:::::::', inLine) + const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() + newPStart.y = aStartY + newPEnd.y = roofLine.y2 //Big(roofLine.y2).plus(eLineY).toNumber() + // let idx = 0 >= index - 1 ? sortRoofLines.length : index + // const newLine = sortRoofLines[idx - 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const newLine = sortRoofLines[prevIndex] + + if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { + if (inLine) { + if (inLine.x2 < inLine.x1) { + getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: bStartY, x: wallLine.x2 }, 'pink') + } + } + 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, position: 'right_out_start' }) + } else { + const cLineY = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() + newPStart.y = Big(newPStart.y).plus(cLineY).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.x2 < inLine.x1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + } else { + //newPStart.y = wallLine.y1; + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.x1).minus(roofLine.x1).abs().toNumber() + newPStart.y = Big(wallBaseLine.y1).plus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.x2 > inLine.x1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') + } else { + getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + } + } + } + } + + 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 = roofLine.y1 //Big(roofLine.y1).minus(eLineY).toNumber() + // let idx = sortRoofLines.length < index + 1 ? 0 : index + // const newLine = sortRoofLines[idx + 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[nextIndex] - if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { if (inLine) { - if (inLine.x1 < inLine.x2) { + if (inLine.x2 < inLine.x1) { getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') } else { getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: bStartY, x: wallLine.x1 }, 'pink') } } - 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, position: 'left_out_end' }) - } else { - const cLineY = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() - newPEnd.y = Big(newPEnd.y).plus(cLineY).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.x1 < inLine.x2) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') - } + 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, position: 'right_out_end' }) } else { - // newPEnd.y = wallLine.y2 - - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() - newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).abs().toNumber() + const cLineY = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() + newPEnd.y = Big(newPEnd.y).minus(cLineY).toNumber() const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) if (inLine) { - if (inLine.x2 > inLine.x1) { + if (inLine.x2 < inLine.x1) { getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') } else { getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') } - } - } - } - findPoints.push({ y: newPStart.y, x: newPEnd.x, position: 'left_out_end' }) - } - } else if (condition === '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, position: 'right_in_start' }) - 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, position: 'right_in_end' }) - 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') - } - } else if (condition === 'right_out') { - console.log('right_out::::isStartEnd:::::', isStartEnd) - if (isStartEnd.start) { - //x1 inside - const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() - const aStartY = Big(roofLine.y1).plus(moveDist).abs().toNumber() - const bStartY = Big(wallLine.y1).plus(moveDist).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 }) - console.log('startLines:::::::', inLine) - const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber() - newPStart.y = aStartY - newPEnd.y = roofLine.y2 //Big(roofLine.y2).plus(eLineY).toNumber() - let idx = 0 >= index - 1 ? roofLines.length : index - const newLine = roofLines[idx - 1] - - if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) { - if (inLine) { - if (inLine.x2 < inLine.x1) { - getAddLine({ y: bStartY, x: wallLine.x2 }, { y: inLine.y2, x: inLine.x2 }, 'pink') } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: bStartY, x: wallLine.x2 }, 'pink') - } - } - 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, position: 'right_out_start' }) - } else { - const cLineY = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber() - newPStart.y = Big(newPStart.y).plus(cLineY).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) - if (inLine) { - if (inLine.x2 < inLine.x1) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') - } - } else { - //newPStart.y = wallLine.y1; - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.x1).minus(roofLine.x1).abs().toNumber() - newPStart.y = Big(wallBaseLine.y1).plus(rLineM).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) - if (inLine) { - if (inLine.x2 > inLine.x1) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') - } else { - getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPStart.y, x: newPStart.x }, 'purple') - } - } - } - } - } + //newPEnd.y = wallLine.y2; - 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 = roofLine.y1 //Big(roofLine.y1).minus(eLineY).toNumber() - let idx = roofLines.length < index + 1 ? 0 : index - const newLine = roofLines[idx + 1] - if (inLine) { - if (inLine.x2 < inLine.x1) { - getAddLine({ y: bStartY, x: wallLine.x1 }, { y: inLine.y2, x: inLine.x2 }, 'pink') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: bStartY, x: wallLine.x1 }, '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, position: 'right_out_end' }) - } else { - const cLineY = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber() - newPEnd.y = Big(newPEnd.y).minus(cLineY).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.x2 < inLine.x1) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') - } - } else { - //newPEnd.y = wallLine.y2; - - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() - newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.x2 > inLine.x1) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') - } else { - getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber() + newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.x2 > inLine.x1) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') + } else { + getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } } } } } } } - } - } else if (getOrientation(roofLine) === 'horizontal') { - //red + } else if (getOrientation(roofLine) === 'horizontal') { + //red - if (['top', 'bottom'].includes(mLine.position)) { - if (Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1 || Math.abs(wallLine.y2 - wallBaseLine.y2) < 0.1) { - return false - } - const isTopPosition = mLine.position === 'top' - const isBottomPosition = mLine.position === 'bottom' - const isInPosition = - (isTopPosition && wallLine.y1 < wallBaseLine.y1) || - (isBottomPosition && wallLine.y1 > wallBaseLine.y1) || - (isTopPosition && wallLine.y2 < wallBaseLine.y2) || - (isBottomPosition && wallLine.y2 > wallBaseLine.y2) - - const positionType = isInPosition ? 'in' : 'out' - const condition = `${mLine.position}_${positionType}` - let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines) - - let sPoint, ePoint - - if (condition === 'top_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).plus(moveDist).toNumber() - - const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() - const pLineX = Big(roofLine.x1).minus(0).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, position: 'top_in_start' }) - - 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 (['top', 'bottom'].includes(mLine.position)) { + if (Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1 || Math.abs(wallLine.y2 - wallBaseLine.y2) < 0.1) { + return false } + const isTopPosition = mLine.position === 'top' + const isBottomPosition = mLine.position === 'bottom' + const isInPosition = + (isTopPosition && wallLine.y1 < wallBaseLine.y1) || + (isBottomPosition && wallLine.y1 > wallBaseLine.y1) || + (isTopPosition && wallLine.y2 < wallBaseLine.y2) || + (isBottomPosition && wallLine.y2 > wallBaseLine.y2) - 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 positionType = isInPosition ? 'in' : 'out' + const condition = `${mLine.position}_${positionType}` + let isStartEnd = findInteriorPoint(wallBaseLine, sortWallBaseLines) - const newPointY = Big(roofLine.y1).plus(moveDist).toNumber() + let sPoint, ePoint - 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, position: 'top_in_end' }) + if (condition === 'top_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 - 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') - } + const newPointY = Big(roofLine.y2).plus(moveDist).toNumber() - //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') - } - } else if (condition === 'top_out') { - console.log('top_out isStartEnd:::::::', isStartEnd) + const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber() + const pLineX = Big(roofLine.x1).minus(0).toNumber() + // let idx = 0 >= index - 1 ? sortRoofLines.length : index + // const pLineY = sortRoofLines[idx - 1].y1 - 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 }) + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineY = sortRoofLines[prevIndex].y1 - const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() - newPEnd.x = roofLine.x2 //Big(newPEnd.x).plus(eLineX).toNumber() - newPStart.x = aStartX - let idx = 0 > index - 1 ? roofLines.length : index - const newLine = roofLines[idx - 1] - if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - if (inLine) { - if (inLine.y2 > inLine.y1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } else { - getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') - } + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'top_in_start' }) + + 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: 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, position: 'top_out_start' }) - } else { - const cLineX = Big(wallBaseLine.y1).minus(wallLine.y1).abs().toNumber() - newPStart.x = Big(newPStart.x).plus(cLineX).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) - if (inLine) { - if (inLine.y2 > inLine.y1) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + //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 = sortRoofLines.length < index + 1 ? 0 : index + // const pLineY = sortRoofLines[idx + 1].y2 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineY = sortRoofLines[nextIndex].y2 + + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'top_in_end' }) + + 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') + } + } else if (condition === 'top_out') { + console.log('top_out isStartEnd:::::::', 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 }) + + const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber() + newPEnd.x = roofLine.x2 //Big(newPEnd.x).plus(eLineX).toNumber() + newPStart.x = aStartX + // let idx = 0 > index - 1 ? sortRoofLines.length : index + // const newLine = sortRoofLines[idx - 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[prevIndex] + + if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { + if (inLine) { + if (inLine.y2 > inLine.y1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } else { + getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') + } } + 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, position: 'top_out_start' }) } else { - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber() - newPStart.x = Big(wallBaseLine.x1).plus(rLineM).abs().toNumber() + const cLineX = Big(wallBaseLine.y1).minus(wallLine.y1).abs().toNumber() + newPStart.x = Big(newPStart.x).plus(cLineX).toNumber() const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) if (inLine) { if (inLine.y2 > inLine.y1) { @@ -1265,215 +1226,251 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { } else { getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') } - } - } - } - } - 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 = roofLine.x1 //Big(newPStart.x).minus(eLineX).abs().toNumber() - newPEnd.x = aStartX - let idx = roofLines.length < index + 1 ? 0 : index - const newLine = roofLines[idx + 1] - - if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - if (inLine) { - if (inLine.y2 > inLine.y1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') } else { - getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') - } - } - 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, position: 'top_out_end' }) - } else { - const cLineX = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() - newPEnd.x = Big(newPEnd.x).minus(cLineX).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.y2 > inLine.y1) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') - } - } else { - //newPEnd.x = wallLine.x2; - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber() - newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.y1 > inLine.y2) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') - } else { - getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber() + newPStart.x = Big(wallBaseLine.x1).plus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.y2 > inLine.y1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } } } } } - } - } else if (condition === '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 + 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 = roofLine.x1 //Big(newPStart.x).minus(eLineX).abs().toNumber() + newPEnd.x = aStartX + // let idx = sortRoofLines.length < index + 1 ? 0 : index + // const newLine = sortRoofLines[idx + 1] - const newPointY = Big(roofLine.y2).minus(moveDist).toNumber() + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[nextIndex] - 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, position: 'bottom_in_start' }) - - 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, position: 'bottom_in_end' }) - - 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') - } - } else if (condition === 'bottom_out') { - console.log('bottom_out isStartEnd:::::::', isStartEnd) - 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 = roofLine.x2 //Big(roofLine.x2).minus(eLineX).toNumber() - newPStart.x = aStartX - let idx = 0 > index - 1 ? roofLines.length : index - const newLine = roofLines[idx - 1] - - if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { - if (inLine) { - if (inLine.y2 < inLine.y1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } else { - getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') - } - } - 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, position: 'bottom_out_start' }) - } else { - const cLineX = Big(wallBaseLine.y1).minus(wallLine.y1).abs().toNumber() - newPStart.x = Big(newPStart.x).minus(cLineX).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) - if (inLine) { - if (inLine.y2 < inLine.y1) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') - } - } else { - //newPStart.x = wallLine.x1; - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber() - newPStart.x = Big(wallBaseLine.x1).minus(rLineM).abs().toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { if (inLine) { if (inLine.y2 > inLine.y1) { - getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') } else { - getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPStart.y, x: newPStart.x }, 'purple') + getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') } } - } - } - } - - 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 = roofLine.x1 //Big(roofLine.x1).plus(eLineX).toNumber() - let idx = roofLines.length < index + 1 ? 0 : index - const newLine = roofLines[idx + 1] - - if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { - if (inLine) { - if (inLine.y2 < inLine.y1) { - getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') - } else { - getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') - } - } - 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, position: 'bottom_out_end' }) - } else { - const cLineX = Big(wallBaseLine.y2).minus(wallLine.y2).abs().toNumber() - newPEnd.x = Big(newPEnd.x).plus(cLineX).toNumber() - const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) - if (inLine) { - if (inLine.y2 < inLine.y1) { - getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') - } else { - getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') - } + 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, position: 'top_out_end' }) } else { - //newPEnd.x = wallLine.x2; - //외곽 라인 그리기 - const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber() - newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).abs().toNumber() + const cLineX = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + newPEnd.x = Big(newPEnd.x).minus(cLineX).toNumber() const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) if (inLine) { - if (inLine.y1 > inLine.y2) { + if (inLine.y2 > inLine.y1) { getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') } else { getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') } + } else { + //newPEnd.x = wallLine.x2; + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber() + newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.y1 > inLine.y2) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') + } else { + getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } + } + } + } + } + } else if (condition === '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 ? sortRoofLines.length : index + // const pLineY = sortRoofLines[idx - 1].y1 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineY = sortRoofLines[prevIndex].y1 + + getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'bottom_in_start' }) + + 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 = sortRoofLines.length < index + 1 ? 0 : index + // const pLineY = sortRoofLines[idx + 1].y2 + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length + const nextIndex = (index + 1) % sortRoofLines.length + const pLineY = sortRoofLines[nextIndex].y2 + + + getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue') + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'bottom_in_end' }) + + 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') + } + } else if (condition === 'bottom_out') { + console.log('bottom_out isStartEnd:::::::', isStartEnd) + 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 = roofLine.x2 //Big(roofLine.x2).minus(eLineX).toNumber() + newPStart.x = aStartX + // let idx = 0 > index - 1 ? sortRoofLines.length : index + // const newLine = sortRoofLines[idx - 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[prevIndex] + + if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) { + if (inLine) { + if (inLine.y2 < inLine.y1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } else { + getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') + } + } + 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, position: 'bottom_out_start' }) + } else { + const cLineX = Big(wallBaseLine.y1).minus(wallLine.y1).abs().toNumber() + newPStart.x = Big(newPStart.x).minus(cLineX).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.y2 < inLine.y1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + } else { + //newPStart.x = wallLine.x1; + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber() + newPStart.x = Big(wallBaseLine.x1).minus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x }) + if (inLine) { + if (inLine.y2 > inLine.y1) { + getAddLine({ y: newPStart.y, x: newPStart.x }, { y: inLine.y1, x: inLine.x1 }, 'purple') + } else { + getAddLine({ y: inLine.y2, x: inLine.x2 }, { y: newPStart.y, x: newPStart.x }, 'purple') + } + } + } + } + } + + 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 = roofLine.x1 //Big(roofLine.x1).plus(eLineX).toNumber() + // let idx = sortRoofLines.length < index + 1 ? 0 : index + // const newLine = sortRoofLines[idx + 1] + + const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length; + const nextIndex = (index + 1) % sortRoofLines.length; + const newLine = sortRoofLines[nextIndex] + + if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) { + if (inLine) { + if (inLine.y2 < inLine.y1) { + getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink') + } else { + getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink') + } + } + 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, position: 'bottom_out_end' }) + } else { + const cLineX = Big(wallBaseLine.y2).minus(wallLine.y2).abs().toNumber() + newPEnd.x = Big(newPEnd.x).plus(cLineX).toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.y2 < inLine.y1) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } + } else { + //newPEnd.x = wallLine.x2; + //외곽 라인 그리기 + const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber() + newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).abs().toNumber() + const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x }) + if (inLine) { + if (inLine.y1 > inLine.y2) { + getAddLine({ y: newPEnd.y, x: newPEnd.x }, { y: inLine.y2, x: inLine.x2 }, 'purple') + } else { + getAddLine({ y: inLine.y1, x: inLine.x1 }, { y: newPEnd.y, x: newPEnd.x }, 'purple') + } + } } } } } } } + + getAddLine(newPStart, newPEnd, 'red') + //canvas.remove(roofLine) + } else { + getAddLine(roofLine.startPoint, roofLine.endPoint) } - getAddLine(newPStart, newPEnd, 'red') - //canvas.remove(roofLine) - } else { - getAddLine(roofLine.startPoint, roofLine.endPoint) - } - - canvas.renderAll() - }); -} + canvas.renderAll() + }) + } getMoveUpDownLine() } @@ -1765,6 +1762,115 @@ const isSameLine = (edgeStartX, edgeStartY, edgeEndX, edgeEndY, baseLine) => { // --- Disconnected Line Processing --- +/** + * 라인들이 반시계 방향이 되도록 정렬하고, 왼쪽 상단에서 시작하는 새 배열 반환 + * @param {Array} lines - x1, y1, x2, y2 속성을 가진 라인 객체 배열 + * @returns {Array} 반시계 방향으로 정렬된 새 라인 배열 + */ +export function ensureCounterClockwiseLines(lines) { + if (!lines || lines.length < 3) return [...(lines || [])]; + + // 1. 모든 점을 연결 그래프로 구성 + const graph = new Map(); + + // 각 점에서 연결된 점들을 저장 + lines.forEach(line => { + const p1 = `${line.x1},${line.y1}`; + const p2 = `${line.x2},${line.y2}`; + + if (!graph.has(p1)) graph.set(p1, []); + if (!graph.has(p2)) graph.set(p2, []); + + // 양방향 연결 + graph.get(p1).push({ x: line.x2, y: line.y2, line }); + graph.get(p2).push({ x: line.x1, y: line.y1, line }); + }); + + // 2. 왼쪽 상단 점 찾기 + let startPoint = null; + let minY = Infinity; + let minX = Infinity; + + for (const [pointStr] of graph) { + const [x, y] = pointStr.split(',').map(Number); + if (y < minY || (y === minY && x < minX)) { + minY = y; + minX = x; + startPoint = { x, y }; + } + } + + if (!startPoint) return [...lines]; + + // 3. 점들을 순회하며 라인 구성 + const visited = new Set(); + const result = []; + let current = `${startPoint.x},${startPoint.y}`; + let prev = null; + + while (true) { + if (visited.has(current)) break; + visited.add(current); + + const neighbors = graph.get(current) || []; + if (neighbors.length === 0) break; + + // 이전 점 제외 + const nextPoints = neighbors.filter(n => + !prev || `${n.x},${n.y}` !== `${prev.x},${prev.y}` + ); + + if (nextPoints.length === 0) break; + + // 각도가 가장 작은(반시계 방향) 이웃 선택 + const [cx, cy] = current.split(',').map(Number); + const next = nextPoints.reduce((best, curr) => { + const angleBest = Math.atan2(best.y - cy, best.x - cx); + const angleCurr = Math.atan2(curr.y - cy, curr.x - cx); + return angleCurr > angleBest ? curr : best; + }, nextPoints[0]); + + // 라인 추가 (방향 유지) + const line = next.line; + const isReversed = (line.x1 !== next.x || line.y1 !== next.y); + + result.push({ + ...line, + x1: isReversed ? line.x2 : line.x1, + y1: isReversed ? line.y2 : line.y1, + x2: isReversed ? line.x1 : line.x2, + y2: isReversed ? line.y1 : line.y2, + idx: result.length + }); + + prev = { x: cx, y: cy }; + current = `${next.x},${next.y}`; + } + + // 4. 시계 방향이면 뒤집기 + let area = 0; + for (let i = 0; i < result.length; i++) { + const current = result[i]; + const next = result[(i + 1) % result.length]; + area += (next.x1 - current.x1) * (next.y1 + current.y1); + } + + if (area > 0) { + return result.reverse().map((line, idx) => ({ + ...line, + x1: line.x2, + y1: line.y2, + x2: line.x1, + y2: line.y1, + idx + })); + } + + return result; +} + + + /** * 점을 선분에 투영한 점의 좌표를 반환합니다. * @param {object} point - 투영할 점 {x, y} @@ -2991,17 +3097,32 @@ function pointToLineDistance(point, lineP1, lineP2) { 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 (!line) { + console.error('line 객체가 유효하지 않습니다:', line); + return null; // 또는 적절한 기본값 반환 + } - if (dx < eps && dy >= eps) return 'vertical' - if (dy < eps && dx >= eps) return 'horizontal' - if (dx < eps && dy < eps) return 'point' - return 'diagonal' + // get 메서드가 있으면 사용하고, 없으면 직접 프로퍼티에 접근 + const getValue = (obj, key) => + obj && typeof obj.get === 'function' ? obj.get(key) : obj[key]; + + try { + const x1 = getValue(line, 'x1'); + const y1 = getValue(line, 'y1'); + const x2 = getValue(line, 'x2'); + const y2 = getValue(line, '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'; + } catch (e) { + console.error('방향 계산 중 오류 발생:', e); + return null; + } } @@ -3370,102 +3491,3 @@ function findInteriorPoint(line, polygonLines) { }; } -/** - * baseLines의 순서를 wallLines의 순서와 일치시킵니다. - * 1순위: 공통 ID(id, matchingId, parentId 등)를 이용한 직접 매칭 - * 2순위: 기하학적 유사성(기울기, 길이, 위치)을 점수화하여 매칭 - * - * @param {Array} baseLines - 정렬할 원본 baseLine 배열 - * @param {Array} wallLines - 기준이 되는 wallLine 배열 - * @returns {Array} wallLines 순서에 맞춰 정렬된 baseLines - */ -export const sortBaseLinesByWallLines = (baseLines, wallLines) => { - if (!baseLines || !wallLines || baseLines.length === 0 || wallLines.length === 0) { - return baseLines; - } - - const sortedBaseLines = new Array(wallLines.length).fill(null); - const usedBaseIndices = new Set(); - - // [1단계] ID 매칭 (기존 로직 유지 - 혹시 ID가 있는 경우를 대비) - // ... (ID 매칭 코드는 생략하거나 유지) ... - - // [2단계] 'originPoint' 또는 좌표 일치성을 이용한 강력한 기하학적 매칭 - wallLines.forEach((wLine, wIndex) => { - if (sortedBaseLines[wIndex]) return; - - // 비교할 기준 좌표 설정 (originPoint가 있으면 그것을, 없으면 현재 좌표 사용) - const wStart = wLine.attributes?.originPoint - ? { x: wLine.attributes.originPoint.x1, y: wLine.attributes.originPoint.y1 } - : { x: wLine.x1, y: wLine.y1 }; - - const wEnd = wLine.attributes?.originPoint - ? { x: wLine.attributes.originPoint.x2, y: wLine.attributes.originPoint.y2 } - : { x: wLine.x2, y: wLine.y2 }; - - // 수직/수평 여부 판단 - const isVertical = Math.abs(wStart.x - wEnd.x) < 0.1; - const isHorizontal = Math.abs(wStart.y - wEnd.y) < 0.1; - - let bestMatchIndex = -1; - let minDiff = Infinity; - - baseLines.forEach((bLine, bIndex) => { - if (usedBaseIndices.has(bIndex)) return; - - let diff = Infinity; - - // 1. 수직선인 경우: X좌표가 일치해야 함 (예: 230.8 == 230.8) - if (isVertical) { - // bLine도 수직선인지 확인 (x1, x2 차이가 거의 없어야 함) - if (Math.abs(bLine.x1 - bLine.x2) < 1.0) { - // X좌표 차이를 오차(diff)로 계산 - diff = Math.abs(wStart.x - bLine.x1); - } - } - // 2. 수평선인 경우: Y좌표가 일치해야 함 - else if (isHorizontal) { - // bLine도 수평선인지 확인 - if (Math.abs(bLine.y1 - bLine.y2) < 1.0) { - diff = Math.abs(wStart.y - bLine.y1); - } - } - // 3. 대각선인 경우: 기울기와 절편 비교 (복잡하므로 거리로 대체) - else { - // 중점 간 거리 + 기울기 차이 - // (이전 답변의 로직 사용 가능) - } - - // 오차가 매우 작으면(예: 1px 미만) 같은 라인으로 간주 - if (diff < 1.0 && diff < minDiff) { - minDiff = diff; - bestMatchIndex = bIndex; - } - }); - - if (bestMatchIndex !== -1) { - sortedBaseLines[wIndex] = baseLines[bestMatchIndex]; - usedBaseIndices.add(bestMatchIndex); - } - }); - - // [3단계] 남은 라인 처리 (Fallback) - // 매칭되지 않은 wallLine들에 대해 남은 baseLines를 순서대로 배정하거나 - // 거리 기반 근사 매칭을 수행 - // ... (기존 fallback 로직) ... - - // 빈 구멍 채우기 (null 방지) - for(let i=0; i !usedBaseIndices.has(idx)); - if(unused !== -1) { - sortedBaseLines[i] = baseLines[unused]; - usedBaseIndices.add(unused); - } else { - sortedBaseLines[i] = baseLines[0]; // 최후의 수단 - } - } - } - - return sortedBaseLines; -}; \ No newline at end of file