모듈 자동 설정 작업 진행중

This commit is contained in:
yjnoh 2024-11-25 17:40:41 +09:00
parent 997b8febeb
commit 5d4832e5bc

View File

@ -5,6 +5,7 @@ import { rectToPolygon, setSurfaceShapePattern } from '@/util/canvas-util'
import { roofDisplaySelector } from '@/store/settingAtom'
import offsetPolygon from '@/util/qpolygon-utils'
import { QPolygon } from '@/components/fabric/QPolygon'
import { QLine } from '@/components/fabric/QLine'
import { moduleSetupSurfaceState, moduleIsSetupState } from '@/store/canvasAtom'
import { useEvent } from '@/hooks/useEvent'
import { POLYGON_TYPE, BATCH_TYPE } from '@/common/common'
@ -53,6 +54,11 @@ export function useModuleBasicSetting() {
setupSurface.setViewLengthText(false)
canvas.add(setupSurface)
bottomModuleLine(setupSurface)
topModuleLine(setupSurface)
leftModuleLine(setupSurface)
// rightModuleLine(setupSurface)
//지붕면 선택 금지
roof.set({
selectable: false,
@ -597,7 +603,7 @@ export function useModuleBasicSetting() {
name: 'module',
})
tempModule.setViewLengthText(false)
canvas?.add(tempModule)
// canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
}
} else {
@ -617,7 +623,7 @@ export function useModuleBasicSetting() {
lineRow: row,
name: 'module',
})
canvas?.add(tempModule)
// canvas?.add(tempModule)
moduleSetupArray.push(tempModule)
}
}
@ -765,41 +771,417 @@ export function useModuleBasicSetting() {
return hull
}
const calcMinXByHeightDistance = (nowSurface, index, reverse) => {
function calculateSlopeIntercept(x1, y1, x2, y2) {
console.log('Intercept', x1, y1, x2, y2)
const bottomModuleLine = (nowSurface) => {
let selectedLine = null
const slope = (y2 - y1) / (x2 - x1)
const intercept = y1 - slope * x1
const sortedLines = sortLinesByTopLeft(nowSurface.lines)
return { slope, intercept }
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
// if (nowSurface.flowDirection === 'east') {
// const leftFlow = nowSurface.lines.reduce(
// (acc, line, index) => {
// if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
// return { x1: line.x1, y1: line.y1, index: index }
// }
// return acc
// },
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
// )
// selectedLine = leftFlow
// } else if (nowSurface.flowDirection === 'west') {
// const rightFlow = nowSurface.lines.reduce(
// (acc, line, index) => {
// if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) {
// return { x1: line.x1, y1: line.y1, index: index }
// }
// return acc
// },
// { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
// )
// selectedLine = rightFlow
// } else if (nowSurface.flowDirection === 'north') {
// const topFlow = nowSurface.lines.reduce(
// (acc, line, index) => {
// if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
// return { x1: line.x1, y1: line.y1, index: index }
// }
// return acc
// },
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
// )
// selectedLine = topFlow
// } else {
const bottomFlow = nowSurface.lines.reduce(
(acc, line, index) => {
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
return { x1: line.x1, y1: line.y1, index: index }
}
return acc
},
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
)
selectedLine = bottomFlow
// }
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
let nextLines = nowSurface.lines[selectedLine.index]
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
const c1 = prevLines.y1 - m1 * prevLines.x1
const c2 = nextLines.y1 - m2 * nextLines.x1
// Step 2: Calculate intersection point
let xIntersectPrev = 0
let yIntersectPrev = 0
let xIntersectNext = 0
let yIntersectNext = 0
let endPoint = prevLines.y1 > nextLines.y2 ? prevLines.y1 : nextLines.y2
let biggerEndPoint = prevLines.y1 > nextLines.y2 ? 'left' : 'right'
//bottom일 경우
xIntersectPrev = (endPoint - c1) / m1
yIntersectPrev = m1 * xIntersectPrev + c1
xIntersectNext = (endPoint - c2) / m2
yIntersectNext = m2 * xIntersectNext + c2
let lineCoords
let polygonCoords
let ratio = 1
if (biggerEndPoint === 'left') {
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
polygonCoords = [
{ x: prevLines.x1, y: yIntersectNext },
{ x: xIntersectNext, y: yIntersectNext },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
} else {
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
polygonCoords = [
{ x: xIntersectPrev, y: yIntersectPrev },
{ x: nextLines.x2, y: yIntersectPrev },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
}
let prevLines = nowSurface.lines[(index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
let nextLines = nowSurface.lines[index]
const tempTriangle = new QPolygon(polygonCoords, {
fill: 'transparent',
stroke: 'green',
strokeWidth: 2,
originY: 'bottom',
strokeDashArray: [5, 5],
// fontSize: 15,
})
// 선분 정보
const l1 = prevLines
const l2 = nextLines
const lineLength = 172.2
// canvas.add(tempTriangle)
// l1과 l2의 기울기 및 절편
let { slope: m1, intercept: b1 } = calculateSlopeIntercept(l1.x1, l1.y1, l1.x2, l1.y2)
let { slope: m2, intercept: b2 } = calculateSlopeIntercept(l2.x1, l2.y1, l2.x2, l2.y2)
let cloneCoords = []
tempTriangle.clone((clone) => {
clone.scale(ratio)
cloneCoords = clone.getCurrentPoints()
})
console.log(m1, b1, m2, b2)
//아래쪽에선 잴 작은
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] > point['y'] ? acc : point))
// 가로선 x1 계산
const x1 = (m2 * lineLength + b2 - b1) / (m1 - m2)
const x2 = x1 + lineLength // 끝점 x2
const differenceDistance = overlapCoords.x - vertexPoints.x
// 가로선 y값 계산
const y0 = m1 * x1 + b1
const newTriangleCoords = cloneCoords.map((point) => {
return { x: point.x + differenceDistance, y: point.y }
})
// 결과 출력
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] > point['y'] ? acc : point))
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
console.log({ x1: x1, y1: y0, x2: x2, y2: y0 })
return { x1: x1, y1: y0, x2: x2, y2: y0 }
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
fill: 'transparent',
stroke: 'red',
strokeWidth: 2,
selectable: true,
fontSize: 14,
})
canvas.add(newLine)
return newLine
}
const topModuleLine = (nowSurface) => {
let selectedLine = null
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
const topFlow = nowSurface.lines.reduce(
(acc, line, index) => {
if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
return { x1: line.x1, y1: line.y1, index: index }
}
return acc
},
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
)
selectedLine = topFlow
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
let nextLines = nowSurface.lines[selectedLine.index]
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
const c1 = prevLines.y1 - m1 * prevLines.x1
const c2 = nextLines.y1 - m2 * nextLines.x1
// Step 2: Calculate intersection point
let xIntersectPrev = 0
let yIntersectPrev = 0
let xIntersectNext = 0
let yIntersectNext = 0
let endPoint = prevLines.y1 > nextLines.y2 ? nextLines.y2 : prevLines.y1
let biggerEndPoint = prevLines.y1 < nextLines.y2 ? 'left' : 'right'
//bottom일 경우
xIntersectPrev = (endPoint - c1) / m1
yIntersectPrev = m1 * xIntersectPrev + c1
xIntersectNext = (endPoint - c2) / m2
yIntersectNext = m2 * xIntersectNext + c2
let lineCoords
let polygonCoords
let ratio = 1
if (biggerEndPoint === 'left') {
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
polygonCoords = [
{ x: prevLines.x1, y: yIntersectNext },
{ x: xIntersectNext, y: yIntersectNext },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
} else {
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
polygonCoords = [
{ x: xIntersectPrev, y: yIntersectPrev },
{ x: nextLines.x2, y: yIntersectPrev },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
}
const tempTriangle = new QPolygon(polygonCoords, {
fill: 'transparent',
stroke: 'green',
strokeWidth: 2,
originY: 'top',
strokeDashArray: [5, 5],
// fontSize: 15,
})
// canvas.add(tempTriangle)
let cloneCoords = []
tempTriangle.clone((clone) => {
clone.scale(ratio)
cloneCoords = clone.getCurrentPoints()
})
//아래쪽에선 잴 작은
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] < point['y'] ? acc : point))
const differenceDistance = overlapCoords.x - vertexPoints.x
const newTriangleCoords = cloneCoords.map((point) => {
return { x: point.x + differenceDistance, y: point.y }
})
// const newTriangle1 = new QPolygon(newTriangleCoords, {
// fill: 'transparent',
// stroke: 'red',
// strokeWidth: 1,
// selectable: true,
// fontSize: 14,
// })
// canvas.add(newTriangle1)
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] < point['y'] ? acc : point))
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
fill: 'transparent',
stroke: 'red',
strokeWidth: 2,
selectable: true,
fontSize: 14,
})
canvas.add(newLine)
return newLine
}
const leftModuleLine = (nowSurface) => {
let selectedLine = null
sortLinesByTopLeft(nowSurface)
console.log('nowSurface', nowSurface)
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
const leftFlow = nowSurface.lines.reduce(
(acc, line, index) => {
if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
return { x1: line.x1, y1: line.y1, index: index }
}
return acc
},
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
)
selectedLine = leftFlow
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
let nextLines = nowSurface.lines[selectedLine.index]
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
const c1 = prevLines.y1 - m1 * prevLines.x1
const c2 = nextLines.y1 - m2 * nextLines.x1
// Step 2: Calculate intersection point
let xIntersectPrev = 0
let yIntersectPrev = 0
let xIntersectNext = 0
let yIntersectNext = 0
let biggerEndPoint = prevLines.x1 > nextLines.x2 ? 'top' : 'bottom'
console.log('prevLines.x1', prevLines.x1)
console.log('nextLines.x2', nextLines.x2)
console.log('biggerEndPoint', biggerEndPoint)
//bottom일 경우
xIntersectPrev = prevLines.x1
yIntersectPrev = m1 * xIntersectPrev + c1
xIntersectNext = prevLines.x1
yIntersectNext = m2 * xIntersectNext + c2
let lineCoords
let polygonCoords
let ratio = 1
if (biggerEndPoint === 'top') {
//윗쪽이이 더 밑이면 아래 라인에 절편으로 계산
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
polygonCoords = [
{ x: prevLines.x1, y: yIntersectNext },
{ x: xIntersectNext, y: yIntersectNext },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
} else {
lineCoords = [xIntersectPrev, prevLines.y1, xIntersectPrev, yIntersectPrev]
polygonCoords = [
{ x: xIntersectNext, y: prevLines.y1 },
{ x: xIntersectNext, y: yIntersectNext },
{ x: overlapCoords.x, y: overlapCoords.y },
]
ratio = moduleWidthLength / Math.abs(prevLines.y1 - yIntersectNext)
}
const tempTriangle = new QPolygon(polygonCoords, {
fill: 'transparent',
stroke: 'green',
strokeWidth: 2,
originX: 'left',
strokeDashArray: [5, 5],
// fontSize: 15,
selectable: true,
})
// canvas.add(tempTriangle)
let cloneCoords = []
tempTriangle.clone((clone) => {
clone.scale(ratio)
cloneCoords = clone.getCurrentPoints()
// canvas.add(clone)
})
canvas.remove(tempTriangle)
//left에선 가장 왼쪽
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['x'] < point['x'] ? acc : point))
const differenceDistance = overlapCoords.y - vertexPoints.y
const newTriangleCoords = cloneCoords.map((point) => {
return { x: point.x, y: point.y + differenceDistance }
})
// const newTriangle1 = new QPolygon(newTriangleCoords, {
// fill: 'transparent',
// stroke: 'red',
// strokeWidth: 1,
// selectable: true,
// fontSize: 14,
// })
// canvas.add(newTriangle1)
const deleteLeftPoint = newTriangleCoords.reduce((acc, point) => (acc['x'] < point['x'] ? acc : point))
const deleteIndex = newTriangleCoords.indexOf(deleteLeftPoint)
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
fill: 'transparent',
stroke: 'red',
strokeWidth: 2,
viewLengthText: false,
// selectable: true,
fontSize: 14,
})
canvas.add(newLine)
return newLine
}
function sortLinesByTopLeft(surface) {
// 좌측 상단 기준으로 정렬
const sortedLines = surface.lines.sort((a, b) => {
// x1, y1 값을 기준으로 정렬
if (a.x1 !== b.x1) {
return a.x1 - b.x1 // x1 기준 정렬
} else {
return a.y1 - b.y1 // x1이 같으면 y1 기준 정렬
}
})
// 정렬된 결과를 기반으로 좌표 재정렬
sortedLines.forEach((line) => {
// 좌측 상단이 (0,0) 기준이 되도록 좌표 이동
const minX = Math.min(line.x1, line.x2)
const minY = Math.min(line.y1, line.y2)
line.set({
x1: line.x1 - minX,
y1: line.y1 - minY,
x2: line.x2 - minX,
y2: line.y2 - minY,
})
})
surface.set({
sortedLines: sortedLines,
})
return sortedLines
}
return {