보조선 사이즈 변경 후 지붕면 할당 시 할당 제대로 안되는 현상 수정

This commit is contained in:
hyojun.choi 2026-06-23 14:22:46 +09:00
parent ad5fa31576
commit cc6c734250
3 changed files with 70 additions and 1 deletions

View File

@ -8,6 +8,7 @@ import { useEffect, useState } from 'react'
import Image from 'next/image'
import Big from 'big.js'
import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils'
import { syncOuterBoundaryTwin } from '@/util/canvas-util'
import { normalizeDigits } from '@/util/input-utils'
import { useUndoRedo } from '@/hooks/useUndoRedo'
import { CalculatorInput } from '@/components/common/input/CalcInput'
@ -126,6 +127,12 @@ export default function AuxiliarySize(props) {
degree,
)
currentObject.addLengthText()
// [BOUNDARY-SYNC 2026-06-23] currentObject (polygon.lines) " ",
// .
// split 2 .
// ( )
syncOuterBoundaryTwin(canvas, currentObject, { x: x1, y: y1 }, { x: x2, y: y2 })
}
canvas.renderAll()
}

View File

@ -5,7 +5,7 @@ import { useEvent } from '@/hooks/useEvent'
import { useMouse } from '@/hooks/useMouse'
import { useLine } from '@/hooks/useLine'
import { useTempGrid } from '@/hooks/useTempGrid'
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine } from '@/util/canvas-util'
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine, translateOuterBoundaryTwin } from '@/util/canvas-util'
import { fabric } from 'fabric'
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
import { useSwal } from '@/hooks/useSwal'
@ -172,6 +172,11 @@ export function useAuxiliaryDrawing(id, isUseEffect = true) {
roof.innerLines = roof.innerLines.filter((inner) => inner !== object)
})
// [BOUNDARY-SYNC 2026-06-23] object 가 처마 외곽선(polygon.lines)과 좌표가 같은 "경계 복제본"이면,
// 그 처마선 쌍둥이도 같은 delta(x,y)로 함께 이동시켜 두 경계 표현을 동기화한다(지붕면 할당 가짜 면 방지).
// 일반 보조선은 동일 좌표 처마선이 없어 매칭 안 됨 → 영향 없음.
translateOuterBoundaryTwin(canvas, object, x, y)
canvas.remove(object)
canvas.setActiveObject(line)
}

View File

@ -1124,3 +1124,60 @@ export function getTrianglePoints(triangle) {
return points.map((point) => fabric.util.transformPoint(point, matrix))
}
// [BOUNDARY-SYNC 2026-06-23] 지붕 경계는 polygon.lines(처마선)과 polygon.innerLines 안의 경계 복제본
// 두 군데에 중복 보관된다(정상 시 좌표 동일 → split 중복제거로 합쳐짐). 보조선 사이즈 변경/이동으로
// 한쪽 경계선만 옮기면 두 표현이 어긋나, 지붕면 할당 split 이 경계를 2벌로 인식 → 바깥 전체 사각형이
// 가짜 면으로 잡힌다(예: 4면이어야 하는데 5면). 아래 헬퍼로 편집 시 좌표가 동일했던 "쌍둥이" 경계선을
// 함께 갱신해 동기화한다. (일반 보조선은 동일 좌표 처마선이 없어 매칭 안 됨 → 영향 없음)
const _eqBoundaryPt = (a, b, eps = 1) => Math.abs(a.x - b.x) <= eps && Math.abs(a.y - b.y) <= eps
/** 모든 지붕의 lines + innerLines 중, 끝점이 (p1,p2) 와 같은(순서 무관) 라인을 editedLine 제외하고 반환 */
function _findBoundaryTwins(canvas, editedLine, p1, p2) {
if (!canvas) return []
const roofs = canvas.getObjects().filter((o) => o.name === 'roof')
const twins = []
roofs.forEach((roof) => {
;[...(roof.lines || []), ...(roof.innerLines || [])].forEach((twin) => {
if (twin === editedLine) return
const t1 = { x: twin.x1, y: twin.y1 }
const t2 = { x: twin.x2, y: twin.y2 }
if ((_eqBoundaryPt(t1, p1) && _eqBoundaryPt(t2, p2)) || (_eqBoundaryPt(t1, p2) && _eqBoundaryPt(t2, p1))) {
twins.push({ twin, p1IsT1: _eqBoundaryPt(t1, p1) })
}
})
})
return twins
}
/**
* 사이즈 변경 등으로 끝점이 옮겨진 경우: 편집 좌표(origP1/origP2) 같던 처마선 쌍둥이를
* editedLine 현재(편집 ) 좌표로 맞춘다. 끝점 대응을 보존해 매핑한다.
*/
export function syncOuterBoundaryTwin(canvas, editedLine, origP1, origP2) {
if (!canvas || !editedLine) return
const newP1 = { x: editedLine.x1, y: editedLine.y1 }
const newP2 = { x: editedLine.x2, y: editedLine.y2 }
_findBoundaryTwins(canvas, editedLine, origP1, origP2).forEach(({ twin, p1IsT1 }) => {
// twin 의 t1 끝점이 origP1 에 대응하면 t1→newP1, 아니면 t1→newP2
if (p1IsT1) twin.set({ x1: newP1.x, y1: newP1.y, x2: newP2.x, y2: newP2.y })
else twin.set({ x1: newP2.x, y1: newP2.y, x2: newP1.x, y2: newP1.y })
if (typeof twin.setCoords === 'function') twin.setCoords()
twin.attributes = { ...twin.attributes, planeSize: editedLine.attributes?.planeSize, actualSize: editedLine.attributes?.actualSize }
if (typeof twin.addLengthText === 'function') twin.addLengthText()
})
}
/**
* 평행 이동(보조선 이동)으로 옮겨진 경우: object 좌표가 같던 처마선 쌍둥이를 같은 delta(dx,dy) 평행 이동한다.
*/
export function translateOuterBoundaryTwin(canvas, object, dx, dy) {
if (!canvas || !object) return
const p1 = { x: object.x1, y: object.y1 }
const p2 = { x: object.x2, y: object.y2 }
_findBoundaryTwins(canvas, object, p1, p2).forEach(({ twin }) => {
twin.set({ x1: twin.x1 + dx, y1: twin.y1 + dy, x2: twin.x2 + dx, y2: twin.y2 + dy })
if (typeof twin.setCoords === 'function') twin.setCoords()
if (typeof twin.addLengthText === 'function') twin.addLengthText()
})
}