From 7b8b995e1cecbb968328cbfba83bcf9bf988d46b Mon Sep 17 00:00:00 2001 From: "hyojun.choi" Date: Fri, 27 Mar 2026 10:46:38 +0900 Subject: [PATCH 1/2] =?UTF-8?q?1805=20=EC=84=A4=EC=B9=98=EC=98=81=EC=97=AD?= =?UTF-8?q?=20=EC=A0=9C=EB=8C=80=EB=A1=9C=20=EC=84=A4=EC=B9=98=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=ED=98=84=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/module/useModuleBasicSetting.js | 6 +-- src/hooks/useMode.js | 30 ++++++----- src/util/qpolygon-utils.js | 62 +++++++++++++++-------- 3 files changed, 63 insertions(+), 35 deletions(-) diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index cc315e32..ef477e67 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -395,7 +395,7 @@ export function useModuleBasicSetting(tabNum) { const cleanedLines = cleaned.lines const originPolygon = new QPolygon(roof.getCurrentPoints(), { fontSize: 0 }) - let result = createPaddingPolygon(polygon, cleanedLines).vertices + let result = createPaddingPolygon(polygon, cleanedLines, 0, true).vertices //margin polygon 의 point가 기준 polygon의 밖에 있는지 판단한다. const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point)) @@ -408,9 +408,9 @@ export function useModuleBasicSetting(tabNum) { } else { //육지붕이 아닐때 if (allPointsOutside) { - offsetPoints = createMarginPolygon(polygon, cleanedLines).vertices + offsetPoints = createMarginPolygon(polygon, cleanedLines, 0, true).vertices } else { - offsetPoints = createPaddingPolygon(polygon, cleanedLines).vertices + offsetPoints = createPaddingPolygon(polygon, cleanedLines, 0, true).vertices } // 자기교차(꼬임) 제거 offsetPoints = cleanSelfIntersectingPolygon(offsetPoints) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 69c2db78..8492042a 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1746,7 +1746,7 @@ export function useMode() { return { vertices: cleanedVertices, lines: cleanedLines } } - function createMarginPolygon(polygon, lines, arcSegments = 0) { + function createMarginPolygon(polygon, lines, arcSegments = 0, bevelJoin = false) { const offsetEdges = [] polygon.edges.forEach((edge, i) => { @@ -1761,11 +1761,14 @@ export function useMode() { offsetEdges.forEach((thisEdge, i) => { const prevEdge = offsetEdges[(i + offsetEdges.length - 1) % offsetEdges.length] const vertex = edgesIntersection(prevEdge, thisEdge) - if (vertex && (!vertex.isIntersectionOutside || arcSegments < 1)) { - vertices.push({ - x: vertex.x, - y: vertex.y, - }) + if (vertex) { + if (!vertex.isIntersectionOutside || !bevelJoin) { + vertices.push({ x: vertex.x, y: vertex.y }) + } else { + // 둔각 + bevelJoin: offset edge 끝점 사용 + vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) + vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + } } }) @@ -1781,7 +1784,7 @@ export function useMode() { * @param arcSegments * @returns {{vertices, edges: *[], minX: *, minY: *, maxX: *, maxY: *}} */ - function createPaddingPolygon(polygon, lines, arcSegments = 0) { + function createPaddingPolygon(polygon, lines, arcSegments = 0, bevelJoin = false) { const offsetEdges = [] polygon.edges.forEach((edge, i) => { @@ -1797,11 +1800,14 @@ export function useMode() { offsetEdges.forEach((thisEdge, i) => { const prevEdge = offsetEdges[(i + offsetEdges.length - 1) % offsetEdges.length] const vertex = edgesIntersection(prevEdge, thisEdge) - if (vertex && (!vertex.isIntersectionOutside || arcSegments < 1)) { - vertices.push({ - x: vertex.x, - y: vertex.y, - }) + if (vertex) { + if (!vertex.isIntersectionOutside || !bevelJoin) { + vertices.push({ x: vertex.x, y: vertex.y }) + } else { + // 둔각 + bevelJoin: offset edge 끝점 사용 + vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y }) + vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y }) + } } }) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index bf4c87cb..adee3ff3 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -256,8 +256,8 @@ function createPaddingPolygon(polygon, offset, arcSegments = 0) { * @returns {Array} 정리된 점 배열 */ /** - * offset 폴리곤을 원본 폴리곤 경계 안으로 클리핑한다. - * 둔각 꼭짓점에서 offset 교차점이 원본 바깥으로 튀어나가는 문제를 해결한다. + * offset 폴리곤의 꼭짓점 중 원본 폴리곤 바깥에 나간 점을 + * 원본 폴리곤 경계 위의 가장 가까운 점으로 투영한다. * @param {Array} offsetVertices - offset된 점 배열 [{x, y}, ...] * @param {Array} originalVertices - 원본 폴리곤 점 배열 [{x, y}, ...] * @returns {Array} 클리핑된 점 배열 @@ -266,27 +266,49 @@ export function clipOffsetToOriginal(offsetVertices, originalVertices) { if (!offsetVertices || offsetVertices.length < 3) return offsetVertices if (!originalVertices || originalVertices.length < 3) return offsetVertices - try { - const offsetCoords = offsetVertices.map((p) => [p.x, p.y]) - offsetCoords.push([offsetVertices[0].x, offsetVertices[0].y]) - - const origCoords = originalVertices.map((p) => [p.x, p.y]) - origCoords.push([originalVertices[0].x, originalVertices[0].y]) - - const offsetPoly = turf.polygon([offsetCoords]) - const origPoly = turf.polygon([origCoords]) - - const clipped = turf.intersect(turf.featureCollection([offsetPoly, origPoly])) - - if (clipped) { - const clippedCoords = clipped.geometry.coordinates[0] - return clippedCoords.slice(0, -1).map((c) => ({ x: c[0], y: c[1] })) + // 점이 폴리곤 내부에 있는지 판단 (ray casting) + function pointInPolygon(point, polygon) { + let inside = false + for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { + const xi = polygon[i].x, yi = polygon[i].y + const xj = polygon[j].x, yj = polygon[j].y + if (((yi > point.y) !== (yj > point.y)) && + (point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi)) { + inside = !inside + } } - } catch (e) { - console.warn('Failed to clip offset polygon to original:', e) + return inside } - return offsetVertices + // 점을 선분 위의 가장 가까운 점으로 투영 + function projectOnSegment(p, a, b) { + const dx = b.x - a.x + const dy = b.y - a.y + const lenSq = dx * dx + dy * dy + if (lenSq === 0) return { x: a.x, y: a.y } + let t = ((p.x - a.x) * dx + (p.y - a.y) * dy) / lenSq + t = Math.max(0, Math.min(1, t)) + return { x: a.x + t * dx, y: a.y + t * dy } + } + + return offsetVertices.map((p) => { + if (pointInPolygon(p, originalVertices)) return p + + // 바깥에 있으면 원본 폴리곤의 가장 가까운 변 위의 점으로 이동 + let minDist = Infinity + let nearest = p + for (let i = 0; i < originalVertices.length; i++) { + const a = originalVertices[i] + const b = originalVertices[(i + 1) % originalVertices.length] + const proj = projectOnSegment(p, a, b) + const dist = (proj.x - p.x) * (proj.x - p.x) + (proj.y - p.y) * (proj.y - p.y) + if (dist < minDist) { + minDist = dist + nearest = proj + } + } + return nearest + }) } export function cleanSelfIntersectingPolygon(vertices) { From f2b527b77c450998d4a349fc6e94c7d838144d81 Mon Sep 17 00:00:00 2001 From: ysCha Date: Fri, 27 Mar 2026 16:23:06 +0900 Subject: [PATCH 2/2] =?UTF-8?q?top,bottom=20=3D=20in,=20=ED=95=A0=EB=8B=B9?= =?UTF-8?q?=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roofcover/useRoofAllocationSetting.js | 23 ++- src/hooks/usePolygon.js | 2 +- src/util/skeleton-utils.js | 155 ++++++++++++++++-- 3 files changed, 164 insertions(+), 16 deletions(-) diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index c31797cf..568e2dc8 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -444,15 +444,30 @@ export function useRoofAllocationSetting(id) { const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) roofBases.forEach((roofBase) => { try { - const roofEaveHelpLines = canvas.getObjects().filter((obj) => obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id) + // 지붕 할당 로직에 extensionLine 추가 + const roofEaveHelpLines = canvas.getObjects().filter((obj) => + (obj.lineName === 'eaveHelpLine' || obj.lineName === 'extensionLine') && + obj.roofId === roofBase.id + ) + // console.log('roofBase.id:', roofBase.id) + // console.log('roofEaveHelpLines:', roofEaveHelpLines) + // console.log('extensionLines found:', roofEaveHelpLines.filter(l => l.lineName === 'extensionLine')) if (roofEaveHelpLines.length > 0) { if (roofBase.lines) { // Filter out any eaveHelpLines that are already in lines to avoid duplicates const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id)) const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id)) // Filter out lines from roofBase.lines that share any points with newEaveLines + + // extensionLine과 일반 eaveHelpLine 분리 + const extensionLines = newEaveLines.filter(line => line.lineName === 'extensionLine') + const normalEaveLines = newEaveLines.filter(line => line.lineName === 'eaveHelpLine') + // console.log('extensionLines count:', extensionLines.length) + // console.log('normalEaveLines count:', normalEaveLines.length) + + // 일반 eaveHelpLine만 Overlap 판단에 사용 const linesToKeep = roofBase.lines.filter(roofLine => { - const shouldRemove = newEaveLines.some(eaveLine => { + const shouldRemove = normalEaveLines.some(eaveLine => { // 1. 기본적인 포인트 일치 확인 const rX1 = roofLine.x1, rY1 = roofLine.y1, rX2 = roofLine.x2, rY2 = roofLine.y2; const eX1 = eaveLine.x1, eY1 = eaveLine.y1, eX2 = eaveLine.x2, eY2 = eaveLine.y2; @@ -501,7 +516,9 @@ export function useRoofAllocationSetting(id) { return !shouldRemove; }); // Combine remaining lines with newEaveLines - roofBase.lines = [...linesToKeep, ...newEaveLines]; + roofBase.lines = [...linesToKeep, ...normalEaveLines, ...extensionLines]; + // console.log('Final roofBase.lines count:', roofBase.lines.length) + // console.log('extensionLines in final:', roofBase.lines.filter(l => l.lineName === 'extensionLine').length) } else { roofBase.lines = [...roofEaveHelpLines] } diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 3a83c947..2536b9f0 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -821,7 +821,7 @@ export const usePolygon = () => { if (innerLine.attributes && polygonLine.attributes.type) { // innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경 if (polygonLine.length < innerLine.length) { - if (polygonLine.lineName !== 'eaveHelpLine' || polygonLine.lineName !== 'eaveHelpLine') { + if (polygonLine.lineName !== 'eaveHelpLine' && polygonLine.lineName !== 'extensionLine') { polygonLine.need = false } } diff --git a/src/util/skeleton-utils.js b/src/util/skeleton-utils.js index a7868622..0daeb1c7 100644 --- a/src/util/skeleton-utils.js +++ b/src/util/skeleton-utils.js @@ -465,6 +465,36 @@ export const skeletonBuilder = (roofId, canvas, textMode) => { // 6. 마루이동(용마루 위치 수동 조정)이 설정된 경우 movingLineFromSkeleton 결과로 대체 if (moveFlowLine !== 0 || moveUpDown !== 0) { const movedPoints = movingLineFromSkeleton(roofId, canvas) + console.log("movedPoints:::", movedPoints); + + // movedPoints를 roof 경계로 확장 + // 이번 이동에서 실제로 변경된 포인트만 구분하여, 변경되지 않은 축만 roof 경계로 확장 + const oldPoints = canvas?.skeleton?.lastPoints ?? roofLinePoints + const tolerance = 0.1 + const correctedPoints = movedPoints.map((mp, i) => { + const rp = roofLinePoints[i] + const op = oldPoints[i] + if (!rp || !op) return mp + const xMatch = Math.abs(mp.x - rp.x) < tolerance + const yMatch = Math.abs(mp.y - rp.y) < tolerance + if (xMatch && yMatch) return mp + // 이번 이동에서 실제로 변경된 축 판별 (oldPoints vs movedPoints) + const xMoved = Math.abs(mp.x - op.x) >= tolerance + const yMoved = Math.abs(mp.y - op.y) >= tolerance + let newX = mp.x + let newY = mp.y + // 이번에 이동되지 않았는데 roof 경계와 다른 축만 교정 + if (!xMoved && !xMatch) newX = rp.x + if (!yMoved && !yMatch) newY = rp.y + if (newX !== mp.x || newY !== mp.y) { + console.log(`point[${i}] 교정: mp=(${mp.x}, ${mp.y}) → (${newX}, ${newY}), op=(${op.x}, ${op.y}), xMoved=${xMoved}, yMoved=${yMoved}`) + } + return { x: newX, y: newY } + }) + + // roofLineContactPoints = correctedPoints + // changRoofLinePoints = correctedPoints + roofLineContactPoints = movedPoints changRoofLinePoints = movedPoints } @@ -828,11 +858,11 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //roofline 외곽선 설정 - 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)) + // 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)) const isCollinear = (l1, l2, tolerance = 0.1) => { const slope1 = Math.abs(l1.x2 - l1.x1) < tolerance ? Infinity : (l1.y2 - l1.y1) / (l1.x2 - l1.x1) @@ -871,7 +901,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //현재 roof는 무조건 시계방향 - const getAddLine = (p1, p2, stroke = '') => { + const getAddLine = (p1, p2, stroke = '', lineType = 'eaveHelpLine') => { movedLines.push({ index, p1, p2 }) const dx = Math.abs(p2.x - p1.x); @@ -884,14 +914,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { fontSize: roof.fontSize, stroke: 'black', strokeWidth: 4, - name: 'eaveHelpLine', - lineName: 'eaveHelpLine', + name: lineType, + lineName: lineType, visible: true, roofId: roofId, selectable: true, hoverCursor: 'pointer', attributes: { - type: 'eaveHelpLine', + type: lineType, isStart: true, pitch: wallLine.attributes.pitch, planeSize: calcLinePlaneSize({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }), @@ -970,7 +1000,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { 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') + // 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') @@ -1000,7 +1030,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { 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') + // 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') @@ -1179,7 +1209,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { 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') + //getAddLine({ x: roofLine.x1, y: Big(roofLine.y1).minus(moveDist).toNumber() }, { x: newPointX, y: Big(roofLine.y1).minus(moveDist).toNumber()}, 'orange') if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) { getAddLine({ x: pLineX, y: pLineY }, { x: newPointX, y: pLineY }, 'green') @@ -1384,6 +1414,56 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') } + if(!isStartEnd.start && !isStartEnd.end){ + console.log('top_in start and end false') + + const moveDistY1 = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(wallLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + + const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } + const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } + + + if(moveDistX1 > 0) { + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'top_in_start' }) + + if(moveDistY1 > moveDistX1){ + const dist = moveDistY1 - moveDistX1 + // console.log('Creating extensionLine (Y1 > X1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1, y: roofLine.y1 + dist }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + }else{ + const dist = moveDistX1 - moveDistY1 + // console.log('Creating extensionLine (X1 > Y1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1 - dist, y: roofLine.y1 }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + } + + } + if(moveDistX2 > 0) { + findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'top_in_end' }) + + if(moveDistY2 > moveDistX2){ + const dist = moveDistY2 - moveDistX2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'red') + // console.log('Creating extensionLine (Y2 > X2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2, y: roofLine.y2 + dist }, 'orange', 'extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + }else{ + const dist = moveDistX2 - moveDistY2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'red') + // console.log('Creating extensionLine (X2 > Y2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2 + dist, y: roofLine.y2 }, 'orange', 'extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + } + } + + } } else if (condition === 'top_out') { console.log('top_out isStartEnd:::::::', isStartEnd) @@ -1557,6 +1637,57 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => { //getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange') getAddLine(newPStart, newPEnd, 'red') } + + if(!isStartEnd.start && !isStartEnd.end){ + + console.log('isStartEnd:::::', isStartEnd) + + const moveDistY1 = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber() + const moveDistX1 = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber() + const moveDistX2 = Big(wallLine.x2).minus(wallBaseLine.x2).abs().toNumber() + const moveDistY2 = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber() + + const sPoint = { x: wallBaseLine.x1, y: wallBaseLine.y1 } + const ePoint = { x: wallBaseLine.x2, y: wallBaseLine.y2 } + + + if(moveDistX1 > 0) { + findPoints.push({ x: sPoint.x, y: sPoint.y, position: 'bottom_in_start' }) + + if(moveDistY1 > moveDistX1){ + const dist = moveDistY1 - moveDistX1 + // console.log('Creating extensionLine (Y1 > X1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1, y: roofLine.y1 - dist }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + }else{ + const dist = moveDistX1 - moveDistY1 + // console.log('Creating extensionLine (X1 > Y1):', { sPoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: sPoint.x, y: sPoint.y }, { x: roofLine.x1 + dist, y: roofLine.y1 }, 'orange','extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + } + + } + if(moveDistX2 > 0) { + findPoints.push({ x: ePoint.x, y: ePoint.y, position: 'bottom_in_end' }) + + if(moveDistY2 > moveDistX2){ + const dist = moveDistY2 - moveDistX2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'red') + // console.log('Creating extensionLine (Y2 > X2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2, y: roofLine.y2 - dist }, 'orange', 'extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + }else{ + const dist = moveDistX2 - moveDistY2 + // getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'red') + // console.log('Creating extensionLine (X2 > Y2):', { ePoint, roofLine, dist, roofId }) + const createdLine = getAddLine({ x: ePoint.x, y: ePoint.y }, { x: roofLine.x2 - dist, y: roofLine.y2 }, 'orange', 'extensionLine') + console.log('extensionLine created - length:', createdLine.length, 'coords:', { x1: createdLine.x1, y1: createdLine.y1, x2: createdLine.x2, y2: createdLine.y2 }) + + } + } + } } else if (condition === 'bottom_out') { console.log('bottom_out isStartEnd:::::::', isStartEnd) if (isStartEnd.start) {