보조선 사이즈 변경 후 지붕면 할당 시 할당 제대로 안되는 현상 수정
This commit is contained in:
parent
ad5fa31576
commit
cc6c734250
@ -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()
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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()
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user