모듈 흡착점 추가

This commit is contained in:
yjnoh 2024-09-30 17:09:31 +09:00
parent 4ee102f1b9
commit 71e3d78c9b

View File

@ -39,6 +39,7 @@ import * as turf from '@turf/turf'
import { INPUT_TYPE, Mode } from '@/common/common' import { INPUT_TYPE, Mode } from '@/common/common'
import { m } from 'framer-motion' import { m } from 'framer-motion'
import { set } from 'react-hook-form' import { set } from 'react-hook-form'
import { FaWineGlassEmpty } from 'react-icons/fa6'
export function useMode() { export function useMode() {
const [mode, setMode] = useRecoilState(modeState) const [mode, setMode] = useRecoilState(modeState)
@ -4941,6 +4942,12 @@ export function useMode() {
) )
} }
const coordToTurfPolygon = (points) => {
const coordinates = points.map((point) => [point.x, point.y])
coordinates.push(coordinates[0])
return turf.polygon([coordinates])
}
/** /**
* trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 진입여부를 확인 * trestle에서 영역을 가져와 mouse:move 이벤트로 해당 영역에 진입했을때 booleanPointInPolygon 진입여부를 확인
* 확인 셀을 이동시킴 * 확인 셀을 이동시킴
@ -4949,58 +4956,125 @@ export function useMode() {
const trestlePolygons = canvas?.getObjects().filter((obj) => obj.name === 'trestle') //가대를 가져옴 const trestlePolygons = canvas?.getObjects().filter((obj) => obj.name === 'trestle') //가대를 가져옴
if (trestlePolygons.length !== 0) { if (trestlePolygons.length !== 0) {
let lastPointPosition = { x: 0, y: 0 }
let fabricPolygon = null let fabricPolygon = null
let inside = false let inside = false
let turfPolygon let turfPolygon
let manualDrawCells = drewRoofCells // let manualDrawCells = drewRoofCells // 앞에서 자동으로 했을때 추가됨
let direction
canvas.on('mouse:move', (e) => { canvas.on('mouse:move', (e) => {
//마우스 이벤트 삭제 후 재추가 //마우스 이벤트 삭제 후 재추가
const mousePoint = canvas.getPointer(e.e) const mousePoint = canvas.getPointer(e.e)
const turfPoint = turf.point([mousePoint.x, mousePoint.y])
for (let i = 0; i < trestlePolygons.length; i++) { for (let i = 0; i < trestlePolygons.length; i++) {
turfPolygon = polygonToTurfPolygon(trestlePolygons[i]) turfPolygon = polygonToTurfPolygon(trestlePolygons[i])
if (turf.booleanPointInPolygon(turfPoint, turfPolygon)) { direction = trestlePolygons[i].direction //도형의 방향
let width = direction === 'south' || direction === 'north' ? 172 : 113
let height = direction === 'south' || direction === 'north' ? 113 : 172
const points = [
{ x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 },
{ x: mousePoint.x + width / 2, y: mousePoint.y - height / 2 },
{ x: mousePoint.x + width / 2, y: mousePoint.y + height / 2 },
{ x: mousePoint.x - width / 2, y: mousePoint.y + height / 2 },
]
const turfPoints = coordToTurfPolygon(points)
if (turf.booleanWithin(turfPoints, turfPolygon)) {
//turf에 보면 폴리곤안에 포인트가 있는지 함수가 있다 //turf에 보면 폴리곤안에 포인트가 있는지 함수가 있다
const direction = trestlePolygons[i].direction //도형의 방향
let width = direction === 'south' || direction === 'north' ? 172.2 : 113.4
let height = direction === 'south' || direction === 'north' ? 113.4 : 172.2
if (Math.abs(mousePoint.x - lastPointPosition.x) >= 5 || Math.abs(mousePoint.y - lastPointPosition.y) >= 5) {
let isDrawing = false
if (isDrawing) return // if (Math.abs(mousePoint.x - lastPointPosition.x) >= 5 || Math.abs(mousePoint.y - lastPointPosition.y) >= 5) {
canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tmpCell')) //움직일때 일단 지워가면서 움직임 let isDrawing = false
const points = [ if (isDrawing) return
{ x: mousePoint.x - width / 2, y: mousePoint.y - height / 2 }, canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === 'tmpCell')) //움직일때 일단 지워가면서 움직임
{ x: mousePoint.x + width / 2, y: mousePoint.y - height / 2 },
{ x: mousePoint.x + width / 2, y: mousePoint.y + height / 2 },
{ x: mousePoint.x - width / 2, y: mousePoint.y + height / 2 },
]
fabricPolygon = new QPolygon(points, { fabricPolygon = new QPolygon(points, {
fill: '#BFFD9F', fill: '#BFFD9F',
stroke: 'black', // stroke: 'black',
selectable: false, // 선택 가능하게 설정 // strokeWidth: 1,
lockMovementX: true, // X 축 이동 잠금 selectable: false, // 선택 가능하게 설정
lockMovementY: true, // Y 축 이동 잠금 lockMovementX: true, // X 축 이동 잠금
lockRotation: true, // 회전 잠금 lockMovementY: true, // Y 축 이동 잠금
lockScalingX: true, // X 축 크기 조정 잠금 lockRotation: true, // 회전 잠금
lockScalingY: true, // Y 축 크기 조정 잠금 lockScalingX: true, // X 축 크기 조정 잠금
opacity: 0.8, lockScalingY: true, // Y 축 크기 조정 잠금
parentId: trestlePolygons[i].parentId, opacity: 0.8,
name: 'tmpCell', parentId: trestlePolygons[i].parentId,
}) name: 'tmpCell',
})
canvas?.add(fabricPolygon) //움직여가면서 추가됨 canvas?.add(fabricPolygon) //움직여가면서 추가됨
lastPointPosition = { x: mousePoint.x, y: mousePoint.y }
/**
* 스냅기능
*/
let snapDistance = 20
const bigLeft = trestlePolygons[i].left
const bigTop = trestlePolygons[i].top
const bigRight = bigLeft + trestlePolygons[i].width * trestlePolygons[i].scaleX
const bigBottom = bigTop + trestlePolygons[i].height * trestlePolygons[i].scaleY
const bigCenter = (bigTop + bigTop + trestlePolygons[i].height) / 2
// 작은 폴리곤의 경계 좌표 계산
const smallLeft = fabricPolygon.left
const smallTop = fabricPolygon.top
const smallRight = smallLeft + fabricPolygon.width * fabricPolygon.scaleX
const smallBottom = smallTop + fabricPolygon.height * fabricPolygon.scaleY
const smallCenter = smallLeft + (fabricPolygon.width * fabricPolygon.scaleX) / 2
// 위쪽 변에 스냅
if (Math.abs(smallTop - bigTop) < snapDistance) {
fabricPolygon.top = bigTop
} }
// 아래쪽 변에 스냅
if (Math.abs(smallTop + fabricPolygon.height * fabricPolygon.scaleY - (bigTop + trestlePolygons[i].height)) < snapDistance) {
fabricPolygon.top = bigTop + trestlePolygons[i].height - fabricPolygon.height * fabricPolygon.scaleY
}
// 왼쪽변에 스냅
if (Math.abs(smallLeft - bigLeft) < snapDistance) {
fabricPolygon.left = bigLeft
}
//오른쪽 변에 스냅
if (Math.abs(smallRight - bigRight) < snapDistance) {
fabricPolygon.left = bigRight - fabricPolygon.width * fabricPolygon.scaleX
}
if (direction === 'south' || direction === 'north') {
// 모듈왼쪽이 세로중앙선에 붙게 스냅
if (Math.abs(smallLeft - (bigLeft + trestlePolygons[i].width / 2)) < snapDistance) {
fabricPolygon.left = bigLeft + trestlePolygons[i].width / 2
}
// 모듈이 가운데가 세로중앙선에 붙게 스냅
if (Math.abs(smallCenter - (bigLeft + trestlePolygons[i].width / 2)) < snapDistance) {
fabricPolygon.left = bigLeft + trestlePolygons[i].width / 2 - (fabricPolygon.width * fabricPolygon.scaleX) / 2
}
// 모듈오른쪽이 세로중앙선에 붙게 스냅
if (Math.abs(smallRight - (bigLeft + trestlePolygons[i].width / 2)) < snapDistance) {
fabricPolygon.left = bigLeft + trestlePolygons[i].width / 2 - fabricPolygon.width * fabricPolygon.scaleX
}
} else {
// 모듈이 가로중앙선에 스냅
if (Math.abs(smallTop + fabricPolygon.height / 2 - bigCenter) < snapDistance) {
fabricPolygon.top = bigCenter - fabricPolygon.height / 2
}
if (Math.abs(smallTop - (bigTop + trestlePolygons[i].height / 2)) < snapDistance) {
fabricPolygon.top = bigTop + trestlePolygons[i].height / 2
}
// 모듈 밑면이 가로중앙선에 스냅
if (Math.abs(smallBottom - (bigTop + trestlePolygons[i].height / 2)) < snapDistance) {
fabricPolygon.top = bigTop + trestlePolygons[i].height / 2 - fabricPolygon.height * fabricPolygon.scaleY
}
}
fabricPolygon.setCoords()
canvas?.renderAll() canvas?.renderAll()
inside = true inside = true
break
} else { } else {
inside = false inside = false
} }
@ -5016,20 +5090,26 @@ export function useMode() {
if (!inside) return if (!inside) return
if (fabricPolygon) { if (fabricPolygon) {
const turfCellPolygon = polygonToTurfPolygon(fabricPolygon) const turfCellPolygon = polygonToTurfPolygon(fabricPolygon)
fabricPolygon.setCoords() //좌표 재정렬
if (turf.booleanWithin(turfCellPolygon, turfPolygon)) { if (turf.booleanWithin(turfCellPolygon, turfPolygon)) {
//마우스 클릭시 set으로 해당 위치에 셀을 넣음 //마우스 클릭시 set으로 해당 위치에 셀을 넣음
manualDrawCells.forEach((cell) => {
console.log('cells', cell.points)
})
console.log('turfCellPolygon', turfCellPolygon.geometry.coordinates)
const isOverlap = manualDrawCells.some((cell) => turf.booleanOverlap(turfCellPolygon, polygonToTurfPolygon(cell))) const isOverlap = manualDrawCells.some((cell) => turf.booleanOverlap(turfCellPolygon, polygonToTurfPolygon(cell)))
if (!isOverlap) { if (!isOverlap) {
//안겹치면 넣는다 //안겹치면 넣는다
fabricPolygon.set({ name: 'cell' })
fabricPolygon.setCoords() fabricPolygon.setCoords()
fabricPolygon.set({ name: 'cell' })
manualDrawCells.push(fabricPolygon) manualDrawCells.push(fabricPolygon)
} else { } else {
alert('셀끼리 겹치면 안되죠?') alert('셀끼리 겹치면 안되죠?')
} }
} else { // } else {
alert('나갔으요!!') // alert('나갔으요!!')
} }
setDrewRoofCells(manualDrawCells) setDrewRoofCells(manualDrawCells)
} }
@ -5106,27 +5186,6 @@ export function useMode() {
// console.log('bbox', bbox) // console.log('bbox', bbox)
const boxes = []
const installedCellsArray = []
for (let x = bbox[0]; x < bbox[2]; x += width) {
for (let y = bbox[1]; y < bbox[3]; y += height) {
const box = turf.polygon([
[
[x, y],
[x + width, y],
[x + width, y + height],
[x, y + height],
[x, y],
],
])
if (turf.booleanWithin(box, turfTrestlePolygon)) {
boxes.push(box)
}
}
}
for (let col = 0; col <= cols; col++) { for (let col = 0; col <= cols; col++) {
for (let row = 0; row <= rows; row++) { for (let row = 0; row <= rows; row++) {
let x = 0, let x = 0,
@ -5176,20 +5235,6 @@ export function useMode() {
const squarePolygon = turf.polygon([square]) const squarePolygon = turf.polygon([square])
// console.log('turfTrestlePolygon', turfTrestlePolygon)
// console.log('squarePolygon', squarePolygon)
const areaSize = turf.area(turfTrestlePolygon)
// console.log('areaSize', areaSize)
const objSize = turf.area(squarePolygon)
// console.log('objSize', objSize)
const maxObject = Math.floor(areaSize / objSize)
// console.log('maxObjectSize', maxObject)
const disjointFromTrestle = turf.booleanContains(turfTrestlePolygon, squarePolygon) || turf.booleanWithin(squarePolygon, turfTrestlePolygon) const disjointFromTrestle = turf.booleanContains(turfTrestlePolygon, squarePolygon) || turf.booleanWithin(squarePolygon, turfTrestlePolygon)
if (disjointFromTrestle) { if (disjointFromTrestle) {
@ -5230,6 +5275,8 @@ export function useMode() {
lockScalingY: true, // Y 축 크기 조정 잠금 lockScalingY: true, // Y 축 크기 조정 잠금
opacity: 0.8, opacity: 0.8,
parentId: trestle.parentId, parentId: trestle.parentId,
lineCol: col,
lineRow: row,
}) })
canvas?.add(fabricPolygon) canvas?.add(fabricPolygon)
drawCellsArray.push(fabricPolygon) drawCellsArray.push(fabricPolygon)