diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index d044afb6..a1718a66 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -369,10 +369,10 @@ export const skeletonBuilder = (roofId, canvas, textMode) => { /** 외벽선 */ const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId) - //const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0) + const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0) + // roof.points 순서와 맞춰야 offset 매핑이 정확함 + const baseLinePoints = createOrderedBasePoints(roof.points, baseLines) - const baseLines = canvas.getObjects().filter((object) => object.name === 'baseLine' && object.parentId === roofId) || [] - const baseLinePoints = baseLines.map((line) => ({ x: line.left, y: line.top })) const outerLines = canvas.getObjects().filter((object) => object.name === 'outerLinePoint') || [] const outerLinePoints = outerLines.map((line) => ({ x: line.left, y: line.top })) @@ -391,16 +391,46 @@ export const skeletonBuilder = (roofId, canvas, textMode) => { const moveFlowLine = roof.moveFlowLine || 0 // Provide a default value const moveUpDown = roof.moveUpDown || 0 // Provide a default value - let points = roof.points + const isClosedPolygon = (points) => + points.length > 1 && isSamePoint(points[0], points[points.length - 1]) + const roofLinePoints = isClosedPolygon(roof.points) ? roof.points.slice(0, -1) : roof.points + const orderedBaseLinePoints = isClosedPolygon(baseLinePoints) ? baseLinePoints.slice(0, -1) : baseLinePoints + + console.log('roofLinePoints:', roofLinePoints) + console.log('baseLinePoints:', orderedBaseLinePoints) + + // baseLinePoint에서 roofLinePoint 방향으로 45도 대각선 확장 후 가장 가까운 접점 계산 + let roofLineContactPoints = orderedBaseLinePoints.map((point, index) => { + const roofPoint = roofLinePoints[index] + if (!roofPoint) return point + + const dx = roofPoint.x - point.x + const dy = roofPoint.y - point.y + const absDx = Math.abs(dx) + const absDy = Math.abs(dy) + + // 거리가 0이면 이미 같은 위치 + if (absDx === 0 && absDy === 0) return point + + const step = Math.min(absDx, absDy) + if (step === 0) return point + + const nextX = point.x + Math.sign(dx) * step + const nextY = point.y + Math.sign(dy) * step + return { + x: Number(nextX.toFixed(1)), + y: Number(nextY.toFixed(1)) + } + }) //마루이동 if (moveFlowLine !== 0 || moveUpDown !== 0) { - points = movingLineFromSkeleton(roofId, canvas) + roofLineContactPoints = movingLineFromSkeleton(roofId, canvas) } - console.log('points:', points) - const geoJSONPolygon = toGeoJSON(points) + console.log('points:', roofLineContactPoints) + const geoJSONPolygon = toGeoJSON(roofLineContactPoints) try { // SkeletonBuilder는 닫히지 않은 폴리곤을 기대하므로 마지막 점 제거 @@ -436,7 +466,7 @@ export const skeletonBuilder = (roofId, canvas, textMode) => { } canvas.skeleton = [] canvas.skeleton = cleanSkeleton - canvas.skeleton.lastPoints = points + canvas.skeleton.lastPoints = roofLineContactPoints canvas.set('skeleton', cleanSkeleton) canvas.renderAll() @@ -3656,4 +3686,3 @@ function findInteriorPoint(line, polygonLines) { end: endIsValley }; } -