diff --git a/src/hooks/module/useModuleBasicSetting.js b/src/hooks/module/useModuleBasicSetting.js index 18d92ab7..45c17ff0 100644 --- a/src/hooks/module/useModuleBasicSetting.js +++ b/src/hooks/module/useModuleBasicSetting.js @@ -2235,6 +2235,9 @@ export function useModuleBasicSetting(tabNum) { // 대칭 지붕을 위해 south의 calcAreaWidth 저장 (north에서 참조) if (symmetricWidthRef && moduleIndex === 0) { symmetricWidthRef.south = calcAreaWidth + // [SYMM-FIX 2026-06-09] 진짜 대칭 판정용 남면 실제 가로폭 저장 + const southBBox = turf.bbox(polygonToTurfPolygon(moduleSetupSurface)) + symmetricWidthRef.southActualWidth = southBBox[2] - southBBox[0] } if (type === MODULE_SETUP_TYPE.LAYOUT) { @@ -2422,8 +2425,13 @@ export function useModuleBasicSetting(tabNum) { // 북쪽: 남쪽과 동일한 방식으로 계산 (대칭을 위해) let calcAreaWidth = Math.abs(flowLines.right.x1 - flowLines.left.x1) //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직 - // 대칭 지붕: south의 calcAreaWidth가 있고 north의 값이 south보다 10% 이상 작으면 south 값 사용 - if (symmetricWidthRef?.south && calcAreaWidth < symmetricWidthRef.south * 0.9) { + // [SYMM-FIX 2026-06-09] 진짜 대칭 판정: 북면 실제 폴리곤 가로폭이 남면 실제 가로폭과 비슷(>=90%)할 때만 보정. + // T자처럼 북면이 물리적으로 작으면(실제폭 작음) 보정 제외 → 단독 선택과 동일하게 자연 배치. + const northBBox = turf.bbox(polygonToTurfPolygon(moduleSetupSurface)) + const northActualWidth = northBBox[2] - northBBox[0] + const reallySymmetric = !!(symmetricWidthRef?.southActualWidth && northActualWidth >= symmetricWidthRef.southActualWidth * 0.9) + // 대칭 지붕: south의 calcAreaWidth가 있고 north의 flowLines폭이 south보다 10% 이상 작은데 실제 폴리곤은 대칭이면 south 값 사용 + if (symmetricWidthRef?.south && calcAreaWidth < symmetricWidthRef.south * 0.9 && reallySymmetric) { // flowLines 좌표도 보정 (중심점 유지하면서 너비 확장) const center = (flowLines.right.x1 + flowLines.left.x1) / 2 const halfWidth = symmetricWidthRef.south / 2 @@ -2626,6 +2634,8 @@ export function useModuleBasicSetting(tabNum) { // 대칭 지붕을 위해 west의 calcAreaWidth 저장 (east에서 참조) if (symmetricWidthRef && moduleIndex === 0) { symmetricWidthRef.west = calcAreaWidth + const westBBox = turf.bbox(polygonToTurfPolygon(moduleSetupSurface)) + symmetricWidthRef.westActualHeight = westBBox[3] - westBBox[1] } //단수지정 자동이면 @@ -2810,8 +2820,12 @@ export function useModuleBasicSetting(tabNum) { // 동쪽: 서쪽과 동일한 방식으로 계산 (대칭을 위해) let calcAreaWidth = Math.abs(flowLines.bottom.y1 - flowLines.top.y1) //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직 - // 대칭 지붕: west의 calcAreaWidth가 있고 east의 값이 west보다 10% 이상 작으면 west 값 사용 - if (symmetricWidthRef?.west && calcAreaWidth < symmetricWidthRef.west * 0.9) { + // 진짜 대칭 판정: 동면 실제 폴리곤 세로높이가 서면 실제 높이와 비슷(>=90%)할 때만 보정 (T자형 비대칭 제외) + const eastBBox = turf.bbox(polygonToTurfPolygon(moduleSetupSurface)) + const eastActualHeight = eastBBox[3] - eastBBox[1] + const eastReallySymmetric = !!(symmetricWidthRef?.westActualHeight && eastActualHeight >= symmetricWidthRef.westActualHeight * 0.9) + // 대칭 지붕: west의 calcAreaWidth가 있고 east의 flowLines높이가 west보다 10% 이상 작은데 실제 폴리곤은 대칭이면 west 값 사용 + if (symmetricWidthRef?.west && calcAreaWidth < symmetricWidthRef.west * 0.9 && eastReallySymmetric) { // flowLines 좌표도 보정 (중심점 유지하면서 높이 확장) const center = (flowLines.bottom.y1 + flowLines.top.y1) / 2 const halfHeight = symmetricWidthRef.west / 2 @@ -2926,8 +2940,8 @@ export function useModuleBasicSetting(tabNum) { } } - // 대칭 지붕을 위한 calcAreaWidth 공유 객체 (south→north, west→east) - const symmetricWidthRef = { south: null, west: null } + // 대칭 지붕을 위한 calcAreaWidth 공유 객체 (south→north, west→east) + 실제 폴리곤 크기(진짜 대칭 판정용) + const symmetricWidthRef = { south: null, west: null, southActualWidth: null, westActualHeight: null } // 대칭 보정을 위해 south/west가 north/east보다 먼저 처리되도록 정렬 const directionOrder = { south: 0, west: 1, north: 2, east: 3 }