polygon name 수정, 지붕 나누기 수정
This commit is contained in:
parent
da26628f69
commit
0adfe0916c
@ -225,9 +225,9 @@ export function useCanvasSetting() {
|
||||
const option1 = settingModalFirstOptions.option1
|
||||
|
||||
// 'allocDisplay' 할당 표시
|
||||
// 'outlineDisplay' 외벽선 표시 'outerLine', 'wallLine'
|
||||
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
||||
// 'lineDisplay' 지붕선 표시 'roof', 'roofBase'
|
||||
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
||||
// 'wordDisplay' 문자 표시
|
||||
// 'circuitNumDisplay' 회로번호 표시
|
||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
||||
@ -244,13 +244,13 @@ export function useCanvasSetting() {
|
||||
optionName = ['1']
|
||||
break
|
||||
case 'outlineDisplay': //외벽선 표시
|
||||
optionName = ['outerLine', 'wallLine']
|
||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||
break
|
||||
case 'gridDisplay': //그리드 표시
|
||||
optionName = ['lindGrid', 'dotGrid']
|
||||
break
|
||||
case 'lineDisplay': //지붕선 표시
|
||||
optionName = ['roof', 'roofBase']
|
||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||
break
|
||||
case 'wordDisplay': //문자 표시
|
||||
optionName = ['6']
|
||||
|
||||
@ -12,9 +12,9 @@ export function useFirstOption() {
|
||||
const option1 = settingModalFirstOptions.option1
|
||||
|
||||
// 'allocDisplay' 할당 표시
|
||||
// 'outlineDisplay' 외벽선 표시 'outerLine', 'wallLine'
|
||||
// 'outlineDisplay' 외벽선 표시 'outerLine', POLYGON_TYPE.WALL
|
||||
// 'gridDisplay' 그리드 표시 'lindGrid', 'dotGrid'
|
||||
// 'lineDisplay' 지붕선 표시 'roof', 'roofBase'
|
||||
// 'lineDisplay' 지붕선 표시 'roof', POLYGON_TYPE.ROOF
|
||||
// 'wordDisplay' 문자 표시
|
||||
// 'circuitNumDisplay' 회로번호 표시
|
||||
// 'flowDisplay' 흐름방향 표시 'arrow'
|
||||
@ -30,13 +30,13 @@ export function useFirstOption() {
|
||||
optionName = ['1']
|
||||
break
|
||||
case 'outlineDisplay': //외벽선 표시
|
||||
optionName = ['outerLine', 'wallLine']
|
||||
optionName = ['outerLine', POLYGON_TYPE.WALL]
|
||||
break
|
||||
case 'gridDisplay': //그리드 표시
|
||||
optionName = ['lineGrid', 'dotGrid', 'adsorptionPoint', 'tempGrid']
|
||||
break
|
||||
case 'lineDisplay': //지붕선 표시
|
||||
optionName = ['roof', 'roofBase']
|
||||
optionName = ['roof', POLYGON_TYPE.ROOF]
|
||||
break
|
||||
case 'wordDisplay': //문자 표시
|
||||
optionName = ['6']
|
||||
|
||||
@ -15,7 +15,7 @@ import {
|
||||
outerLineLength2State,
|
||||
outerLineTypeState,
|
||||
} from '@/store/outerLineAtom'
|
||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, isPointOnLine, polygonToTurfPolygon } from '@/util/canvas-util'
|
||||
import { fabric } from 'fabric'
|
||||
import { useAdsorptionPoint } from '@/hooks/useAdsorptionPoint'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
@ -23,6 +23,7 @@ import { booleanPointInPolygon } from '@turf/turf'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { calculateAngle } from '@/util/qpolygon-utils'
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
|
||||
// 보조선 작성
|
||||
export function useAuxiliaryDrawing(id) {
|
||||
@ -80,7 +81,7 @@ export function useAuxiliaryDrawing(id) {
|
||||
|
||||
useEffect(() => {
|
||||
// innerLines가 있을경우 삭제
|
||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
if (roofs.length === 0) {
|
||||
swalFire({ text: '지붕형상이 없습니다.' })
|
||||
closePopup(id)
|
||||
@ -561,7 +562,7 @@ export function useAuxiliaryDrawing(id) {
|
||||
return
|
||||
}
|
||||
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
/*const allLines = [...auxiliaryLines]
|
||||
|
||||
roofBases.forEach((roofBase) => {
|
||||
@ -611,6 +612,7 @@ export function useAuxiliaryDrawing(id) {
|
||||
},
|
||||
)
|
||||
lineHistory.current.push(newLine)
|
||||
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
|
||||
removeLine(line1)
|
||||
intersectionPoints.current.push(...interSectionPointsWithRoofLines)
|
||||
return
|
||||
@ -659,6 +661,7 @@ export function useAuxiliaryDrawing(id) {
|
||||
})
|
||||
}
|
||||
lineHistory.current.push(newLine)
|
||||
lineHistory.current = lineHistory.current.filter((history) => history !== line1)
|
||||
removeLine(line1)
|
||||
})
|
||||
|
||||
@ -742,7 +745,7 @@ export function useAuxiliaryDrawing(id) {
|
||||
return
|
||||
}
|
||||
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
|
||||
//lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거
|
||||
// 겹치는 선 하나는 canvas에서 제거한다.
|
||||
@ -772,9 +775,13 @@ export function useAuxiliaryDrawing(id) {
|
||||
})
|
||||
const roofInnerLines = innerLines.filter((line) => {
|
||||
const inPolygon1 =
|
||||
tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) || roofBase.inPolygon({ x: line.x1, y: line.y1 })
|
||||
tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) ||
|
||||
roofBase.inPolygon({ x: line.x1, y: line.y1 }) ||
|
||||
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x1, y: line.y1 }))
|
||||
const inPolygon2 =
|
||||
tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) || roofBase.inPolygon({ x: line.x2, y: line.y2 })
|
||||
tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) ||
|
||||
roofBase.inPolygon({ x: line.x2, y: line.y2 }) ||
|
||||
roofBase.lines.some((line) => isPointOnLine(line, { x: line.x2, y: line.y2 }))
|
||||
|
||||
if (inPolygon1 && inPolygon2) {
|
||||
line.attributes = { ...line.attributes, roofId: roofBase.id }
|
||||
|
||||
@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil'
|
||||
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { useLine } from '@/hooks/useLine'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
import { outerLineFixState } from '@/store/outerLineAtom'
|
||||
@ -54,7 +54,7 @@ export function useEavesGableEdit(id) {
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
wallLines.forEach((wallLine) => {
|
||||
convertPolygonToLines(wallLine)
|
||||
})
|
||||
@ -160,7 +160,7 @@ export function useEavesGableEdit(id) {
|
||||
attributes,
|
||||
})
|
||||
|
||||
const roofBases = canvas?.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
|
||||
roofBases.forEach((roof) => {
|
||||
roof.innerLines.forEach((line) => {
|
||||
@ -169,7 +169,7 @@ export function useEavesGableEdit(id) {
|
||||
canvas.remove(roof)
|
||||
})
|
||||
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
||||
removeTargets.forEach((obj) => {
|
||||
canvas.remove(obj)
|
||||
|
||||
@ -4,6 +4,7 @@ import { usePopup } from '@/hooks/usePopup'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
|
||||
//동선이동 형 올림 내림
|
||||
export function useMovementSetting(id) {
|
||||
@ -41,7 +42,7 @@ export function useMovementSetting(id) {
|
||||
}, [type])
|
||||
|
||||
useEffect(() => {
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') // 기존 wallLine의 visible false
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) // 기존 wallLine의 visible false
|
||||
wallLines.forEach((line) => {
|
||||
line.set({ visible: false })
|
||||
})
|
||||
@ -55,7 +56,7 @@ export function useMovementSetting(id) {
|
||||
addCanvasMouseEventListener('mouse:move', mouseMoveEvent)
|
||||
return () => {
|
||||
initEvent()
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
wallLines.forEach((line) => {
|
||||
line.set({ visible: true })
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil'
|
||||
import { canvasState, currentObjectState } from '@/store/canvasAtom'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
@ -135,7 +135,7 @@ export function usePropertiesSetting(id) {
|
||||
hideLine(line)
|
||||
})
|
||||
|
||||
const wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
const wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
|
||||
wall.lines = [...lines]
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ import { useSwal } from '@/hooks/useSwal'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { roofDisplaySelector } from '@/store/settingAtom'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
import { POLYGON_TYPE } from '@/common/common'
|
||||
|
||||
// 지붕면 할당
|
||||
export function useRoofAllocationSetting(id) {
|
||||
@ -81,12 +82,12 @@ export function useRoofAllocationSetting(id) {
|
||||
const [selectedRoofMaterial, setSelectedRoofMaterial] = useState(roofMaterials[0])
|
||||
|
||||
useEffect(() => {
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
if (roofBases.length === 0) {
|
||||
swalFire({ text: '할당할 지붕이 없습니다.' })
|
||||
closePopup(id)
|
||||
}
|
||||
// if (type === 'roofBase') {
|
||||
// if (type === POLYGON_TYPE.ROOF) {
|
||||
// // 지붕면 할당
|
||||
//
|
||||
// } else if ('roof') {
|
||||
@ -104,8 +105,8 @@ export function useRoofAllocationSetting(id) {
|
||||
|
||||
// 선택한 지붕재로 할당
|
||||
const handleSave = () => {
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
roofBases.forEach((roofBase) => {
|
||||
try {
|
||||
splitPolygonWithLines(roofBase)
|
||||
@ -117,7 +118,7 @@ export function useRoofAllocationSetting(id) {
|
||||
canvas.remove(line)
|
||||
})
|
||||
|
||||
canvas.remove(roofBase)
|
||||
// canvas.remove(roofBase)
|
||||
})
|
||||
|
||||
wallLines.forEach((wallLine) => {
|
||||
|
||||
@ -4,7 +4,7 @@ import { useEffect, useRef, useState } from 'react'
|
||||
import { useLine } from '@/hooks/useLine'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEvent } from '@/hooks/useEvent'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { outerLineFixState } from '@/store/outerLineAtom'
|
||||
@ -60,7 +60,7 @@ export function useRoofShapePassivitySetting(id) {
|
||||
useEffect(() => {
|
||||
if (!isLoading) return
|
||||
addCanvasMouseEventListener('mouse:down', mouseDown)
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine')
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
|
||||
canvas?.remove(...wallLines)
|
||||
|
||||
@ -185,7 +185,7 @@ export function useRoofShapePassivitySetting(id) {
|
||||
}
|
||||
|
||||
const handleLineToPolygon = () => {
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === 'roofBase')
|
||||
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
|
||||
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
exceptObjs.forEach((obj) => {
|
||||
@ -199,10 +199,10 @@ export function useRoofShapePassivitySetting(id) {
|
||||
let wall
|
||||
|
||||
if (isFix.current) {
|
||||
wall = addPolygonByLines(lines, { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
} else {
|
||||
// 그냥 닫을 경우 처리
|
||||
wall = addPolygonByLines([...initLines.current], { name: 'wallLine', fill: 'transparent', stroke: 'black' })
|
||||
wall = addPolygonByLines([...initLines.current], { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
||||
lines.forEach((line, idx) => {
|
||||
line.attributes = initLines.current[idx].attributes
|
||||
})
|
||||
|
||||
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
||||
import { LINE_TYPE } from '@/common/common'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import { usePolygon } from '@/hooks/usePolygon'
|
||||
import { useMode } from '@/hooks/useMode'
|
||||
import { useLine } from '@/hooks/useLine'
|
||||
@ -129,7 +129,7 @@ export function useRoofShapeSetting(id) {
|
||||
|
||||
useEffect(() => {
|
||||
if (shapeNum === 4) {
|
||||
canvas?.remove(canvas.getObjects().find((obj) => obj.name === 'wallLine'))
|
||||
canvas?.remove(canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL))
|
||||
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
||||
outerLines.forEach((line) => {
|
||||
showLine(line)
|
||||
@ -376,20 +376,20 @@ export function useRoofShapeSetting(id) {
|
||||
// 기존 wallLine, roofBase 제거
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === 'wallLine')
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
.forEach((line) => {
|
||||
canvas.remove(line)
|
||||
})
|
||||
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === 'roofBase')
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
||||
.forEach((obj) => {
|
||||
canvas.remove(...obj.innerLines)
|
||||
canvas.remove(obj)
|
||||
})
|
||||
|
||||
const polygon = addPolygonByLines(outerLines, { name: 'wallLine' })
|
||||
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL })
|
||||
polygon.lines = [...outerLines]
|
||||
|
||||
addPitchTextsByOuterLines()
|
||||
|
||||
@ -5,7 +5,7 @@ export const settingModalFirstOptionsState = atom({
|
||||
default: {
|
||||
option1: [
|
||||
{ id: 1, column: 'allocDisplay', name: 'modal.canvas.setting.first.option.alloc', selected: false },
|
||||
{ id: 2, column: 'outlineDisplay', name: 'modal.canvas.setting.first.option.outline', selected: false },
|
||||
{ id: 2, column: 'outlineDisplay', name: 'modal.canvas.setting.first.option.outline', selected: true },
|
||||
{ id: 3, column: 'gridDisplay', name: 'modal.canvas.setting.first.option.grid', selected: false },
|
||||
{ id: 4, column: 'lineDisplay', name: 'modal.canvas.setting.first.option.roof.line', selected: false },
|
||||
{ id: 5, column: 'wordDisplay', name: 'modal.canvas.setting.first.option.word', selected: false },
|
||||
|
||||
@ -521,9 +521,11 @@ export function isPointOnLine(line, point) {
|
||||
const a = line.y2 - line.y1
|
||||
const b = line.x1 - line.x2
|
||||
const c = line.x2 * line.y1 - line.x1 * line.y2
|
||||
return a * point.x + b * point.y + c === 0
|
||||
}
|
||||
const result = Math.abs(a * point.x + b * point.y + c) / 100
|
||||
|
||||
// 점이 선 위에 있는지 확인
|
||||
return result <= 10
|
||||
}
|
||||
/**
|
||||
* 점과 가까운 line 찾기
|
||||
* @param point
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
import { fabric } from 'fabric'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, getDegreeByChon, getDirectionByPoint } from '@/util/canvas-util'
|
||||
import {
|
||||
calculateIntersection,
|
||||
distanceBetweenPoints,
|
||||
findClosestPoint,
|
||||
getDegreeByChon,
|
||||
getDirectionByPoint,
|
||||
isPointOnLine,
|
||||
} from '@/util/canvas-util'
|
||||
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import * as turf from '@turf/turf'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
@ -957,10 +965,13 @@ export default function offsetPolygon(vertices, offset) {
|
||||
}
|
||||
}
|
||||
|
||||
export const splitPolygonWithLines = (polygon) => {
|
||||
/*export const splitPolygonWithLines = (polygon) => {
|
||||
const roofs = []
|
||||
const allLines = [...polygon.innerLines]
|
||||
|
||||
const polygonLines = polygon.lines
|
||||
const innerLines = polygon.innerLines
|
||||
|
||||
allLines.forEach((line) => {
|
||||
line.startPoint = { x: line.x1, y: line.y1 }
|
||||
line.endPoint = { x: line.x2, y: line.y2 }
|
||||
@ -983,10 +994,10 @@ export const splitPolygonWithLines = (polygon) => {
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
/!**
|
||||
* 좌표 테스트용
|
||||
*/
|
||||
/*allLines.forEach((line) => {
|
||||
*!/
|
||||
/!*allLines.forEach((line) => {
|
||||
const text = new fabric.Text(`(${line.startPoint.x},${line.startPoint.y})`, {
|
||||
left: line.startPoint.x,
|
||||
top: line.startPoint.y,
|
||||
@ -1015,10 +1026,10 @@ export const splitPolygonWithLines = (polygon) => {
|
||||
|
||||
polygon.canvas.add(text)
|
||||
polygon.canvas.renderAll()
|
||||
})*/
|
||||
/**
|
||||
})*!/
|
||||
/!**
|
||||
* 좌표 테스트용 끝
|
||||
*/
|
||||
*!/
|
||||
|
||||
polygon.points.forEach((point, index) => {
|
||||
allLines.forEach((line) => {
|
||||
@ -1164,6 +1175,233 @@ export const splitPolygonWithLines = (polygon) => {
|
||||
polygon.canvas.add(roof)
|
||||
polygon.canvas.renderAll()
|
||||
})
|
||||
}*/
|
||||
export const splitPolygonWithLines = (polygon) => {
|
||||
const canvas = polygon.canvas
|
||||
polygon.set({ visible: false })
|
||||
let innerLines = [...polygon.innerLines]
|
||||
let polygonLines = [...polygon.lines]
|
||||
const roofs = []
|
||||
|
||||
let delIndexs = []
|
||||
let newLines = []
|
||||
|
||||
polygonLines.forEach((line, index) => {
|
||||
line.tempIndex = index
|
||||
innerLines.forEach((innerLine) => {
|
||||
let newLine1, newLine2
|
||||
if (isPointOnLine(line, innerLine.startPoint)) {
|
||||
// 해당 line을 startPoint로 나눈 line2개를 canvas에 추가 하고 기존 line을 제거한다.
|
||||
newLine1 = new QLine([line.x1, line.y1, innerLine.startPoint.x, innerLine.startPoint.y], {
|
||||
fontSize: polygon.fontSize,
|
||||
stroke: 'black',
|
||||
strokeWidth: 3,
|
||||
})
|
||||
|
||||
newLine2 = new QLine([innerLine.startPoint.x, innerLine.startPoint.y, line.x2, line.y2], {
|
||||
fontSize: polygon.fontSize,
|
||||
stroke: 'black',
|
||||
strokeWidth: 3,
|
||||
})
|
||||
delIndexs.push(polygonLines.indexOf(line))
|
||||
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
||||
if (newLine1.length / 10 > 10) {
|
||||
newLines.push(newLine1)
|
||||
}
|
||||
if (newLine2.length / 10 > 10) {
|
||||
newLines.push(newLine2)
|
||||
}
|
||||
}
|
||||
if (isPointOnLine(line, innerLine.endPoint)) {
|
||||
newLine1 = new QLine([line.x1, line.y1, innerLine.endPoint.x, innerLine.endPoint.y], {
|
||||
fontSize: polygon.fontSize,
|
||||
stroke: 'black',
|
||||
strokeWidth: 3,
|
||||
})
|
||||
|
||||
newLine2 = new QLine([innerLine.endPoint.x, innerLine.endPoint.y, line.x2, line.y2], {
|
||||
fontSize: polygon.fontSize,
|
||||
stroke: 'black',
|
||||
strokeWidth: 3,
|
||||
})
|
||||
delIndexs.push(polygonLines.indexOf(line))
|
||||
canvas.remove(polygonLines[polygonLines.indexOf(line)])
|
||||
if (newLine1.length / 10 > 10) {
|
||||
newLines.push(newLine1)
|
||||
}
|
||||
if (newLine2.length / 10 > 10) {
|
||||
newLines.push(newLine2)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
polygonLines = polygonLines.filter((line) => !delIndexs.includes(line.tempIndex))
|
||||
polygonLines = [...polygonLines, ...newLines]
|
||||
|
||||
const allLines = [...polygonLines, ...innerLines]
|
||||
|
||||
/**
|
||||
* 왼쪽 상단을 startPoint로 전부 변경
|
||||
*/
|
||||
allLines.forEach((line) => {
|
||||
let startPoint // 시작점
|
||||
let endPoint // 끝점
|
||||
if (line.x1 < line.x2) {
|
||||
startPoint = { x: line.x1, y: line.y1 }
|
||||
endPoint = { x: line.x2, y: line.y2 }
|
||||
} else if (line.x1 > line.x2) {
|
||||
startPoint = { x: line.x2, y: line.y2 }
|
||||
endPoint = { x: line.x1, y: line.y1 }
|
||||
} else {
|
||||
if (line.y1 < line.y2) {
|
||||
startPoint = { x: line.x1, y: line.y1 }
|
||||
endPoint = { x: line.x2, y: line.y2 }
|
||||
} else {
|
||||
startPoint = { x: line.x2, y: line.y2 }
|
||||
endPoint = { x: line.x1, y: line.y1 }
|
||||
}
|
||||
}
|
||||
|
||||
line.startPoint = startPoint
|
||||
line.endPoint = endPoint
|
||||
})
|
||||
|
||||
polygonLines.forEach((line) => {
|
||||
const startPoint = line.startPoint // 시작점
|
||||
let arrivalPoint = line.endPoint // 도착점
|
||||
|
||||
let currentPoint = startPoint
|
||||
const roofPoints = [startPoint]
|
||||
|
||||
const startLine = line
|
||||
const visitPoints = [startPoint]
|
||||
const visitLines = [startLine]
|
||||
let cnt = 0
|
||||
|
||||
while (!isSamePoint(currentPoint, arrivalPoint)) {
|
||||
line.set({ stroke: 'red' })
|
||||
canvas.renderAll()
|
||||
let nextLines = allLines.filter(
|
||||
(line2) =>
|
||||
(isSamePoint(line2.startPoint, currentPoint) || isSamePoint(line2.endPoint, currentPoint)) &&
|
||||
line !== line2 &&
|
||||
innerLines.includes(line2) &&
|
||||
!visitLines.includes(line2),
|
||||
)
|
||||
|
||||
if (nextLines.length === 0) {
|
||||
nextLines = allLines.filter(
|
||||
(line2) =>
|
||||
(isSamePoint(line2.startPoint, currentPoint) || isSamePoint(line2.endPoint, currentPoint)) &&
|
||||
line !== line2 &&
|
||||
!visitLines.includes(line2),
|
||||
)
|
||||
}
|
||||
|
||||
if (!nextLines) {
|
||||
break
|
||||
}
|
||||
|
||||
let comparisonPoints = []
|
||||
|
||||
nextLines.forEach((nextLine) => {
|
||||
if (isSamePoint(nextLine.startPoint, currentPoint)) {
|
||||
comparisonPoints.push(nextLine.endPoint)
|
||||
} else {
|
||||
comparisonPoints.push(nextLine.startPoint)
|
||||
}
|
||||
})
|
||||
|
||||
comparisonPoints = comparisonPoints.filter((point) => !visitPoints.some((visitPoint) => isSamePoint(visitPoint, point)))
|
||||
comparisonPoints = comparisonPoints.filter((point) => !isSamePoint(point, currentPoint))
|
||||
|
||||
const minDistancePoint = comparisonPoints.reduce((prev, current) => {
|
||||
const prevDistance = Math.sqrt(Math.pow(prev.x - arrivalPoint.x, 2) + Math.pow(prev.y - arrivalPoint.y, 2))
|
||||
const currentDistance = Math.sqrt(Math.pow(current.x - arrivalPoint.x, 2) + Math.pow(current.y - arrivalPoint.y, 2))
|
||||
|
||||
return prevDistance < currentDistance ? prev : current
|
||||
}, comparisonPoints[0])
|
||||
|
||||
nextLines.forEach((nextLine) => {
|
||||
if (isSamePoint(nextLine.startPoint, minDistancePoint) || isSamePoint(nextLine.endPoint, minDistancePoint)) {
|
||||
visitLines.push(nextLine)
|
||||
}
|
||||
})
|
||||
|
||||
currentPoint = { ...minDistancePoint }
|
||||
roofPoints.push(currentPoint)
|
||||
cnt++
|
||||
if (cnt > 100) {
|
||||
throw new Error('무한루프')
|
||||
}
|
||||
}
|
||||
roofs.push(roofPoints)
|
||||
})
|
||||
|
||||
const newRoofs = removeDuplicatePolygons(roofs)
|
||||
console.log(newRoofs)
|
||||
newRoofs.forEach((roofPoint, index) => {
|
||||
let defense, pitch
|
||||
const direction = getDirectionByPoint(roofPoint[0], roofPoint[roofPoint.length - 1])
|
||||
|
||||
switch (direction) {
|
||||
case 'top':
|
||||
defense = 'east'
|
||||
break
|
||||
case 'right':
|
||||
defense = 'south'
|
||||
break
|
||||
case 'bottom':
|
||||
defense = 'west'
|
||||
break
|
||||
case 'left':
|
||||
defense = 'north'
|
||||
break
|
||||
}
|
||||
pitch = polygon.lines[index].attributes?.pitch ?? 0
|
||||
|
||||
const roof = new QPolygon(roofPoint, {
|
||||
fontSize: polygon.fontSize,
|
||||
stroke: 'black',
|
||||
fill: 'transparent',
|
||||
strokeWidth: 3,
|
||||
name: POLYGON_TYPE.ROOF,
|
||||
originX: 'center',
|
||||
originY: 'center',
|
||||
selectable: true,
|
||||
defense: defense,
|
||||
direction: defense,
|
||||
pitch: pitch,
|
||||
})
|
||||
|
||||
polygon.canvas.add(roof)
|
||||
canvas.remove(polygon)
|
||||
polygon.canvas.renderAll()
|
||||
})
|
||||
}
|
||||
|
||||
const removeDuplicatePolygons = (polygons) => {
|
||||
const uniquePolygons = []
|
||||
|
||||
polygons.forEach((polygon) => {
|
||||
const sortedPolygon = polygon
|
||||
.map((point) => `${Math.floor(point.x)},${Math.floor(point.y)}`)
|
||||
.sort()
|
||||
.join('|')
|
||||
const isDuplicate = uniquePolygons.some((uniquePolygon) => {
|
||||
const sortedUniquePolygon = uniquePolygon
|
||||
.map((point) => `${Math.floor(point.x)},${Math.floor(point.y)}`)
|
||||
.sort()
|
||||
.join('|')
|
||||
return sortedPolygon === sortedUniquePolygon
|
||||
})
|
||||
|
||||
if (!isDuplicate) {
|
||||
uniquePolygons.push(polygon)
|
||||
}
|
||||
})
|
||||
|
||||
return uniquePolygons
|
||||
}
|
||||
|
||||
const isSamePoint = (a, b) => {
|
||||
@ -1218,6 +1456,7 @@ export const drawRidgeRoof = (roofId, canvas) => {
|
||||
* @param canvas
|
||||
*/
|
||||
const drawRidge = (roof, canvas) => {
|
||||
debugger
|
||||
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines // 외벽의 라인
|
||||
const roofLines = roof.lines // 지붕의 라인
|
||||
let ridgeRoof = []
|
||||
@ -3312,7 +3551,7 @@ function createRoofPaddingPolygon(polygon, lines, arcSegments = 0) {
|
||||
}
|
||||
|
||||
function arePointsEqual(point1, point2) {
|
||||
return point1.x === point2.x && point1.y === point2.y
|
||||
return Math.abs(point1.x - point2.x) < 1 && Math.abs(point1.y - point2.y) - 1
|
||||
}
|
||||
|
||||
function arraysHaveSamePoints(array1, array2) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user