Merge pull request 'dev_cha' (#447) from dev_cha into dev
Reviewed-on: #447
This commit is contained in:
commit
23b8aa7fa7
3
.gitignore
vendored
3
.gitignore
vendored
@ -42,4 +42,5 @@ next-env.d.ts
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
certificates
|
||||
certificates
|
||||
.ai
|
||||
@ -22,7 +22,7 @@
|
||||
"chart.js": "^4.4.6",
|
||||
"dayjs": "^1.11.13",
|
||||
"env-cmd": "^10.1.0",
|
||||
"fabric": "^5.3.0",
|
||||
"fabric": "^5.5.2",
|
||||
"framer-motion": "^11.2.13",
|
||||
"fs": "^0.0.1-security",
|
||||
"iron-session": "^8.0.2",
|
||||
|
||||
@ -336,8 +336,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
||||
// 용마루 -- straight-skeleton
|
||||
console.log('용마루 지붕')
|
||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
//drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
||||
//drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
||||
} else if (isGableRoof(types)) {
|
||||
// A형, B형 박공 지붕
|
||||
console.log('패턴 지붕')
|
||||
|
||||
@ -30,6 +30,8 @@ import { QcastContext } from '@/app/QcastProvider'
|
||||
import { usePlan } from '@/hooks/usePlan'
|
||||
import { roofsState } from '@/store/roofAtom'
|
||||
import { useText } from '@/hooks/useText'
|
||||
import { processEaveHelpLines } from '@/util/skeleton-utils'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
|
||||
export function useRoofAllocationSetting(id) {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -449,6 +451,22 @@ export function useRoofAllocationSetting(id) {
|
||||
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
||||
roofBases.forEach((roofBase) => {
|
||||
try {
|
||||
|
||||
const roofEaveHelpLines = canvas.getObjects().filter((obj) => obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id)
|
||||
if (roofEaveHelpLines.length > 0) {
|
||||
if (roofBase.lines) {
|
||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
||||
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
||||
roofBase.lines = [...newEaveLines]
|
||||
} else {
|
||||
roofBase.lines = [...roofEaveHelpLines]
|
||||
}
|
||||
if (!roofBase.innerLines) {
|
||||
roofBase.innerLines = []
|
||||
}
|
||||
}
|
||||
|
||||
if (roofBase.separatePolygon.length > 0) {
|
||||
splitPolygonWithSeparate(roofBase.separatePolygon)
|
||||
} else {
|
||||
|
||||
@ -845,6 +845,8 @@ export const usePolygon = () => {
|
||||
polygonLines.forEach((line) => {
|
||||
line.need = true
|
||||
})
|
||||
// 순서에 의존하지 않도록 모든 조합을 먼저 확인한 후 처리
|
||||
const innerLineMapping = new Map() // innerLine -> polygonLine 매핑 저장
|
||||
|
||||
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
||||
innerLines.forEach((innerLine) => {
|
||||
@ -854,14 +856,28 @@ export const usePolygon = () => {
|
||||
if (innerLine.attributes && polygonLine.attributes.type) {
|
||||
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
||||
if (polygonLine.length < innerLine.length) {
|
||||
polygonLine.need = false
|
||||
if(polygonLine.lineName !== 'eaveHelpLine'){
|
||||
polygonLine.need = false
|
||||
}
|
||||
}
|
||||
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||
innerLine.attributes.type = polygonLine.attributes.type
|
||||
innerLine.direction = polygonLine.direction
|
||||
innerLine.attributes.isStart = true
|
||||
innerLine.parentLine = polygonLine
|
||||
// innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||
// innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||
// innerLine.attributes.type = polygonLine.attributes.type
|
||||
// innerLine.direction = polygonLine.direction
|
||||
// innerLine.attributes.isStart = true
|
||||
// innerLine.parentLine = polygonLine
|
||||
|
||||
|
||||
// 매핑된 innerLine의 attributes를 변경 (교차점 계산 전에 적용)
|
||||
innerLineMapping.forEach((polygonLine, innerLine) => {
|
||||
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||
innerLine.attributes.type = polygonLine.attributes.type
|
||||
innerLine.direction = polygonLine.direction
|
||||
innerLine.attributes.isStart = true
|
||||
innerLine.parentLine = polygonLine
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1371,7 +1387,7 @@ export const usePolygon = () => {
|
||||
let representLine
|
||||
|
||||
// 지붕을 그리면서 기존 polygon의 line중 연결된 line을 찾는다.
|
||||
;[...polygonLines, ...innerLines].forEach((line) => {
|
||||
[...polygonLines, ...innerLines].forEach((line) => {
|
||||
let startFlag = false
|
||||
let endFlag = false
|
||||
const startPoint = line.startPoint
|
||||
@ -1567,52 +1583,126 @@ export const usePolygon = () => {
|
||||
|
||||
// ==== Dijkstra pathfinding ====
|
||||
|
||||
// function findShortestPath(start, end, graph, epsilon = 1) {
|
||||
// const startKey = pointToKey(start, epsilon)
|
||||
// const endKey = pointToKey(end, epsilon)
|
||||
//
|
||||
// const distances = {}
|
||||
// const previous = {}
|
||||
// const visited = new Set()
|
||||
// const queue = [{ key: startKey, dist: 0 }]
|
||||
//
|
||||
// for (const key in graph) distances[key] = Infinity
|
||||
// distances[startKey] = 0
|
||||
//
|
||||
// while (queue.length > 0) {
|
||||
// queue.sort((a, b) => a.dist - b.dist)
|
||||
// const { key } = queue.shift()
|
||||
// if (visited.has(key)) continue
|
||||
// visited.add(key)
|
||||
//
|
||||
// for (const neighbor of graph[key] || []) {
|
||||
// const neighborKey = pointToKey(neighbor.point, epsilon)
|
||||
// const alt = distances[key] + neighbor.distance
|
||||
// if (alt < distances[neighborKey]) {
|
||||
// distances[neighborKey] = alt
|
||||
// previous[neighborKey] = key
|
||||
// queue.push({ key: neighborKey, dist: alt })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// const path = []
|
||||
// let currentKey = endKey
|
||||
//
|
||||
// if (!previous[currentKey]) return null
|
||||
//
|
||||
// while (currentKey !== startKey) {
|
||||
// const [x, y] = currentKey.split(',').map(Number)
|
||||
// path.unshift({ x, y })
|
||||
// currentKey = previous[currentKey]
|
||||
// }
|
||||
//
|
||||
// const [sx, sy] = startKey.split(',').map(Number)
|
||||
// path.unshift({ x: sx, y: sy })
|
||||
//
|
||||
// return path
|
||||
// }
|
||||
|
||||
function findShortestPath(start, end, graph, epsilon = 1) {
|
||||
const startKey = pointToKey(start, epsilon)
|
||||
const endKey = pointToKey(end, epsilon)
|
||||
const startKey = pointToKey(start, epsilon);
|
||||
const endKey = pointToKey(end, epsilon);
|
||||
|
||||
const distances = {}
|
||||
const previous = {}
|
||||
const visited = new Set()
|
||||
const queue = [{ key: startKey, dist: 0 }]
|
||||
// 거리와 이전 노드 추적
|
||||
const distances = { [startKey]: 0 };
|
||||
const previous = {};
|
||||
const visited = new Set();
|
||||
|
||||
for (const key in graph) distances[key] = Infinity
|
||||
distances[startKey] = 0
|
||||
// 우선순위 큐 (거리가 짧은 순으로 정렬)
|
||||
const queue = [{ key: startKey, dist: 0 }];
|
||||
|
||||
while (queue.length > 0) {
|
||||
queue.sort((a, b) => a.dist - b.dist)
|
||||
const { key } = queue.shift()
|
||||
if (visited.has(key)) continue
|
||||
visited.add(key)
|
||||
// 모든 노드 초기화
|
||||
for (const key in graph) {
|
||||
if (key !== startKey) {
|
||||
distances[key] = Infinity;
|
||||
}
|
||||
}
|
||||
|
||||
for (const neighbor of graph[key] || []) {
|
||||
const neighborKey = pointToKey(neighbor.point, epsilon)
|
||||
const alt = distances[key] + neighbor.distance
|
||||
if (alt < distances[neighborKey]) {
|
||||
distances[neighborKey] = alt
|
||||
previous[neighborKey] = key
|
||||
queue.push({ key: neighborKey, dist: alt })
|
||||
// 우선순위 큐에서 다음 노드 선택
|
||||
const getNextNode = () => {
|
||||
if (queue.length === 0) return null;
|
||||
queue.sort((a, b) => a.dist - b.dist);
|
||||
return queue.shift();
|
||||
};
|
||||
|
||||
let current;
|
||||
while ((current = getNextNode())) {
|
||||
const currentKey = current.key;
|
||||
|
||||
// 목적지에 도달하면 종료
|
||||
if (currentKey === endKey) break;
|
||||
|
||||
// 이미 방문한 노드는 건너뜀
|
||||
if (visited.has(currentKey)) continue;
|
||||
visited.add(currentKey);
|
||||
|
||||
// 인접 노드 탐색
|
||||
for (const neighbor of graph[currentKey] || []) {
|
||||
const neighborKey = pointToKey(neighbor.point, epsilon);
|
||||
if (visited.has(neighborKey)) continue;
|
||||
|
||||
const alt = distances[currentKey] + neighbor.distance;
|
||||
|
||||
// 더 짧은 경로를 찾은 경우 업데이트
|
||||
if (alt < (distances[neighborKey] || Infinity)) {
|
||||
distances[neighborKey] = alt;
|
||||
previous[neighborKey] = currentKey;
|
||||
|
||||
// 우선순위 큐에 추가
|
||||
queue.push({ key: neighborKey, dist: alt });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const path = []
|
||||
let currentKey = endKey
|
||||
// 경로 재구성
|
||||
const path = [];
|
||||
let currentKey = endKey;
|
||||
|
||||
if (!previous[currentKey]) return null
|
||||
|
||||
while (currentKey !== startKey) {
|
||||
const [x, y] = currentKey.split(',').map(Number)
|
||||
path.unshift({ x, y })
|
||||
currentKey = previous[currentKey]
|
||||
// 시작점에 도달할 때까지 역추적
|
||||
while (previous[currentKey] !== undefined) {
|
||||
const [x, y] = currentKey.split(',').map(Number);
|
||||
path.unshift({ x, y });
|
||||
currentKey = previous[currentKey];
|
||||
}
|
||||
|
||||
const [sx, sy] = startKey.split(',').map(Number)
|
||||
path.unshift({ x: sx, y: sy })
|
||||
// 시작점 추가
|
||||
if (path.length > 0) {
|
||||
const [sx, sy] = startKey.split(',').map(Number);
|
||||
path.unshift({ x: sx, y: sy });
|
||||
}
|
||||
|
||||
return path
|
||||
return path.length > 0 ? path : null;
|
||||
}
|
||||
|
||||
// 최종 함수
|
||||
function getPath(start, end, graph, epsilon = 1) {
|
||||
// startPoint와 arrivalPoint가 될 수 있는 점은 line.attributes.type이 'default' 혹은 null이 아닌 line인 경우에만 가능
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user