Merge pull request 'dev' (#176) from dev into prd-deploy
Reviewed-on: #176
This commit is contained in:
commit
93cda139de
@ -25,6 +25,7 @@ import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
import { roofMaterialsAtom } from '@/store/settingAtom'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { ROOF_MATERIAL_LAYOUT } from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
|
||||
export const ToggleonMouse = (e, act, target) => {
|
||||
const listWrap = e.target.closest(target)
|
||||
@ -75,6 +76,8 @@ export default function Header(props) {
|
||||
const [commonCode, setCommonCode] = useRecoilState(commonCodeState)
|
||||
const { promiseGet } = useAxios()
|
||||
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
/**
|
||||
* 지붕재 목록 Header에서 조회
|
||||
*/
|
||||
@ -232,11 +235,32 @@ export default function Header(props) {
|
||||
key={`${menu.id}`}
|
||||
href={menu.url}
|
||||
replace={true}
|
||||
onClick={() => {
|
||||
// moveHome()
|
||||
removeStuffRecoil(menu)
|
||||
if (pathName === '/' && menu.id !== 8) {
|
||||
window.location.reload()
|
||||
onClick={(e) => {
|
||||
|
||||
if(pathName === '/floor-plan') {
|
||||
e.preventDefault() // 기본 네비게이션 방지
|
||||
e.stopPropagation() // 이벤트 전파 방지
|
||||
swalFire({
|
||||
text : getMessage(common.link.confirm), // 적절한 확인 메시지
|
||||
type : 'confirm',
|
||||
confirmFn: () => {
|
||||
// 확인 버튼 클릭 시 실행
|
||||
removeStuffRecoil(menu)
|
||||
if (pathName === '/' && menu.id !== 8) {
|
||||
window.location.reload()
|
||||
} else {
|
||||
router.push(menu.url)
|
||||
}
|
||||
router.push(menu.url)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
removeStuffRecoil(menu)
|
||||
if (pathName === '/' && menu.id !== 8) {
|
||||
window.location.reload()
|
||||
} else {
|
||||
router.push(menu.url)
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
@ -258,9 +282,24 @@ export default function Header(props) {
|
||||
scroll={false}
|
||||
href={m.url}
|
||||
replace={true}
|
||||
onClick={() => {
|
||||
removeStuffRecoil(m)
|
||||
}}
|
||||
onClick={(e) => {
|
||||
if(pathName === '/floor-plan') {
|
||||
e.preventDefault() // 기본 네비게이션 방지
|
||||
e.stopPropagation() // 이벤트 전파 방지
|
||||
swalFire({
|
||||
text: getMessage('common.link.confirm'), // 적절한 확인 메시지
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
// 확인 버튼 클릭 시 기존 로직 실행
|
||||
removeStuffRecoil(m)
|
||||
router.push(m.url)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
removeStuffRecoil(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
>
|
||||
{getMessage(m.name)}
|
||||
</Link>
|
||||
|
||||
37
src/hooks/common/useTurf.js
Normal file
37
src/hooks/common/useTurf.js
Normal file
@ -0,0 +1,37 @@
|
||||
import * as turf from '@turf/turf'
|
||||
|
||||
export const useTurf = () => {
|
||||
/**
|
||||
* 배치면 안에 있는지 확인
|
||||
* @param {*} squarePolygon
|
||||
* @param {*} turfModuleSetupSurface
|
||||
* @param spare
|
||||
* @returns
|
||||
*/
|
||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface, spare = 1) => {
|
||||
// 표면 영역을 spare만큼 수동 확장
|
||||
const expandedSurface = {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
turfModuleSetupSurface.geometry.coordinates[0].map(([x, y]) => {
|
||||
// 각 점을 바깥쪽으로 2 단위씩 이동
|
||||
const coords = turfModuleSetupSurface.geometry.coordinates[0]
|
||||
const centerX = coords.slice(0, -1).reduce((sum, [x, y]) => sum + x, 0) / (coords.length - 1)
|
||||
const centerY = coords.slice(0, -1).reduce((sum, [x, y]) => sum + y, 0) / (coords.length - 1)
|
||||
|
||||
return [x < centerX ? x - spare : x + spare, y < centerY ? y - spare : y + spare]
|
||||
}),
|
||||
],
|
||||
}
|
||||
|
||||
const isWithin = turf.booleanContains(expandedSurface, squarePolygon) || turf.booleanWithin(squarePolygon, expandedSurface)
|
||||
|
||||
const isContact = turf.booleanIntersects(squarePolygon, expandedSurface) && !turf.booleanOverlap(squarePolygon, expandedSurface)
|
||||
|
||||
return isWithin || isContact
|
||||
}
|
||||
|
||||
return {
|
||||
checkModuleDisjointSurface,
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,7 @@ import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { useTurf } from '@/hooks/common/useTurf'
|
||||
|
||||
export function useModuleBasicSetting(tabNum) {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -62,6 +63,8 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const setManualSetupMode = useSetRecoilState(toggleManualSetupModeState)
|
||||
const setModuleRowColArray = useSetRecoilState(moduleRowColArrayState)
|
||||
|
||||
const { checkModuleDisjointSurface } = useTurf()
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
//수동 설치시 초기화
|
||||
@ -517,6 +520,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockScalingX: true, // X 축 크기 조정 잠금
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
opacity: 0.85,
|
||||
}
|
||||
|
||||
if (moduleSetupSurfaces.length !== 0) {
|
||||
@ -758,21 +762,21 @@ export function useModuleBasicSetting(tabNum) {
|
||||
//여기서부턴 배치면 설치 외곽선 라인
|
||||
// 위쪽 변에 스냅
|
||||
if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) {
|
||||
tempModule.top = trestleTop + 1
|
||||
tempModule.top = trestleTop
|
||||
}
|
||||
|
||||
// 아래쪽 변에 스냅
|
||||
if (Math.abs(smallBottom - trestleBottom) < trestleSnapDistance) {
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height - 1
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height
|
||||
}
|
||||
|
||||
// 왼쪽변에 스냅
|
||||
if (Math.abs(smallLeft - trestleLeft) < trestleSnapDistance) {
|
||||
tempModule.left = trestleLeft + 1
|
||||
tempModule.left = trestleLeft
|
||||
}
|
||||
//오른쪽 변에 스냅
|
||||
if (Math.abs(smallRight - trestleRight) < trestleSnapDistance) {
|
||||
tempModule.left = trestleRight - tempModule.width - 1
|
||||
tempModule.left = trestleRight - tempModule.width
|
||||
}
|
||||
|
||||
if (flowDirection === 'south' || flowDirection === 'north') {
|
||||
@ -869,7 +873,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
if (!isIntersection) return
|
||||
|
||||
tempModule.setCoords() //좌표 재정렬
|
||||
if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) {
|
||||
if (checkModuleDisjointSurface(tempTurfModule, turfPolygon)) {
|
||||
//마우스 클릭시 set으로 해당 위치에 셀을 넣음
|
||||
const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module, true))) //겹치는지 확인
|
||||
if (!isOverlap) {
|
||||
@ -892,6 +896,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
})
|
||||
|
||||
canvas?.add(manualModule)
|
||||
canvas.bringToFront(manualModule)
|
||||
manualDrawModules.push(manualModule)
|
||||
setModuleStatisticsData()
|
||||
|
||||
@ -990,6 +995,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockScalingX: true, // X 축 크기 조정 잠금
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
opacity: 0.85,
|
||||
}
|
||||
|
||||
const objectsIncludeSurface = (turfModuleSetupSurface) => {
|
||||
@ -1426,7 +1432,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const tempTurfModule = polygonToTurfPolygon(tempModule)
|
||||
tempModule.setCoords() //좌표 재정렬
|
||||
|
||||
if (turf.booleanContains(turfPolygon, tempTurfModule) || turf.booleanWithin(tempTurfModule, turfPolygon)) {
|
||||
if (checkModuleDisjointSurface(tempTurfModule, turfPolygon)) {
|
||||
//마우스 클릭시 set으로 해당 위치에 셀을 넣음
|
||||
const isOverlap = manualDrawModules.some((module) => turf.booleanOverlap(tempTurfModule, polygonToTurfPolygon(module))) //겹치는지 확인
|
||||
if (!isOverlap) {
|
||||
@ -1450,6 +1456,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
//오브젝트와 겹치지 않으면 넣는다
|
||||
if (isDisjoint) {
|
||||
canvas?.add(manualModule)
|
||||
canvas.bringToFront(manualModule)
|
||||
canvas?.renderAll()
|
||||
manualDrawModules.push(manualModule)
|
||||
setModuleStatisticsData()
|
||||
@ -1874,6 +1881,8 @@ export function useModuleBasicSetting(tabNum) {
|
||||
lockScalingX: true, // X 축 크기 조정 잠금
|
||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
name: POLYGON_TYPE.MODULE,
|
||||
//투명도 추가
|
||||
opacity: 0.85,
|
||||
}
|
||||
|
||||
//선택된 지붕안에 오브젝트(도머, 개구등)이 있는지 확인하는 로직 포함되면 배열 반환
|
||||
@ -1892,15 +1901,20 @@ export function useModuleBasicSetting(tabNum) {
|
||||
return containsBatchObjects
|
||||
}
|
||||
|
||||
const addModule = (tempModule, moduleSetupArray, moduleArray) => {
|
||||
canvas?.add(tempModule)
|
||||
canvas.bringToFront(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치면 안에 있는지 확인
|
||||
* @param {*} squarePolygon
|
||||
* @param {*} turfModuleSetupSurface
|
||||
* @returns
|
||||
*/
|
||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||
}
|
||||
|
||||
/**
|
||||
* 자동 레이아웃 설치 일시 row col 초과 여부 확인
|
||||
@ -2091,10 +2105,10 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const moduleArray = []
|
||||
|
||||
let calcAreaWidth = Math.abs(flowLines.right.x1 - flowLines.left.x1) //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
|
||||
let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1
|
||||
let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1)
|
||||
let calcModuleHeightCount = calcAreaHeight / (height + intvVer)
|
||||
|
||||
if (type === MODULE_SETUP_TYPE.LAYOUT) {
|
||||
calcModuleWidthCount = layoutCol > calcModuleWidthCount ? calcModuleWidthCount : layoutCol
|
||||
@ -2124,7 +2138,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
for (let i = 0; i < calcModuleHeightCount; i++) {
|
||||
let isInstall = false
|
||||
let moduleY = flowLines.bottom.y1 - height * i - 1 //살짝 여유를 준다
|
||||
let moduleY = flowLines.bottom.y1 - height * i //살짝 여유를 준다
|
||||
|
||||
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
|
||||
if (installedModuleHeightCount > 0) {
|
||||
@ -2135,7 +2149,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
heightMargin = installedModuleHeightCount === 0 ? 0 : intvVer
|
||||
|
||||
for (let j = 0; j < totalModuleWidthCount; j++) {
|
||||
let moduleX = startPointX + width * j + 1 //5정도 마진을 준다
|
||||
let moduleX = startPointX + width * j //5정도 마진을 준다
|
||||
widthMargin = j === 0 ? 0 : intvHor * j // 가로 마진값
|
||||
chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다
|
||||
if (isChidori) {
|
||||
@ -2170,10 +2184,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
if (disjointFromTrestle && isDisjoint) {
|
||||
//최초 한번은 그냥 그린다
|
||||
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
addModule(tempModule, moduleSetupArray, moduleArray)
|
||||
|
||||
// ++installedModuleHeightCount
|
||||
|
||||
@ -2277,9 +2288,9 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const moduleArray = []
|
||||
|
||||
let calcAreaWidth = flowLines.right.x1 - flowLines.left.x1 //오른쪽 x에서 왼쪽 x를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (width + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (width + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcAreaHeight = flowLines.bottom.y1 - flowLines.top.y1
|
||||
let calcModuleHeightCount = calcAreaHeight / (height + intvVer + 1)
|
||||
let calcModuleHeightCount = calcAreaHeight / (height + intvVer)
|
||||
|
||||
//단수지정 자동이면
|
||||
if (type === MODULE_SETUP_TYPE.LAYOUT) {
|
||||
@ -2319,7 +2330,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
heightMargin = installedModuleHeightCount === 0 ? 0 : intvVer //모듈간에 마진이 있어 마진값도 넣음
|
||||
for (let j = 0; j < totalModuleWidthCount; j++) {
|
||||
//모듈 열수 만큼 반복
|
||||
let moduleX = startPointX - width * j - 1 //시작점에서 우 -> 좌로 그려 내려간다
|
||||
let moduleX = startPointX - width * j //시작점에서 우 -> 좌로 그려 내려간다
|
||||
widthMargin = j === 0 ? 0 : intvHor * j
|
||||
chidoriLength = 0
|
||||
if (isChidori && !isMaxSetup) {
|
||||
@ -2349,10 +2360,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||
|
||||
if (disjointFromTrestle && isDisjoint) {
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
addModule(tempModule, moduleSetupArray, moduleArray)
|
||||
|
||||
isInstall = true
|
||||
|
||||
@ -2460,10 +2468,10 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
const moduleArray = []
|
||||
|
||||
let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
|
||||
let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
|
||||
let calcAreaWidth = Math.abs(flowLines.bottom.y1 - flowLines.top.y1) //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (height + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcAreaHeight = Math.abs(flowLines.right.x1 - flowLines.left.x1)
|
||||
let calcModuleHeightCount = calcAreaHeight / (width + intvVer)
|
||||
|
||||
//단수지정 자동이면
|
||||
if (type === MODULE_SETUP_TYPE.LAYOUT) {
|
||||
@ -2490,12 +2498,12 @@ export function useModuleBasicSetting(tabNum) {
|
||||
//첫번재 모듈 설치 후 두번째 모듈을 몇개까지 설치 할 수 있는지 계산
|
||||
if (moduleIndex > 0) {
|
||||
moduleMaxRows = totalModuleMaxRows - installedModuleHeightCount //두번째 모듈일때
|
||||
isChidoriLine = installedModuleHeightCount % 2 != 0 ? true : false //첫번째에서 짝수에서 끝났으면 홀수는 치도리가 아님 짝수는 치도리
|
||||
isChidoriLine = installedModuleHeightCount % 2 !== 0 //첫번째에서 짝수에서 끝났으면 홀수는 치도리가 아님 짝수는 치도리
|
||||
}
|
||||
|
||||
for (let i = 0; i < calcModuleHeightCount; i++) {
|
||||
let isInstall = false
|
||||
let moduleY = flowLines.left.x1 + width * i + 1 //살짝 여유를 준다
|
||||
let moduleY = flowLines.left.x1 + width * i //살짝 여유를 준다
|
||||
|
||||
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
|
||||
if (installedModuleHeightCount > 0) {
|
||||
@ -2506,11 +2514,11 @@ export function useModuleBasicSetting(tabNum) {
|
||||
heightMargin = installedModuleHeightCount === 0 ? 0 : intvHor
|
||||
|
||||
for (let j = 0; j < totalModuleWidthCount; j++) {
|
||||
let moduleX = startPointX + height * j + 1 //5정도 마진을 준다
|
||||
let moduleX = startPointX + height * j //5정도 마진을 준다
|
||||
widthMargin = j === 0 ? 0 : intvVer * j // 가로 마진값
|
||||
chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다
|
||||
if (isChidori && !isMaxSetup) {
|
||||
chidoriLength = installedModuleHeightCount % 2 == 0 ? 0 : height / 2 - intvVer
|
||||
chidoriLength = installedModuleHeightCount % 2 === 0 ? 0 : height / 2 - intvVer
|
||||
}
|
||||
|
||||
let square = [
|
||||
@ -2527,17 +2535,14 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
moduleOptions = { ...moduleOptions, fill: module.color, surfaceId: moduleSetupSurface.id, moduleInfo: module }
|
||||
let tempModule = new QPolygon(points, { ...moduleOptions, turfPoints: squarePolygon })
|
||||
|
||||
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, polygonToTurfPolygon(moduleSetupSurface, true))
|
||||
let turfSurface = polygonToTurfPolygon(moduleSetupSurface, true)
|
||||
let disjointFromTrestle = checkModuleDisjointSurface(squarePolygon, turfSurface)
|
||||
let isDisjoint = checkModuleDisjointObjects(squarePolygon, containsBatchObjects)
|
||||
|
||||
if (disjointFromTrestle && isDisjoint) {
|
||||
//최초 한번은 그냥 그린다
|
||||
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
addModule(tempModule, moduleSetupArray, moduleArray)
|
||||
|
||||
// ++installedModuleHeightCount
|
||||
|
||||
@ -2546,9 +2551,9 @@ export function useModuleBasicSetting(tabNum) {
|
||||
installedLastHeightCoord = moduleY + width + widthMargin
|
||||
} else {
|
||||
//디버깅용
|
||||
// tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 })
|
||||
// canvas?.add(tempModule)
|
||||
// canvas.renderAll()
|
||||
/*tempModule.set({ fill: 'transparent', stroke: 'red', strokeWidth: 1 })
|
||||
canvas?.add(tempModule)
|
||||
canvas.renderAll()*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -2643,9 +2648,9 @@ export function useModuleBasicSetting(tabNum) {
|
||||
const moduleArray = []
|
||||
|
||||
let calcAreaWidth = flowLines.bottom.y1 - flowLines.top.y1 //아래에서 y에서 위를 y를 뺀 가운데를 찾는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (height + intvHor + 1) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcModuleWidthCount = calcAreaWidth / (height + intvHor) //뺀 공간에서 모듈을 몇개를 넣을수 있는지 확인하는 로직
|
||||
let calcAreaHeight = flowLines.right.x1 - flowLines.left.x1
|
||||
let calcModuleHeightCount = calcAreaHeight / (width + intvVer + 1)
|
||||
let calcModuleHeightCount = calcAreaHeight / (width + intvVer)
|
||||
|
||||
//단수지정 자동이면
|
||||
if (type === MODULE_SETUP_TYPE.LAYOUT) {
|
||||
@ -2677,7 +2682,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
for (let i = 0; i < calcModuleHeightCount; i++) {
|
||||
let isInstall = false
|
||||
let moduleY = flowLines.right.x1 - width * i - 1 //살짝 여유를 준다
|
||||
let moduleY = flowLines.right.x1 - width * i //살짝 여유를 준다
|
||||
|
||||
//두번째 모듈 -> 혼합일 경우의 설치될 모듈 높이를 계산
|
||||
if (installedModuleHeightCount > 0) {
|
||||
@ -2688,7 +2693,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
heightMargin = installedModuleHeightCount === 0 ? 0 : intvHor
|
||||
|
||||
for (let j = 0; j < totalModuleWidthCount; j++) {
|
||||
let moduleX = startPointX - height * j - 1 //5정도 마진을 준다
|
||||
let moduleX = startPointX - height * j //5정도 마진을 준다
|
||||
widthMargin = j === 0 ? 0 : intvVer * j // 가로 마진값
|
||||
chidoriLength = 0 //치도리가 아니여도 기본값을 5정도 준다
|
||||
if (isChidori && !isMaxSetup) {
|
||||
@ -2721,10 +2726,7 @@ export function useModuleBasicSetting(tabNum) {
|
||||
if (disjointFromTrestle && isDisjoint) {
|
||||
//최초 한번은 그냥 그린다
|
||||
//겹치는지 확인해서 포함된 모듈만 그린다
|
||||
canvas?.add(tempModule)
|
||||
moduleSetupArray.push(tempModule)
|
||||
moduleArray.push(tempModule)
|
||||
canvas.renderAll()
|
||||
addModule(tempModule, moduleSetupArray, moduleArray)
|
||||
|
||||
isInstall = true
|
||||
//마지막에 설치된 모듈의 Y 좌표
|
||||
@ -3414,21 +3416,21 @@ export function useModuleBasicSetting(tabNum) {
|
||||
|
||||
// 위쪽 변에 스냅
|
||||
if (Math.abs(smallTop - trestleTop) < trestleSnapDistance) {
|
||||
tempModule.top = trestleTop + 1
|
||||
tempModule.top = trestleTop
|
||||
}
|
||||
|
||||
// 아래쪽 변에 스냅
|
||||
if (Math.abs(smallBottom - trestleBottom) < trestleSnapDistance) {
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height - 1
|
||||
tempModule.top = trestleTop + moduleSetupSurfaces[i].height - tempModule.height
|
||||
}
|
||||
|
||||
// 왼쪽변에 스냅
|
||||
if (Math.abs(smallLeft - trestleLeft) < trestleSnapDistance) {
|
||||
tempModule.left = trestleLeft + 1
|
||||
tempModule.left = trestleLeft
|
||||
}
|
||||
//오른쪽 변에 스냅
|
||||
if (Math.abs(smallRight - trestleRight) < trestleSnapDistance) {
|
||||
tempModule.left = trestleRight - tempModule.width - 1
|
||||
tempModule.left = trestleRight - tempModule.width
|
||||
}
|
||||
|
||||
if (flowDirection === 'south' || flowDirection === 'north') {
|
||||
@ -3705,16 +3707,6 @@ export function useModuleBasicSetting(tabNum) {
|
||||
return containsBatchObjects
|
||||
}
|
||||
|
||||
/**
|
||||
* 배치면 안에 있는지 확인
|
||||
* @param {*} squarePolygon
|
||||
* @param {*} turfModuleSetupSurface
|
||||
* @returns
|
||||
*/
|
||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||
}
|
||||
|
||||
const flatRoofDownFlowSetupModule = (
|
||||
surfaceMaxLines,
|
||||
maxLengthLine,
|
||||
|
||||
@ -68,6 +68,8 @@ export function useRoofShapeSetting(id) {
|
||||
const globalLocaleState = useRecoilValue(globalLocaleStore)
|
||||
const { post } = useAxios(globalLocaleState)
|
||||
|
||||
const { addLine, removeLine } = useLine()
|
||||
|
||||
useEffect(() => {
|
||||
pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch)
|
||||
}, [pitch])
|
||||
@ -182,6 +184,41 @@ export function useRoofShapeSetting(id) {
|
||||
return
|
||||
}
|
||||
|
||||
/**
|
||||
* 외벽선이 시계방향인지 시계반대 방향인지 확인
|
||||
*/
|
||||
const outerLinePoints = outerLines.map((line) => ({ x: line.x1, y: line.y1 }))
|
||||
let counterClockwise = true
|
||||
let signedArea = 0
|
||||
|
||||
outerLinePoints.forEach((point, index) => {
|
||||
const nextPoint = outerLinePoints[(index + 1) % outerLinePoints.length]
|
||||
signedArea += point.x * nextPoint.y - point.y * nextPoint.x
|
||||
})
|
||||
|
||||
if (signedArea > 0) {
|
||||
counterClockwise = false
|
||||
}
|
||||
/** 시계 방향일 경우 외벽선 reverse*/
|
||||
if (!counterClockwise) {
|
||||
outerLines.reverse().forEach((line, index) => {
|
||||
addLine([line.x2, line.y2, line.x1, line.y1], {
|
||||
stroke: line.stroke,
|
||||
strokeWidth: line.strokeWidth,
|
||||
idx: index,
|
||||
selectable: line.selectable,
|
||||
name: 'outerLine',
|
||||
x1: line.x2,
|
||||
y1: line.y2,
|
||||
x2: line.x1,
|
||||
y2: line.y1,
|
||||
visible: line.visible,
|
||||
})
|
||||
canvas.remove(line)
|
||||
})
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
if ([1, 2, 3, 5, 6, 7, 8].includes(shapeNum)) {
|
||||
// 변별로 설정이 아닌 경우 경사를 지붕재에 적용해주어야함
|
||||
setRoofPitch()
|
||||
|
||||
@ -565,6 +565,7 @@
|
||||
"commons.north": "北",
|
||||
"commons.none": "選択しない",
|
||||
"common.type": "分類",
|
||||
"common.link.confirm": "移動しますか?",
|
||||
"font.style.normal": "通常",
|
||||
"font.style.italic": "イタリック体",
|
||||
"font.style.bold": "太字",
|
||||
|
||||
@ -565,6 +565,7 @@
|
||||
"commons.north": "북",
|
||||
"commons.none": "선택안함",
|
||||
"common.type": "분류",
|
||||
"common.link.confirm": "이동 하시겠습니까?",
|
||||
"font.style.normal": "보통",
|
||||
"font.style.italic": "기울임꼴",
|
||||
"font.style.bold": "굵게",
|
||||
|
||||
@ -2555,7 +2555,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
{ x: currentRoof.x2, y: currentRoof.y2 },
|
||||
]
|
||||
const prevHipLines = []
|
||||
const nextHipLine = []
|
||||
const nextHipLines = []
|
||||
let prevLineRidge, nextLineRidge
|
||||
|
||||
baseHipLines.forEach((current) => {
|
||||
@ -2584,7 +2584,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
y: line.y1,
|
||||
}))
|
||||
) {
|
||||
nextHipLine.push(current)
|
||||
nextHipLines.push(current)
|
||||
}
|
||||
})
|
||||
prevHipLines.forEach((current) => {
|
||||
@ -2633,7 +2633,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
})
|
||||
}
|
||||
})
|
||||
nextHipLine.forEach((current) => {
|
||||
nextHipLines.forEach((current) => {
|
||||
if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
let findPoint
|
||||
if (Math.abs(current.x1 - currentRoof.x2) <= 1 && Math.abs(current.y1 - currentRoof.y2) <= 1) {
|
||||
@ -2740,235 +2740,236 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
/** 4각*/
|
||||
if (prevLineRidge === nextLineRidge) {
|
||||
polygonPoints.push({ x: ridgeLine.x1, y: ridgeLine.y1 }, { x: ridgeLine.x2, y: ridgeLine.y2 })
|
||||
}
|
||||
/** 6각이상*/
|
||||
let isOverLap =
|
||||
currentVectorX === 0
|
||||
? (prevLineRidge.y1 <= nextLineRidge.y1 && prevLineRidge.y2 >= nextLineRidge.y1) ||
|
||||
(prevLineRidge.y1 >= nextLineRidge.y1 && prevLineRidge.y2 <= nextLineRidge.y1) ||
|
||||
(prevLineRidge.y1 <= nextLineRidge.y2 && prevLineRidge.y2 >= nextLineRidge.y2) ||
|
||||
(prevLineRidge.y1 >= nextLineRidge.y2 && prevLineRidge.y2 <= nextLineRidge.y2)
|
||||
: (prevLineRidge.x1 <= nextLineRidge.x1 && prevLineRidge.x2 >= nextLineRidge.x1) ||
|
||||
(prevLineRidge.x1 >= nextLineRidge.x1 && prevLineRidge.x2 <= nextLineRidge.x1) ||
|
||||
(prevLineRidge.x1 <= nextLineRidge.x2 && prevLineRidge.x2 >= nextLineRidge.x2) ||
|
||||
(prevLineRidge.x1 >= nextLineRidge.x2 && prevLineRidge.x2 <= nextLineRidge.x2)
|
||||
if (isOverLap) {
|
||||
const prevDistance = currentVectorX === 0 ? Math.abs(prevLineRidge.x1 - currentRoof.x1) : Math.abs(prevLineRidge.y1 - currentRoof.y1)
|
||||
const nextDistance = currentVectorX === 0 ? Math.abs(nextLineRidge.x1 - currentRoof.x1) : Math.abs(nextLineRidge.y1 - currentRoof.y1)
|
||||
|
||||
/** 현재 지붕 라인과 먼 라인의 포인트를 온전히 사용한다. */
|
||||
if (Math.abs(prevDistance - nextDistance) < 1) {
|
||||
const minX = Math.min(currentRoof.x1, currentRoof.x2, currentLine.x1, currentLine.x2)
|
||||
const maxX = Math.max(currentRoof.x1, currentRoof.x2, currentLine.x1, currentLine.x2)
|
||||
const minY = Math.min(currentRoof.y1, currentRoof.y2, currentLine.y1, currentLine.y2)
|
||||
const maxY = Math.max(currentRoof.y1, currentRoof.y2, currentLine.y1, currentLine.y2)
|
||||
if (currentVectorX === 0) {
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: minY }, { x: prevLineRidge.x1, y: maxY })
|
||||
} else {
|
||||
polygonPoints.push({ x: minX, y: prevLineRidge.y1 }, { x: maxX, y: prevLineRidge.y1 })
|
||||
}
|
||||
} else if (prevDistance < nextDistance) {
|
||||
polygonPoints.push({ x: nextLineRidge.x1, y: nextLineRidge.y1 }, { x: nextLineRidge.x2, y: nextLineRidge.y2 })
|
||||
|
||||
/** 이전라인과 교차한 마루의 포인트*/
|
||||
let prevRidgePoint1
|
||||
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
prevRidgePoint1 = polygonPoints.find(
|
||||
(point) =>
|
||||
(point.x === prevLineRidge.x1 && point.y === prevLineRidge.y1) || (point.x === prevLineRidge.x2 && point.y === prevLineRidge.y2),
|
||||
)
|
||||
} else {
|
||||
prevRidgePoint1 =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y1 === prevLineRidge.y1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
: currentRoof.x1 === prevLineRidge.x1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
|
||||
polygonPoints.push(prevRidgePoint1)
|
||||
}
|
||||
|
||||
/** 다음 라인과 교차한 마루의 포인트 중 라인과 접하지 않은 포인트*/
|
||||
let checkRidgePoint
|
||||
if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
const ridgePoint1 = polygonPoints.filter((point) => point.x === nextLineRidge.x1 && point.y === nextLineRidge.y1)
|
||||
checkRidgePoint = ridgePoint1.length > 0 ? { x: nextLineRidge.x2, y: nextLineRidge.y2 } : { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
} else {
|
||||
checkRidgePoint =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y2 !== nextLineRidge.y1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
: currentRoof.x2 !== nextLineRidge.x1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
}
|
||||
|
||||
const prevRidgePoint2 =
|
||||
currentVectorX === 0 ? { x: prevRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: prevRidgePoint1.y }
|
||||
polygonPoints.push(prevRidgePoint2)
|
||||
} else {
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: prevLineRidge.y1 }, { x: prevLineRidge.x2, y: prevLineRidge.y2 })
|
||||
|
||||
/** 다음라인과 교차한 마루의 포인트*/
|
||||
let nextRidgePoint1
|
||||
if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
nextRidgePoint1 = polygonPoints.find(
|
||||
(point) =>
|
||||
(point.x === nextLineRidge.x1 && point.y === nextLineRidge.y1) || (point.x === nextLineRidge.x2 && point.y === nextLineRidge.y2),
|
||||
)
|
||||
} else {
|
||||
nextRidgePoint1 =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y2 === nextLineRidge.y1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
: currentRoof.x2 === nextLineRidge.x1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
polygonPoints.push(nextRidgePoint1)
|
||||
}
|
||||
|
||||
/** 이전 라인과 교차한 마루의 포인트 중 라인과 접하지 않은 포인트*/
|
||||
let checkRidgePoint
|
||||
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
const ridgePoint1 = polygonPoints.filter((point) => point.x === prevLineRidge.x1 && point.y === prevLineRidge.y1)
|
||||
checkRidgePoint = ridgePoint1.length > 0 ? { x: prevLineRidge.x2, y: prevLineRidge.y2 } : { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
} else {
|
||||
checkRidgePoint =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y1 !== prevLineRidge.y1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
: currentRoof.x1 !== prevLineRidge.x1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
}
|
||||
|
||||
const nextRidgePoint2 =
|
||||
currentVectorX === 0 ? { x: nextRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: nextRidgePoint1.y }
|
||||
polygonPoints.push(nextRidgePoint2)
|
||||
}
|
||||
} else {
|
||||
/** 마루가 겹치지 않을때 */
|
||||
const otherRidgeLines = []
|
||||
/** 6각이상*/
|
||||
let isOverLap =
|
||||
currentVectorX === 0
|
||||
? (prevLineRidge.y1 <= nextLineRidge.y1 && prevLineRidge.y2 >= nextLineRidge.y1) ||
|
||||
(prevLineRidge.y1 >= nextLineRidge.y1 && prevLineRidge.y2 <= nextLineRidge.y1) ||
|
||||
(prevLineRidge.y1 <= nextLineRidge.y2 && prevLineRidge.y2 >= nextLineRidge.y2) ||
|
||||
(prevLineRidge.y1 >= nextLineRidge.y2 && prevLineRidge.y2 <= nextLineRidge.y2)
|
||||
: (prevLineRidge.x1 <= nextLineRidge.x1 && prevLineRidge.x2 >= nextLineRidge.x1) ||
|
||||
(prevLineRidge.x1 >= nextLineRidge.x1 && prevLineRidge.x2 <= nextLineRidge.x1) ||
|
||||
(prevLineRidge.x1 <= nextLineRidge.x2 && prevLineRidge.x2 >= nextLineRidge.x2) ||
|
||||
(prevLineRidge.x1 >= nextLineRidge.x2 && prevLineRidge.x2 <= nextLineRidge.x2)
|
||||
if (isOverLap) {
|
||||
const prevDistance = currentVectorX === 0 ? Math.abs(prevLineRidge.x1 - currentRoof.x1) : Math.abs(prevLineRidge.y1 - currentRoof.y1)
|
||||
const nextDistance = currentVectorX === 0 ? Math.abs(nextLineRidge.x1 - currentRoof.x1) : Math.abs(nextLineRidge.y1 - currentRoof.y1)
|
||||
|
||||
baseGableRidgeLines
|
||||
.filter((ridge) => ridge !== prevLineRidge && ridge !== nextLineRidge)
|
||||
.filter((ridge) => (currentVectorX === 0 ? ridge.x1 === ridge.x2 : ridge.y1 === ridge.y2))
|
||||
.filter((ridge) =>
|
||||
currentVectorX === 0 ? nextVectorX === Math.sign(nextLine.x1 - ridge.x1) : nextVectorY === Math.sign(nextLine.y1 - ridge.y1),
|
||||
)
|
||||
.forEach((ridge) => {
|
||||
const size = currentVectorX === 0 ? Math.abs(nextLine.x1 - ridge.x1) : Math.abs(nextLine.y1 - ridge.y1)
|
||||
otherRidgeLines.push({ ridge, size })
|
||||
})
|
||||
if (otherRidgeLines.length > 0) {
|
||||
const otherRidge = otherRidgeLines.sort((a, b) => a.size - b.size)[0].ridge
|
||||
/**
|
||||
* otherRidge이 prevRidgeLine, nextRidgeLine 과 currentLine의 사이에 있는지 확인해서 분할하여 작업
|
||||
* 지붕의 덮힘이 다르기 때문
|
||||
*/
|
||||
const isInside =
|
||||
currentVectorX === 0
|
||||
? Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - prevLineRidge.x1) &&
|
||||
Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - nextLineRidge.x1)
|
||||
: Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - prevLineRidge.y1) &&
|
||||
Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - nextLineRidge.y1)
|
||||
|
||||
if (isInside) {
|
||||
polygonPoints.push(
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
)
|
||||
|
||||
let ridgeAllPoints = [
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
]
|
||||
let ridgePoints = []
|
||||
ridgeAllPoints.forEach((point) => {
|
||||
let isOnLine = false
|
||||
roof.lines.forEach((line) => {
|
||||
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||
isOnLine = true
|
||||
}
|
||||
})
|
||||
if (!isOnLine) {
|
||||
ridgePoints.push(point)
|
||||
}
|
||||
})
|
||||
if (ridgePoints.length === 2) {
|
||||
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||
polygonPoints.push(
|
||||
{ x: otherRidge.x1, y: ridgePoints[0].y },
|
||||
{
|
||||
x: otherRidge.x1,
|
||||
y: ridgePoints[1].y,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
polygonPoints.push(
|
||||
{ x: ridgePoints[0].x, y: otherRidge.y1 },
|
||||
{
|
||||
x: ridgePoints[1].x,
|
||||
y: otherRidge.y1,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
polygonPoints.push({ x: otherRidge.x1, y: otherRidge.y1 }, { x: otherRidge.x2, y: otherRidge.y2 })
|
||||
|
||||
let ridgePoints = [
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
]
|
||||
|
||||
ridgePoints.forEach((point) => {
|
||||
let isOnLine = false
|
||||
roof.lines.forEach((line) => {
|
||||
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||
isOnLine = true
|
||||
}
|
||||
})
|
||||
if (isOnLine) {
|
||||
polygonPoints.push(point)
|
||||
}
|
||||
})
|
||||
|
||||
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||
const prevY =
|
||||
(prevLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= prevLineRidge.y2) ||
|
||||
(prevLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= prevLineRidge.y2)
|
||||
? otherRidge.y1
|
||||
: otherRidge.y2
|
||||
const nextY =
|
||||
(nextLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= nextLineRidge.y2) ||
|
||||
(nextLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= nextLineRidge.y2)
|
||||
? otherRidge.y1
|
||||
: otherRidge.y2
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: prevY }, { x: nextLineRidge.x1, y: nextY })
|
||||
/** 현재 지붕 라인과 먼 라인의 포인트를 온전히 사용한다. */
|
||||
if (Math.abs(prevDistance - nextDistance) < 1) {
|
||||
const minX = Math.min(currentRoof.x1, currentRoof.x2, currentLine.x1, currentLine.x2)
|
||||
const maxX = Math.max(currentRoof.x1, currentRoof.x2, currentLine.x1, currentLine.x2)
|
||||
const minY = Math.min(currentRoof.y1, currentRoof.y2, currentLine.y1, currentLine.y2)
|
||||
const maxY = Math.max(currentRoof.y1, currentRoof.y2, currentLine.y1, currentLine.y2)
|
||||
if (currentVectorX === 0) {
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: minY }, { x: prevLineRidge.x1, y: maxY })
|
||||
} else {
|
||||
const prevX =
|
||||
(prevLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= prevLineRidge.x2) ||
|
||||
(prevLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= prevLineRidge.x2)
|
||||
? otherRidge.x1
|
||||
: otherRidge.x2
|
||||
const nextX =
|
||||
(nextLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= nextLineRidge.x2) ||
|
||||
(nextLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= nextLineRidge.x2)
|
||||
? otherRidge.x1
|
||||
: otherRidge.x2
|
||||
polygonPoints.push({ x: prevX, y: prevLineRidge.y1 }, { x: nextX, y: nextLineRidge.y1 })
|
||||
polygonPoints.push({ x: minX, y: prevLineRidge.y1 }, { x: maxX, y: prevLineRidge.y1 })
|
||||
}
|
||||
} else if (prevDistance < nextDistance) {
|
||||
polygonPoints.push({ x: nextLineRidge.x1, y: nextLineRidge.y1 }, { x: nextLineRidge.x2, y: nextLineRidge.y2 })
|
||||
|
||||
/** 이전라인과 교차한 마루의 포인트*/
|
||||
let prevRidgePoint1
|
||||
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
prevRidgePoint1 = polygonPoints.find(
|
||||
(point) =>
|
||||
(point.x === prevLineRidge.x1 && point.y === prevLineRidge.y1) || (point.x === prevLineRidge.x2 && point.y === prevLineRidge.y2),
|
||||
)
|
||||
} else {
|
||||
prevRidgePoint1 =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y1 === prevLineRidge.y1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
: currentRoof.x1 === prevLineRidge.x1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
|
||||
polygonPoints.push(prevRidgePoint1)
|
||||
}
|
||||
|
||||
/** 다음 라인과 교차한 마루의 포인트 중 라인과 접하지 않은 포인트*/
|
||||
let checkRidgePoint
|
||||
if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
const ridgePoint1 = polygonPoints.filter((point) => point.x === nextLineRidge.x1 && point.y === nextLineRidge.y1)
|
||||
checkRidgePoint = ridgePoint1.length > 0 ? { x: nextLineRidge.x2, y: nextLineRidge.y2 } : { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
} else {
|
||||
checkRidgePoint =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y2 !== nextLineRidge.y1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
: currentRoof.x2 !== nextLineRidge.x1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
}
|
||||
|
||||
const prevRidgePoint2 =
|
||||
currentVectorX === 0 ? { x: prevRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: prevRidgePoint1.y }
|
||||
polygonPoints.push(prevRidgePoint2)
|
||||
} else {
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: prevLineRidge.y1 }, { x: prevLineRidge.x2, y: prevLineRidge.y2 })
|
||||
|
||||
/** 다음라인과 교차한 마루의 포인트*/
|
||||
let nextRidgePoint1
|
||||
if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
nextRidgePoint1 = polygonPoints.find(
|
||||
(point) =>
|
||||
(point.x === nextLineRidge.x1 && point.y === nextLineRidge.y1) || (point.x === nextLineRidge.x2 && point.y === nextLineRidge.y2),
|
||||
)
|
||||
} else {
|
||||
nextRidgePoint1 =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y2 === nextLineRidge.y1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
: currentRoof.x2 === nextLineRidge.x1
|
||||
? { x: nextLineRidge.x1, y: nextLineRidge.y1 }
|
||||
: { x: nextLineRidge.x2, y: nextLineRidge.y2 }
|
||||
polygonPoints.push(nextRidgePoint1)
|
||||
}
|
||||
|
||||
/** 이전 라인과 교차한 마루의 포인트 중 라인과 접하지 않은 포인트*/
|
||||
let checkRidgePoint
|
||||
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
||||
const ridgePoint1 = polygonPoints.filter((point) => point.x === prevLineRidge.x1 && point.y === prevLineRidge.y1)
|
||||
checkRidgePoint = ridgePoint1.length > 0 ? { x: prevLineRidge.x2, y: prevLineRidge.y2 } : { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
} else {
|
||||
checkRidgePoint =
|
||||
currentVectorX === 0
|
||||
? currentRoof.y1 !== prevLineRidge.y1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
: currentRoof.x1 !== prevLineRidge.x1
|
||||
? { x: prevLineRidge.x1, y: prevLineRidge.y1 }
|
||||
: { x: prevLineRidge.x2, y: prevLineRidge.y2 }
|
||||
}
|
||||
|
||||
const nextRidgePoint2 =
|
||||
currentVectorX === 0 ? { x: nextRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: nextRidgePoint1.y }
|
||||
polygonPoints.push(nextRidgePoint2)
|
||||
}
|
||||
} else {
|
||||
/** 마루가 겹치지 않을때 */
|
||||
const otherRidgeLines = []
|
||||
|
||||
baseGableRidgeLines
|
||||
.filter((ridge) => ridge !== prevLineRidge && ridge !== nextLineRidge)
|
||||
.filter((ridge) => (currentVectorX === 0 ? ridge.x1 === ridge.x2 : ridge.y1 === ridge.y2))
|
||||
.filter((ridge) =>
|
||||
currentVectorX === 0 ? nextVectorX === Math.sign(nextLine.x1 - ridge.x1) : nextVectorY === Math.sign(nextLine.y1 - ridge.y1),
|
||||
)
|
||||
.forEach((ridge) => {
|
||||
const size = currentVectorX === 0 ? Math.abs(nextLine.x1 - ridge.x1) : Math.abs(nextLine.y1 - ridge.y1)
|
||||
otherRidgeLines.push({ ridge, size })
|
||||
})
|
||||
if (otherRidgeLines.length > 0) {
|
||||
const otherRidge = otherRidgeLines.sort((a, b) => a.size - b.size)[0].ridge
|
||||
/**
|
||||
* otherRidge이 prevRidgeLine, nextRidgeLine 과 currentLine의 사이에 있는지 확인해서 분할하여 작업
|
||||
* 지붕의 덮힘이 다르기 때문
|
||||
*/
|
||||
const isInside =
|
||||
currentVectorX === 0
|
||||
? Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - prevLineRidge.x1) &&
|
||||
Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - nextLineRidge.x1)
|
||||
: Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - prevLineRidge.y1) &&
|
||||
Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - nextLineRidge.y1)
|
||||
|
||||
if (isInside) {
|
||||
polygonPoints.push(
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
)
|
||||
|
||||
let ridgeAllPoints = [
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
]
|
||||
let ridgePoints = []
|
||||
ridgeAllPoints.forEach((point) => {
|
||||
let isOnLine = false
|
||||
roof.lines.forEach((line) => {
|
||||
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||
isOnLine = true
|
||||
}
|
||||
})
|
||||
if (!isOnLine) {
|
||||
ridgePoints.push(point)
|
||||
}
|
||||
})
|
||||
if (ridgePoints.length === 2) {
|
||||
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||
polygonPoints.push(
|
||||
{ x: otherRidge.x1, y: ridgePoints[0].y },
|
||||
{
|
||||
x: otherRidge.x1,
|
||||
y: ridgePoints[1].y,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
polygonPoints.push(
|
||||
{ x: ridgePoints[0].x, y: otherRidge.y1 },
|
||||
{
|
||||
x: ridgePoints[1].x,
|
||||
y: otherRidge.y1,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
polygonPoints.push({ x: otherRidge.x1, y: otherRidge.y1 }, { x: otherRidge.x2, y: otherRidge.y2 })
|
||||
|
||||
let ridgePoints = [
|
||||
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||
]
|
||||
|
||||
ridgePoints.forEach((point) => {
|
||||
let isOnLine = false
|
||||
roof.lines.forEach((line) => {
|
||||
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||
isOnLine = true
|
||||
}
|
||||
})
|
||||
if (isOnLine) {
|
||||
polygonPoints.push(point)
|
||||
}
|
||||
})
|
||||
|
||||
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||
const prevY =
|
||||
(prevLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= prevLineRidge.y2) ||
|
||||
(prevLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= prevLineRidge.y2)
|
||||
? otherRidge.y1
|
||||
: otherRidge.y2
|
||||
const nextY =
|
||||
(nextLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= nextLineRidge.y2) ||
|
||||
(nextLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= nextLineRidge.y2)
|
||||
? otherRidge.y1
|
||||
: otherRidge.y2
|
||||
polygonPoints.push({ x: prevLineRidge.x1, y: prevY }, { x: nextLineRidge.x1, y: nextY })
|
||||
} else {
|
||||
const prevX =
|
||||
(prevLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= prevLineRidge.x2) ||
|
||||
(prevLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= prevLineRidge.x2)
|
||||
? otherRidge.x1
|
||||
: otherRidge.x2
|
||||
const nextX =
|
||||
(nextLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= nextLineRidge.x2) ||
|
||||
(nextLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= nextLineRidge.x2)
|
||||
? otherRidge.x1
|
||||
: otherRidge.x2
|
||||
polygonPoints.push({ x: prevX, y: prevLineRidge.y1 }, { x: nextX, y: nextLineRidge.y1 })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3043,13 +3044,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||
const intersection = edgesIntersection(checkEdge, lineEdge)
|
||||
if (intersection) {
|
||||
if (isPointOnLine(line, intersection)) {
|
||||
intersectionRoofs.push({
|
||||
line,
|
||||
intersection,
|
||||
size: Big(intersection.x).minus(currentMidX).abs().pow(2).plus(Big(intersection.y).minus(currentMidY).abs().pow(2)).sqrt(),
|
||||
})
|
||||
}
|
||||
intersectionRoofs.push({
|
||||
line,
|
||||
intersection,
|
||||
size: Big(intersection.x).minus(currentMidX).abs().pow(2).plus(Big(intersection.y).minus(currentMidY).abs().pow(2)).sqrt(),
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@ -3063,13 +3062,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||
const intersection = edgesIntersection(checkEdge, lineEdge)
|
||||
if (intersection) {
|
||||
if (isPointOnLine(line, intersection)) {
|
||||
intersectionRoofs.push({
|
||||
line,
|
||||
intersection,
|
||||
size: Big(intersection.x).minus(currentMidX).abs().pow(2).plus(Big(intersection.y).minus(currentMidY).abs().pow(2)).sqrt(),
|
||||
})
|
||||
}
|
||||
intersectionRoofs.push({
|
||||
line,
|
||||
intersection,
|
||||
size: Big(intersection.x).minus(currentMidX).abs().pow(2).plus(Big(intersection.y).minus(currentMidY).abs().pow(2)).sqrt(),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user