polygon name 수정, 지붕 나누기 수정

This commit is contained in:
hyojun.choi 2024-11-04 14:46:38 +09:00
parent da26628f69
commit 0adfe0916c
12 changed files with 299 additions and 49 deletions

View File

@ -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']

View File

@ -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']

View File

@ -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 }

View File

@ -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)

View File

@ -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 })
})

View File

@ -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]

View File

@ -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) => {

View File

@ -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
})

View File

@ -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()

View File

@ -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 },

View File

@ -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

View File

@ -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) {