From 7d33d0875d7a6d33c0a91310238b9a7a305f52e7 Mon Sep 17 00:00:00 2001 From: Cha Date: Sat, 22 Nov 2025 02:46:53 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A7=91=EC=B6=94=EA=B0=80=EC=9E=91=EC=97=855?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/util/skeleton-utils.js | 181 +++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 58 deletions(-) diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index bd64b846..edc5ffea 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -18,7 +18,7 @@ import * as conole from 'mathjs' * @param {string} textMode - 텍스트 표시 모드 * @param pitch */ - +const EPSILON = 0.1 export const drawSkeletonRidgeRoof = (roofId, canvas, textMode) => { @@ -569,7 +569,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //skeleton 라인에서 처마선은 삭제 if(skeletonLine.lineName === 'roofLine'){ - skeletonLine.set('visible', true); //임시 + skeletonLine.set('visible', false); //임시 roof.set({ stroke: 'black', strokeWidth: 10 @@ -617,21 +617,48 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { }) - function sortLinesByStartPoint(lines) { + function sortCurrentRoofLines(lines) { return [...lines].sort((a, b) => { - // 시작점의 x 좌표로 먼저 정렬 - if (a.startPoint.x !== b.startPoint.x) { - return a.startPoint.x - b.startPoint.x; + // 시작점과 끝점 중 더 작은 좌표를 기준으로 정렬 + const getMinPoint = (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') + + // x 좌표가 작은 점을 선택, 같으면 y 좌표가 작은 점 + if (x1 < x2 || (x1 === x2 && y1 < y2)) { + return { x: x1, y: y1 } + } + return { x: x2, y: y2 } } - // x 좌표가 같으면 y 좌표로 정렬 - return a.startPoint.y - b.startPoint.y; - }); + + const aPoint = getMinPoint(a) + const bPoint = getMinPoint(b) + + if (aPoint.x !== bPoint.x) return aPoint.x - bPoint.x + return aPoint.y - bPoint.y + }) } + // 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 sortedWallLines = sortLinesByStartPoint(wall.lines); - const sortedCurrentRoofLines = sortLinesByStartPoint(currentRoofLines); - const sortedRoofLines = sortLinesByStartPoint(roofLines); + const sortedWallLines = sortCurrentRoofLines(wall.lines); + const sortedCurrentRoofLines = sortCurrentRoofLines(currentRoofLines); + const sortedRoofLines = sortCurrentRoofLines(roofLines); + const sortedWallBaseLines = sortCurrentRoofLines(wall.baseLines); @@ -640,12 +667,72 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //wall.baseLine은 움직인라인 const movedLines = [] sortedWallLines.forEach((wallLine, index) => { - console.log("wallLine:::::", wallLine, index) + const roofLine = sortedRoofLines[index]; - const currentRoofLine = sortedCurrentRoofLines[index+1]; + const currentRoofLine = sortedCurrentRoofLines[index]; + const moveLine = sortedWallBaseLines[index] + + const origin = moveLine.attributes?.originPoint + if (!origin) return + const movedStart = + Math.abs(moveLine.x1 - origin.x1) > EPSILON || + Math.abs(moveLine.y1 - origin.y1) > EPSILON +const movedEnd = + Math.abs(moveLine.x2 - origin.x2) > EPSILON || + Math.abs(moveLine.y2 - origin.y2) > EPSILON + +const fullyMoved = movedStart && movedEnd + + if (fullyMoved) { + movedLines.push({ index, moveLine }) + + + const p1roofLine = findClosestRoofLine(roofLine.startPoint,sortedRoofLines) + const p2roofLine = findClosestRoofLine(roofLine.endPoint,sortedRoofLines) + const p1currentRoofLine = findClosestRoofLine(currentRoofLine.startPoint,sortedCurrentRoofLines) + const p2currentRoofLine = findClosestRoofLine(currentRoofLine.endPoint,sortedCurrentRoofLines) + const p1moveLine = findClosestRoofLine(moveLine.startPoint,sortedWallBaseLines) + const p2moveLine = findClosestRoofLine(moveLine.endPoint,sortedWallBaseLines) + + console.log('::::::',p1roofLine, p2roofLine, p1currentRoofLine, p2currentRoofLine, p1moveLine, p2moveLine) + + let testLine = new QLine([moveLine.x1, moveLine.y1, moveLine.x2, moveLine.y2], { + stroke: 'yellow', + strokeWidth: 10, + property: 'normal', + fontSize: 14, + }); + let testLine2 = new QLine([roofLine.x1, roofLine.y1, roofLine.x2, roofLine.y2], { + stroke: 'red', + strokeWidth: 10, + property: 'normal', + fontSize: 14, + }); + let testLine3 = new QLine([currentRoofLine.x1, currentRoofLine.y1, currentRoofLine.x2, currentRoofLine.y2], { + stroke: 'orange', + strokeWidth: 10, + property: 'normal', + fontSize: 14, + }); + canvas.add(testLine) + canvas.add(testLine2) + canvas.add(testLine3) + + canvas.renderAll() + } + + + + + + +}); + return innerLines; +} +/* let p1,p2,p3, p4 let idx = 0; let isMoveLine = false; @@ -660,29 +747,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { const moveLine = wall.baseLines[index] //이동한 wall 존재여부 (초기 wall line = base line) if(index === 2){ - let testLine = new QLine([roofLine.x1, roofLine.y1, roofLine.x2, roofLine.y2], { - stroke: 'yellow', - strokeWidth: 10, - property: 'normal', - fontSize: 14, - }); - let testLine2 = new QLine([currentRoofLine.x1, currentRoofLine.y1, currentRoofLine.x2, currentRoofLine.y2], { - stroke: 'red', - strokeWidth: 10, - property: 'normal', - fontSize: 14, - }); - let testLine3 = new QLine([wallLine.x1, wallLine.y1, wallLine.x2, wallLine.y2], { - stroke: 'blue', - strokeWidth: 10, - property: 'normal', - fontSize: 14, - }); - - canvas.add(testLine) - canvas.add(testLine2) - canvas.add(testLine3) - canvas.renderAll() + } // // 사용자가 라인을 드래그하기 시작할 때 @@ -1290,23 +1355,23 @@ if (moved) { */ - const drawPolygon = (p1,p2,p3,p4) => { - const rect = new QPolygon([p1, p2, p3, p4], { - type: POLYGON_TYPE.ROOF, - fill: 'transparent', - stroke: 'black', - strokeWidth: 3, - selectable: false, - evented: false, - name: 'roofLineRect', - roofId: roofId, - }) - canvas.add(rect) - canvas.renderAll() - } - if(isPolygon){ - drawPolygon( p1,p2,p3, p4) - } + // const drawPolygon = (p1,p2,p3,p4) => { + // const rect = new QPolygon([p1, p2, p3, p4], { + // type: POLYGON_TYPE.ROOF, + // fill: 'transparent', + // stroke: 'black', + // strokeWidth: 3, + // selectable: false, + // evented: false, + // name: 'roofLineRect', + // roofId: roofId, + // }) + // canvas.add(rect) + // canvas.renderAll() + // } + // if(isPolygon){ + // drawPolygon( p1,p2,p3, p4) + // } // const wallLine = wall.baseLines[roofLine.idx - 1]; @@ -1335,10 +1400,10 @@ if (moved) { - } - }); - return innerLines; -} +// } +// }); +// return innerLines; +// } /** * EAVES(처마) Edge를 처리하여 내부 스켈레톤 선을 추가합니다.