회로 할당 작업중
This commit is contained in:
parent
982738939a
commit
e885e7b939
@ -164,6 +164,11 @@ export const SAVE_KEY = [
|
|||||||
'moduleCompass',
|
'moduleCompass',
|
||||||
'isFixed',
|
'isFixed',
|
||||||
'modules',
|
'modules',
|
||||||
|
'rackLen',
|
||||||
|
'itemId',
|
||||||
|
'supFitQty',
|
||||||
|
'supFitIntvlPct',
|
||||||
|
'rackLen',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype]
|
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype]
|
||||||
|
|||||||
@ -12,12 +12,16 @@ import { get } from 'react-hook-form'
|
|||||||
import { correntObjectNoState } from '@/store/settingAtom'
|
import { correntObjectNoState } from '@/store/settingAtom'
|
||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
|
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { powerConditionalState } from '@/store/circuitTrestleAtom'
|
import { powerConditionalState } from '@/store/circuitTrestleAtom'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
|
||||||
|
import { trestleDetailData } from '@/common/example'
|
||||||
|
import { useTrestle } from '@/hooks/module/useTrestle'
|
||||||
|
|
||||||
const ALLOCATION_TYPE = {
|
const ALLOCATION_TYPE = {
|
||||||
AUTO: 'auto',
|
AUTO: 'auto',
|
||||||
PASSIVITY: 'passivity',
|
PASSIVITY: 'passivity',
|
||||||
@ -29,12 +33,17 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
// 탭 번호 2: 회로 할당
|
// 탭 번호 2: 회로 할당
|
||||||
const [tabNum, setTabNum] = useState(1)
|
const [tabNum, setTabNum] = useState(1)
|
||||||
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
|
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
|
||||||
const canvas = useRecoilValue(canvasState)
|
|
||||||
const { swalFire } = useSwal()
|
|
||||||
|
|
||||||
const apply = () => {
|
const [makers, setMakers] = useState([])
|
||||||
closePopup(id)
|
const [series, setSeries] = useState([])
|
||||||
}
|
const [models, setModels] = useState([])
|
||||||
|
const [selectedMaker, setSelectedMaker] = useState(null)
|
||||||
|
const [selectedModels, setSelectedModels] = useState(null)
|
||||||
|
const [selectedSeries, setSelectedSeries] = useState(null)
|
||||||
|
const correntObjectNo = useRecoilValue(correntObjectNoState)
|
||||||
|
const { getPcsMakerList } = useMasterController()
|
||||||
|
const { managementState, setManagementState, managementStateLoaded } = useContext(GlobalDataContext)
|
||||||
|
const { apply } = useTrestle()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log(canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE))
|
// console.log(canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE))
|
||||||
|
|||||||
@ -1136,247 +1136,6 @@ export function useModuleBasicSetting() {
|
|||||||
// calculateForApi()
|
// calculateForApi()
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateForApi = () => {
|
|
||||||
const moduleSufaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
|
||||||
|
|
||||||
const results = []
|
|
||||||
|
|
||||||
moduleSufaces.forEach((moduleSurface) => {
|
|
||||||
const centerPoints = []
|
|
||||||
const direction = moduleSurface.direction
|
|
||||||
const modules = moduleSurface.modules
|
|
||||||
|
|
||||||
modules.forEach((module, index) => {
|
|
||||||
module.tempIndex = index
|
|
||||||
const { x, y } = module.getCenterPoint()
|
|
||||||
const { width, height } = module
|
|
||||||
centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index })
|
|
||||||
})
|
|
||||||
|
|
||||||
if (centerPoints.length === 0) return
|
|
||||||
|
|
||||||
//완전 노출 하면
|
|
||||||
let exposedBottom = 0
|
|
||||||
// 반 노출 하면
|
|
||||||
let exposedHalfBottom = 0
|
|
||||||
// 완전 노출 상면
|
|
||||||
let exposedTop = 0
|
|
||||||
//반 노출 상면
|
|
||||||
let exposedHalfTop = 0
|
|
||||||
// 완전 접면
|
|
||||||
let touchDimension = 0
|
|
||||||
//반접면
|
|
||||||
let halfTouchDimension = 0
|
|
||||||
// 노출하면 체크
|
|
||||||
centerPoints.forEach((centerPoint, index) => {
|
|
||||||
const { x, y, width, height } = centerPoint
|
|
||||||
// centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
|
|
||||||
let bottomCell
|
|
||||||
let bottomLeftPoint
|
|
||||||
let bottomRightPoint
|
|
||||||
let leftBottomCnt
|
|
||||||
let rightBottomCnt
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case 'south':
|
|
||||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2)
|
|
||||||
bottomLeftPoint = { x: x - width / 2, y: y + height }
|
|
||||||
bottomRightPoint = { x: x + width / 2, y: y + height }
|
|
||||||
break
|
|
||||||
case 'north':
|
|
||||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2)
|
|
||||||
bottomLeftPoint = { x: x + width / 2, y: y - height }
|
|
||||||
bottomRightPoint = { x: x - width / 2, y: y - height }
|
|
||||||
break
|
|
||||||
case 'east':
|
|
||||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
|
||||||
bottomLeftPoint = { x: x + width, y: y + height / 2 }
|
|
||||||
bottomRightPoint = { x: x + width, y: y - height / 2 }
|
|
||||||
break
|
|
||||||
case 'west':
|
|
||||||
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
|
||||||
bottomLeftPoint = { x: x - width, y: y - height / 2 }
|
|
||||||
bottomRightPoint = { x: x - width, y: y + height / 2 }
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bottomCell.length === 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 바로 아래에 셀이 없는 경우 물떼세 배치가 왼쪽 되어있는 셀을 찾는다.
|
|
||||||
leftBottomCnt = centerPoints.filter(
|
|
||||||
(centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2,
|
|
||||||
).length
|
|
||||||
rightBottomCnt = centerPoints.filter(
|
|
||||||
(centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2,
|
|
||||||
).length
|
|
||||||
|
|
||||||
if (leftBottomCnt + rightBottomCnt === 1) {
|
|
||||||
exposedHalfBottom++
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 노출상면 체크
|
|
||||||
|
|
||||||
centerPoints.forEach((centerPoint, index) => {
|
|
||||||
const { x, y, width, height } = centerPoint
|
|
||||||
|
|
||||||
let topCell
|
|
||||||
let topLeftPoint
|
|
||||||
let topRightPoint
|
|
||||||
let leftTopCnt
|
|
||||||
let rightTopCnt
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case 'south':
|
|
||||||
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2)
|
|
||||||
topLeftPoint = { x: x - width / 2, y: y - height }
|
|
||||||
topRightPoint = { x: x + width / 2, y: y - height }
|
|
||||||
break
|
|
||||||
case 'north':
|
|
||||||
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2)
|
|
||||||
topLeftPoint = { x: x + width / 2, y: y + height }
|
|
||||||
topRightPoint = { x: x - width / 2, y: y + height }
|
|
||||||
break
|
|
||||||
case 'east':
|
|
||||||
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
|
||||||
topLeftPoint = { x: x - width, y: y + height / 2 }
|
|
||||||
topRightPoint = { x: x - width, y: y - height / 2 }
|
|
||||||
break
|
|
||||||
case 'west':
|
|
||||||
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
|
||||||
topLeftPoint = { x: x + width, y: y - height / 2 }
|
|
||||||
topRightPoint = { x: x + width, y: y + height / 2 }
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topCell.length === 1) {
|
|
||||||
touchDimension++
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
leftTopCnt = centerPoints.filter(
|
|
||||||
(centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2,
|
|
||||||
).length
|
|
||||||
rightTopCnt = centerPoints.filter(
|
|
||||||
(centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2,
|
|
||||||
).length
|
|
||||||
|
|
||||||
if (leftTopCnt + rightTopCnt === 2) {
|
|
||||||
touchDimension++
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftTopCnt + rightTopCnt === 1) {
|
|
||||||
exposedHalfTop++
|
|
||||||
halfTouchDimension++
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (leftTopCnt + rightTopCnt === 0) {
|
|
||||||
exposedTop++
|
|
||||||
}
|
|
||||||
})
|
|
||||||
// 완전 노출 하면 계산
|
|
||||||
|
|
||||||
/*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId)
|
|
||||||
const points = cells.map((cell) => {
|
|
||||||
return cell.getCenterPoint()
|
|
||||||
})*/
|
|
||||||
const groupPoints = groupCoordinates(centerPoints, modules[0], direction)
|
|
||||||
|
|
||||||
groupPoints.forEach((group) => {
|
|
||||||
let maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y
|
|
||||||
let minY = group.reduce((acc, cur) => (acc.y < cur.y ? acc : cur)).y
|
|
||||||
let maxX = group.reduce((acc, cur) => (acc.x > cur.x ? acc : cur)).x
|
|
||||||
let minX = group.reduce((acc, cur) => (acc.x < cur.x ? acc : cur)).x
|
|
||||||
|
|
||||||
let maxYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - maxY) < 2)
|
|
||||||
let minYCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.y - minY) < 2)
|
|
||||||
let maxXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - maxX) < 2)
|
|
||||||
let minXCenterPoint = group.filter((centerPoint) => Math.abs(centerPoint.x - minX) < 2)
|
|
||||||
|
|
||||||
switch (direction) {
|
|
||||||
case 'south':
|
|
||||||
exposedBottom += maxYCenterPoint.length
|
|
||||||
break
|
|
||||||
case 'north':
|
|
||||||
exposedBottom += minYCenterPoint.length
|
|
||||||
break
|
|
||||||
case 'east':
|
|
||||||
exposedBottom += maxXCenterPoint.length
|
|
||||||
break
|
|
||||||
case 'west':
|
|
||||||
exposedBottom += minXCenterPoint.length
|
|
||||||
break
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
results.push({
|
|
||||||
exposedBottom,
|
|
||||||
exposedHalfBottom,
|
|
||||||
exposedTop,
|
|
||||||
exposedHalfTop,
|
|
||||||
touchDimension,
|
|
||||||
halfTouchDimension,
|
|
||||||
})
|
|
||||||
console.log({
|
|
||||||
direction,
|
|
||||||
exposedBottom,
|
|
||||||
exposedHalfBottom,
|
|
||||||
exposedTop,
|
|
||||||
exposedHalfTop,
|
|
||||||
touchDimension,
|
|
||||||
halfTouchDimension,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return results
|
|
||||||
}
|
|
||||||
|
|
||||||
// polygon 내부 cell들의 centerPoint 배열을 그룹화 해서 반환
|
|
||||||
const groupCoordinates = (points, moduleExample, direction) => {
|
|
||||||
const groups = []
|
|
||||||
const visited = new Set()
|
|
||||||
const width = Math.floor(moduleExample.width)
|
|
||||||
const height = Math.floor(moduleExample.height)
|
|
||||||
const horizonPadding = 0 // 가로 패딩
|
|
||||||
const verticalPadding = 0 // 세로 패딩
|
|
||||||
|
|
||||||
function isAdjacent(p1, p2) {
|
|
||||||
const dx = Math.abs(p1.x - p2.x)
|
|
||||||
const dy = Math.abs(p1.y - p2.y)
|
|
||||||
return (
|
|
||||||
(Math.abs(width + horizonPadding - dx) < 2 && dy < 2) ||
|
|
||||||
(dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 ||
|
|
||||||
(Math.abs(dx - width / 2 + horizonPadding / 2) < 2 && Math.abs(dy - height + verticalPadding) < 2)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function dfs(point, group) {
|
|
||||||
visited.add(`${point.x},${point.y}`)
|
|
||||||
group.push(point)
|
|
||||||
|
|
||||||
for (const nextPoint of points) {
|
|
||||||
const key = `${nextPoint.x},${nextPoint.y}`
|
|
||||||
if (!visited.has(key) && isAdjacent(point, nextPoint)) {
|
|
||||||
dfs(nextPoint, group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const point of points) {
|
|
||||||
const key = `${point.x},${point.y}`
|
|
||||||
if (!visited.has(key)) {
|
|
||||||
const group = []
|
|
||||||
dfs(point, group)
|
|
||||||
groups.push(group)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups
|
|
||||||
}
|
|
||||||
|
|
||||||
const coordToTurfPolygon = (points) => {
|
const coordToTurfPolygon = (points) => {
|
||||||
const coordinates = points.map((point) => [point.x, point.y])
|
const coordinates = points.map((point) => [point.x, point.y])
|
||||||
coordinates.push(coordinates[0])
|
coordinates.push(coordinates[0])
|
||||||
|
|||||||
740
src/hooks/module/useTrestle.js
Normal file
740
src/hooks/module/useTrestle.js
Normal file
@ -0,0 +1,740 @@
|
|||||||
|
import { useRecoilValue } from 'recoil'
|
||||||
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
|
import { POLYGON_TYPE } from '@/common/common'
|
||||||
|
import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||||
|
|
||||||
|
// 회로 및 가대설정
|
||||||
|
export const useTrestle = () => {
|
||||||
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터
|
||||||
|
|
||||||
|
const apply = () => {
|
||||||
|
// rack은 맵 형태의 객체인데 key value 형태로 되어있다.
|
||||||
|
// 이때 이 형태를 [{key, value}, ...] 형태로 바꿔야 함.
|
||||||
|
/*const rackInfos = Object.keys(rack).map((key) => {
|
||||||
|
return { key, value: rack[key] }
|
||||||
|
})*/
|
||||||
|
|
||||||
|
//처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함.
|
||||||
|
// exposedBottomPoints는 노출 최하면 들의 centerPoint 배열.
|
||||||
|
|
||||||
|
const surfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||||
|
// 기존 eaveBar를 삭제
|
||||||
|
canvas.getObjects().forEach((obj) => {
|
||||||
|
if (obj.name === 'eaveBar' || obj.name === 'rack') {
|
||||||
|
canvas.remove(obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
surfaces.forEach((surface) => {
|
||||||
|
const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId)
|
||||||
|
const roofMaterialIndex = parent.roofMaterial.index
|
||||||
|
const construction = moduleSelectionData.roofConstructions.find((construction) => construction.roofIndex === roofMaterialIndex).construction
|
||||||
|
let isEaveBar = construction.setupCover
|
||||||
|
let isSnowGuard = construction.setupSnowCover
|
||||||
|
|
||||||
|
const rack = surface.trestleDetail.rack
|
||||||
|
const { rackQty, rackIntvlPct } = surface.trestleDetail
|
||||||
|
const rackInfos = Object.keys(rack).map((key) => {
|
||||||
|
return { key, value: rack[key] }
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = calculateForApi(surface)
|
||||||
|
const centerPoints = result.centerPoints
|
||||||
|
|
||||||
|
const exposedBottomModules = [] // 아래 두면이 모두 노출 되어있는 경우
|
||||||
|
const leftExposedHalfBottomModules = [] // 왼쪽 면만 노출되어있는 경우
|
||||||
|
const rightExposedHalfBottomPoints = [] // 오른쪽 면만 노출되어 있는 경우
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
modules.forEach((module) => {
|
||||||
|
const { x, y } = module.getCenterPoint()
|
||||||
|
const isExposedBottom = result.exposedBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
|
||||||
|
const isLeftExposedHalfBottom = result.leftExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
|
||||||
|
const isRightExposedHalfBottom = result.rightExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2)
|
||||||
|
if (isExposedBottom) {
|
||||||
|
exposedBottomModules.push(module)
|
||||||
|
}
|
||||||
|
if (isLeftExposedHalfBottom) {
|
||||||
|
leftExposedHalfBottomModules.push(module)
|
||||||
|
}
|
||||||
|
if (isRightExposedHalfBottom) {
|
||||||
|
rightExposedHalfBottomPoints.push(module)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'eaveBar')
|
||||||
|
.forEach((obj) => {
|
||||||
|
canvas.remove(obj)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isEaveBar) {
|
||||||
|
// 처마력바설치 true인 경우 설치
|
||||||
|
exposedBottomModules.forEach((module) => {
|
||||||
|
//TODO : 방향별로 처마력바 설치해야함
|
||||||
|
const bottomPoints = findTopTwoPoints([...module.points])
|
||||||
|
if (!bottomPoints) return
|
||||||
|
const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], {
|
||||||
|
name: 'eaveBar',
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 4,
|
||||||
|
selectable: false,
|
||||||
|
})
|
||||||
|
canvas.add(eaveBar)
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산
|
||||||
|
// 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈
|
||||||
|
exposedBottomModules.forEach((module) => {
|
||||||
|
const { width, height } = module
|
||||||
|
let { x: startX, y: startY } = { ...module.getCenterPoint() }
|
||||||
|
let { x, y } = { ...module.getCenterPoint() }
|
||||||
|
const direction = 'south'
|
||||||
|
//TODO : 방향별로 가대 설치해야함
|
||||||
|
|
||||||
|
let leftRows = 1
|
||||||
|
let rightRows = 1
|
||||||
|
let centerRows = 1
|
||||||
|
let hasNextModule = true
|
||||||
|
let findLeft = true
|
||||||
|
let findRight = true
|
||||||
|
|
||||||
|
//우선 절반을 나눈 뒤 왼쪽부터 찾는다.
|
||||||
|
while (hasNextModule) {
|
||||||
|
//바로 위에 있는지 확인한다.
|
||||||
|
let nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
leftRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
// 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
|
||||||
|
if (findLeft) {
|
||||||
|
const topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2
|
||||||
|
})
|
||||||
|
findLeft = false
|
||||||
|
} else {
|
||||||
|
const topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2
|
||||||
|
})
|
||||||
|
findLeft = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
leftRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
hasNextModule = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNextModule = true
|
||||||
|
x = startX
|
||||||
|
y = startY
|
||||||
|
|
||||||
|
// 오른쪽 찾는다.
|
||||||
|
while (hasNextModule) {
|
||||||
|
//바로 위에 있는지 확인한다.
|
||||||
|
let nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
rightRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
// 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
|
||||||
|
if (findRight) {
|
||||||
|
const topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2
|
||||||
|
})
|
||||||
|
findRight = false
|
||||||
|
} else {
|
||||||
|
const topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2
|
||||||
|
})
|
||||||
|
findRight = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
rightRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
hasNextModule = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hasNextModule = true
|
||||||
|
x = startX
|
||||||
|
y = startY
|
||||||
|
|
||||||
|
// 센터 찾는다.
|
||||||
|
while (hasNextModule) {
|
||||||
|
//바로 위에 있는지 확인한다.
|
||||||
|
let nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
centerRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
hasNextModule = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
|
||||||
|
const leftRacks = rackInfos.find((rack) => {
|
||||||
|
return rack.value.moduleRows === leftRows
|
||||||
|
})?.value.racks
|
||||||
|
|
||||||
|
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
|
||||||
|
const rightRacks = rackInfos.find((rack) => {
|
||||||
|
return rack.value.moduleRows === rightRows
|
||||||
|
})?.value.racks
|
||||||
|
// 해당 rack으로 그려준다.
|
||||||
|
|
||||||
|
const centerRacks = rackInfos.find((rack) => {
|
||||||
|
return rack.value.moduleRows === centerRows
|
||||||
|
})?.value.racks
|
||||||
|
|
||||||
|
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L')
|
||||||
|
drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R')
|
||||||
|
|
||||||
|
if (rackQty === 3) {
|
||||||
|
//rack 갯수가 3개인 경우는 중간렉도 추가해줘야함
|
||||||
|
drawRacks(centerRacks, rackQty, rackIntvlPct, module, direction, 'C')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 왼쪽아래에 모듈이 없는 모듈들
|
||||||
|
leftExposedHalfBottomModules.forEach((module) => {
|
||||||
|
const { width, height } = module
|
||||||
|
let { x: startX, y: startY } = { ...module.getCenterPoint() }
|
||||||
|
let { x, y } = { ...module.getCenterPoint() }
|
||||||
|
const direction = 'south'
|
||||||
|
//TODO : 방향별로 가대 설치해야함
|
||||||
|
|
||||||
|
let leftRows = 1
|
||||||
|
let hasNextModule = true
|
||||||
|
let findLeft = true
|
||||||
|
|
||||||
|
//우선 절반을 나눈 뒤 왼쪽부터 찾는다.
|
||||||
|
while (hasNextModule) {
|
||||||
|
//바로 위에 있는지 확인한다.
|
||||||
|
let nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
leftRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
// 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
|
||||||
|
if (findLeft) {
|
||||||
|
const topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2
|
||||||
|
})
|
||||||
|
findLeft = false
|
||||||
|
} else {
|
||||||
|
const topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2
|
||||||
|
})
|
||||||
|
findLeft = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
leftRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
hasNextModule = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모듈의 왼쪽 부터 그릴 랙 정보를 가져온다.
|
||||||
|
const leftRacks = rackInfos.find((rack) => {
|
||||||
|
return rack.value.moduleRows === leftRows
|
||||||
|
})?.value.racks
|
||||||
|
|
||||||
|
drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L')
|
||||||
|
})
|
||||||
|
// 오른쪽 아래에 모듈이 없는 모듈들
|
||||||
|
rightExposedHalfBottomPoints.forEach((module) => {
|
||||||
|
const { width, height } = module
|
||||||
|
let { x: startX, y: startY } = { ...module.getCenterPoint() }
|
||||||
|
let { x, y } = { ...module.getCenterPoint() }
|
||||||
|
const direction = 'south'
|
||||||
|
//TODO : 방향별로 가대 설치해야함
|
||||||
|
|
||||||
|
let rightRows = 1
|
||||||
|
let hasNextModule = true
|
||||||
|
let findRight = true
|
||||||
|
|
||||||
|
// 오른쪽 찾는다.
|
||||||
|
while (hasNextModule) {
|
||||||
|
//바로 위에 있는지 확인한다.
|
||||||
|
let nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2
|
||||||
|
})
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
rightRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
// 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다.
|
||||||
|
if (findRight) {
|
||||||
|
const topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2
|
||||||
|
})
|
||||||
|
findRight = false
|
||||||
|
} else {
|
||||||
|
const topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
nextModule = centerPoints.find((centerPoint) => {
|
||||||
|
return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2
|
||||||
|
})
|
||||||
|
findRight = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextModule) {
|
||||||
|
// 바로 위 모듈을 찾는다.
|
||||||
|
rightRows++
|
||||||
|
x = nextModule.x
|
||||||
|
y = nextModule.y
|
||||||
|
} else {
|
||||||
|
hasNextModule = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모듈의 오른쪽 부터 그릴 랙 정보를 가져온다.
|
||||||
|
const rightRacks = rackInfos.find((rack) => {
|
||||||
|
return rack.value.moduleRows === rightRows
|
||||||
|
})?.value.racks
|
||||||
|
// 해당 rack으로 그려준다.
|
||||||
|
|
||||||
|
drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/*switch (rackYn) {
|
||||||
|
case 'Y': {
|
||||||
|
// rack이 Y일 경우 rackQty가 필요함
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'N': {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
// 지지금구 설치
|
||||||
|
installBracket()
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction = 'south', l) => {
|
||||||
|
const { width, height } = module
|
||||||
|
|
||||||
|
let startPointX, startPointY
|
||||||
|
|
||||||
|
switch (l) {
|
||||||
|
case 'L': {
|
||||||
|
// 왼쪽부분 시작 점
|
||||||
|
if (direction === 'south') {
|
||||||
|
const x = module.left
|
||||||
|
const y = module.top + module.height / 2
|
||||||
|
startPointX = x + width / rackIntvlPct
|
||||||
|
startPointY = y + height / 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'R': {
|
||||||
|
// 오른쪽부분 시작 점
|
||||||
|
if (direction === 'south') {
|
||||||
|
const x = module.left + module.width
|
||||||
|
const y = module.top + module.height / 2
|
||||||
|
startPointX = x - width / rackIntvlPct
|
||||||
|
startPointY = y + height / 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'C': {
|
||||||
|
// 중간부분 시작점
|
||||||
|
if (direction === 'south') {
|
||||||
|
startPointX = x
|
||||||
|
startPointY = y + height / 2
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case 'south': {
|
||||||
|
rackInfos.forEach((rackInfo) => {
|
||||||
|
const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo
|
||||||
|
|
||||||
|
const rackLength = rackLen / 10
|
||||||
|
|
||||||
|
const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY - rackLength], {
|
||||||
|
name: 'rack',
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 4,
|
||||||
|
selectable: false,
|
||||||
|
supFitQty,
|
||||||
|
supFitIntvlPct,
|
||||||
|
rackLen,
|
||||||
|
rackId: itemId,
|
||||||
|
direction: 'top',
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.add(rack)
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
startPointY -= rackLength + 3
|
||||||
|
})
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const installBracket = () => {
|
||||||
|
const racks = canvas.getObjects().filter((obj) => obj.name === 'rack')
|
||||||
|
// name이 bracket인 객체를 찾아서 삭제
|
||||||
|
canvas.getObjects().forEach((obj) => {
|
||||||
|
if (obj.name === 'bracket') {
|
||||||
|
canvas.remove(obj)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
|
||||||
|
racks.forEach((rack) => {
|
||||||
|
const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen } = rack
|
||||||
|
|
||||||
|
const moduleLength = 10
|
||||||
|
|
||||||
|
if (direction === 'top') {
|
||||||
|
const result = getBracketPoints(supFitQty, supFitIntvlPct)
|
||||||
|
|
||||||
|
result.forEach((percent) => {
|
||||||
|
const bracket = new fabric.Rect({
|
||||||
|
left: x2 - moduleLength / 3,
|
||||||
|
top: y2 + (rackLen / 10) * percent,
|
||||||
|
fill: 'green',
|
||||||
|
name: 'bracket',
|
||||||
|
width: moduleLength,
|
||||||
|
height: moduleLength,
|
||||||
|
selectable: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
canvas.add(bracket)
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getBracketPoints = (n, percent) => {
|
||||||
|
if (n < 2) {
|
||||||
|
throw new Error('Number of points must be at least 2')
|
||||||
|
}
|
||||||
|
|
||||||
|
const points = []
|
||||||
|
const topY = percent / 100 // 맨 위의 점의 y 좌표 (10%)
|
||||||
|
const bottomY = 1 - percent / 100 // 맨 아래의 점의 y 좌표 (90%)
|
||||||
|
|
||||||
|
// 맨 위의 점 추가
|
||||||
|
points.push(topY)
|
||||||
|
|
||||||
|
// 중간 점들 추가
|
||||||
|
const interval = (bottomY - topY) / (n - 1)
|
||||||
|
for (let i = 1; i < n - 1; i++) {
|
||||||
|
points.push(topY + i * interval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 맨 아래의 점 추가
|
||||||
|
points.push(bottomY)
|
||||||
|
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTopTwoPoints(points) {
|
||||||
|
points.sort((a, b) => b.y - a.y)
|
||||||
|
|
||||||
|
return points.slice(0, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateForApi = (moduleSurface) => {
|
||||||
|
const centerPoints = []
|
||||||
|
const direction = moduleSurface.direction
|
||||||
|
const modules = moduleSurface.modules
|
||||||
|
|
||||||
|
modules.forEach((module, index) => {
|
||||||
|
module.tempIndex = index
|
||||||
|
const { x, y } = module.getCenterPoint()
|
||||||
|
const { width, height } = module
|
||||||
|
centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index })
|
||||||
|
})
|
||||||
|
|
||||||
|
if (centerPoints.length === 0) return
|
||||||
|
|
||||||
|
//완전 노출 하면
|
||||||
|
let exposedBottom = 0
|
||||||
|
// 반 노출 하면
|
||||||
|
let exposedHalfBottom = 0
|
||||||
|
// 완전 노출 상면
|
||||||
|
let exposedTop = 0
|
||||||
|
//반 노출 상면
|
||||||
|
let exposedHalfTop = 0
|
||||||
|
// 완전 접면
|
||||||
|
let touchDimension = 0
|
||||||
|
//반접면
|
||||||
|
let halfTouchDimension = 0
|
||||||
|
|
||||||
|
// 노출bottom면의 points
|
||||||
|
let exposedBottomPoints = []
|
||||||
|
|
||||||
|
// 반노출 bottom면의 points
|
||||||
|
let leftExposedHalfBottomPoints = []
|
||||||
|
let rightExposedHalfBottomPoints = []
|
||||||
|
|
||||||
|
centerPoints.forEach((centerPoint, index) => {
|
||||||
|
const { x, y, width, height } = centerPoint
|
||||||
|
// centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인
|
||||||
|
let bottomCell
|
||||||
|
let bottomLeftPoint
|
||||||
|
let bottomRightPoint
|
||||||
|
let leftBottomCnt
|
||||||
|
let rightBottomCnt
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case 'south':
|
||||||
|
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2)
|
||||||
|
bottomLeftPoint = { x: x - width / 2, y: y + height }
|
||||||
|
bottomRightPoint = { x: x + width / 2, y: y + height }
|
||||||
|
break
|
||||||
|
case 'north':
|
||||||
|
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2)
|
||||||
|
bottomLeftPoint = { x: x + width / 2, y: y - height }
|
||||||
|
bottomRightPoint = { x: x - width / 2, y: y - height }
|
||||||
|
break
|
||||||
|
case 'east':
|
||||||
|
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
||||||
|
bottomLeftPoint = { x: x + width, y: y + height / 2 }
|
||||||
|
bottomRightPoint = { x: x + width, y: y - height / 2 }
|
||||||
|
break
|
||||||
|
case 'west':
|
||||||
|
bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
||||||
|
bottomLeftPoint = { x: x - width, y: y - height / 2 }
|
||||||
|
bottomRightPoint = { x: x - width, y: y + height / 2 }
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottomCell.length === 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 바로 아래에 셀이 없는 경우 물떼세 배치가 왼쪽 되어있는 셀을 찾는다.
|
||||||
|
leftBottomCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
rightBottomCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
|
||||||
|
if (leftBottomCnt + rightBottomCnt === 1) {
|
||||||
|
exposedHalfBottom++
|
||||||
|
if (leftBottomCnt === 1) {
|
||||||
|
rightExposedHalfBottomPoints.push(centerPoint)
|
||||||
|
}
|
||||||
|
if (rightBottomCnt === 1) {
|
||||||
|
leftExposedHalfBottomPoints.push(centerPoint)
|
||||||
|
}
|
||||||
|
} else if (leftBottomCnt + rightBottomCnt === 0) {
|
||||||
|
exposedBottomPoints.push(centerPoint)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 노출상면 및 접면 체크
|
||||||
|
|
||||||
|
centerPoints.forEach((centerPoint, index) => {
|
||||||
|
const { x, y, width, height } = centerPoint
|
||||||
|
|
||||||
|
let topCell
|
||||||
|
let topLeftPoint
|
||||||
|
let topRightPoint
|
||||||
|
let leftTopCnt
|
||||||
|
let rightTopCnt
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case 'south':
|
||||||
|
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2)
|
||||||
|
topLeftPoint = { x: x - width / 2, y: y - height }
|
||||||
|
topRightPoint = { x: x + width / 2, y: y - height }
|
||||||
|
break
|
||||||
|
case 'north':
|
||||||
|
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2)
|
||||||
|
topLeftPoint = { x: x + width / 2, y: y + height }
|
||||||
|
topRightPoint = { x: x - width / 2, y: y + height }
|
||||||
|
break
|
||||||
|
case 'east':
|
||||||
|
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
||||||
|
topLeftPoint = { x: x - width, y: y + height / 2 }
|
||||||
|
topRightPoint = { x: x - width, y: y - height / 2 }
|
||||||
|
break
|
||||||
|
case 'west':
|
||||||
|
topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2)
|
||||||
|
topLeftPoint = { x: x + width, y: y - height / 2 }
|
||||||
|
topRightPoint = { x: x + width, y: y + height / 2 }
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topCell.length === 1) {
|
||||||
|
touchDimension++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
leftTopCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
rightTopCnt = centerPoints.filter(
|
||||||
|
(centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2,
|
||||||
|
).length
|
||||||
|
|
||||||
|
if (leftTopCnt + rightTopCnt === 2) {
|
||||||
|
touchDimension++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftTopCnt + rightTopCnt === 1) {
|
||||||
|
exposedHalfTop++
|
||||||
|
halfTouchDimension++
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (leftTopCnt + rightTopCnt === 0) {
|
||||||
|
exposedTop++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 완전 노출 하면 계산
|
||||||
|
|
||||||
|
/*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId)
|
||||||
|
const points = cells.map((cell) => {
|
||||||
|
return cell.getCenterPoint()
|
||||||
|
})*/
|
||||||
|
const groupPoints = groupCoordinates(centerPoints, modules[0], direction)
|
||||||
|
|
||||||
|
groupPoints.forEach((group) => {
|
||||||
|
let maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y
|
||||||
|
let minY = group.reduce((acc, cur) => (acc.y < cur.y ? acc : cur)).y
|
||||||
|
let maxX = group.reduce((acc, cur) => (acc.x > cur.x ? acc : cur)).x
|
||||||
|
let minX = group.reduce((acc, cur) => (acc.x < cur.x ? acc : cur)).x
|
||||||
|
|
||||||
|
let maxYCenterPoints = group.filter((centerPoint) => Math.abs(centerPoint.y - maxY) < 2)
|
||||||
|
let minYCenterPoints = group.filter((centerPoint) => Math.abs(centerPoint.y - minY) < 2)
|
||||||
|
let maxXCenterPoints = group.filter((centerPoint) => Math.abs(centerPoint.x - maxX) < 2)
|
||||||
|
let minXCenterPoints = group.filter((centerPoint) => Math.abs(centerPoint.x - minX) < 2)
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case 'south':
|
||||||
|
exposedBottom += maxYCenterPoints.length
|
||||||
|
break
|
||||||
|
case 'north':
|
||||||
|
exposedBottom += minYCenterPoints.length
|
||||||
|
break
|
||||||
|
case 'east':
|
||||||
|
exposedBottom += maxXCenterPoints.length
|
||||||
|
break
|
||||||
|
case 'west':
|
||||||
|
exposedBottom += minXCenterPoints.length
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
exposedBottom,
|
||||||
|
exposedHalfBottom,
|
||||||
|
exposedTop,
|
||||||
|
exposedHalfTop,
|
||||||
|
touchDimension,
|
||||||
|
halfTouchDimension,
|
||||||
|
exposedBottomPoints,
|
||||||
|
leftExposedHalfBottomPoints,
|
||||||
|
rightExposedHalfBottomPoints,
|
||||||
|
centerPoints,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// polygon 내부 cell들의 centerPoint 배열을 그룹화 해서 반환
|
||||||
|
const groupCoordinates = (points, moduleExample, direction) => {
|
||||||
|
const groups = []
|
||||||
|
const visited = new Set()
|
||||||
|
const width = Math.floor(moduleExample.width)
|
||||||
|
const height = Math.floor(moduleExample.height)
|
||||||
|
const horizonPadding = 0 // 가로 패딩
|
||||||
|
const verticalPadding = 0 // 세로 패딩
|
||||||
|
|
||||||
|
function isAdjacent(p1, p2) {
|
||||||
|
const dx = Math.abs(p1.x - p2.x)
|
||||||
|
const dy = Math.abs(p1.y - p2.y)
|
||||||
|
return (
|
||||||
|
(Math.abs(width + horizonPadding - dx) < 2 && dy < 2) ||
|
||||||
|
(dx < 2 && Math.abs(dy - height + verticalPadding)) < 2 ||
|
||||||
|
(Math.abs(dx - width / 2 + horizonPadding / 2) < 2 && Math.abs(dy - height + verticalPadding) < 2)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function dfs(point, group) {
|
||||||
|
visited.add(`${point.x},${point.y}`)
|
||||||
|
group.push(point)
|
||||||
|
|
||||||
|
for (const nextPoint of points) {
|
||||||
|
const key = `${nextPoint.x},${nextPoint.y}`
|
||||||
|
if (!visited.has(key) && isAdjacent(point, nextPoint)) {
|
||||||
|
dfs(nextPoint, group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const point of points) {
|
||||||
|
const key = `${point.x},${point.y}`
|
||||||
|
if (!visited.has(key)) {
|
||||||
|
const group = []
|
||||||
|
dfs(point, group)
|
||||||
|
groups.push(group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups
|
||||||
|
}
|
||||||
|
|
||||||
|
return { apply }
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user