Merge pull request '간격이 다를 때 스켈레톤이 문제' (#656) from dev into prd-deploy
Reviewed-on: #656
This commit is contained in:
commit
af6e623ed1
@ -401,26 +401,70 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
console.log('baseLinePoints:', orderedBaseLinePoints)
|
||||
|
||||
// baseLinePoint에서 roofLinePoint 방향으로 45도 대각선 확장 후 가장 가까운 접점 계산
|
||||
let roofLineContactPoints = orderedBaseLinePoints.map((point, index) => {
|
||||
// 각 포인트의 dx, dy, sign 정보 수집
|
||||
const contactData = orderedBaseLinePoints.map((point, index) => {
|
||||
const roofPoint = roofLinePoints[index]
|
||||
if (!roofPoint) return point
|
||||
if (!roofPoint) return { dx: 0, dy: 0, signDx: 0, signDy: 0 }
|
||||
|
||||
const dx = roofPoint.x - point.x
|
||||
const dy = roofPoint.y - point.y
|
||||
const absDx = Math.abs(dx)
|
||||
const absDy = Math.abs(dy)
|
||||
return { dx, dy, signDx: Math.sign(dx), signDy: Math.sign(dy) }
|
||||
})
|
||||
|
||||
// maxStep: 모든 포인트 중 가장 큰 45도 step
|
||||
const maxStep = contactData.reduce((max, data) => {
|
||||
return Math.max(max, Math.min(Math.abs(data.dx), Math.abs(data.dy)))
|
||||
}, 0)
|
||||
|
||||
// baseLine 폴리곤의 중심 계산 (확장 방향 결정용)
|
||||
const centroid = orderedBaseLinePoints.reduce((acc, p) => {
|
||||
acc.x += p.x / orderedBaseLinePoints.length
|
||||
acc.y += p.y / orderedBaseLinePoints.length
|
||||
return acc
|
||||
}, { x: 0, y: 0 })
|
||||
|
||||
// 모든 포인트를 동일한 maxStep으로 45도 확장
|
||||
let roofLineContactPoints = orderedBaseLinePoints.map((point, index) => {
|
||||
const data = contactData[index]
|
||||
const { dx, dy } = data
|
||||
|
||||
// dx 또는 dy가 0인 경우 중심에서 바깥쪽 방향으로 확장
|
||||
let signDx = data.signDx
|
||||
let signDy = data.signDy
|
||||
if (signDx === 0) {
|
||||
signDx = point.x >= centroid.x ? 1 : -1
|
||||
}
|
||||
if (signDy === 0) {
|
||||
signDy = point.y >= centroid.y ? 1 : -1
|
||||
}
|
||||
|
||||
return {
|
||||
x: point.x + signDx * maxStep,
|
||||
y: point.y + signDy * maxStep
|
||||
}
|
||||
})
|
||||
|
||||
const maxContactDistance = Math.hypot(maxStep, maxStep)
|
||||
|
||||
let changRoofLinePoints = orderedBaseLinePoints.map((point, index) => {
|
||||
const contactPoint = roofLineContactPoints[index]
|
||||
if (!contactPoint) return point
|
||||
|
||||
const dx = contactPoint.x - point.x
|
||||
const dy = contactPoint.y - point.y
|
||||
const len = Math.hypot(dx, dy)
|
||||
|
||||
// 거리가 0이면 이미 같은 위치
|
||||
if (absDx === 0 && absDy === 0) return point
|
||||
if (len === 0) return point
|
||||
|
||||
const step = Math.min(absDx, absDy)
|
||||
const step = maxContactDistance
|
||||
if (step === 0) return point
|
||||
|
||||
const nextX = point.x + Math.sign(dx) * step
|
||||
const nextY = point.y + Math.sign(dy) * step
|
||||
const nextX = point.x + (dx / len) * step
|
||||
const nextY = point.y + (dy / len) * step
|
||||
return {
|
||||
x: Number(nextX.toFixed(1)),
|
||||
y: Number(nextY.toFixed(1))
|
||||
x: nextX,
|
||||
y: nextY
|
||||
}
|
||||
})
|
||||
|
||||
@ -429,8 +473,11 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
roofLineContactPoints = movingLineFromSkeleton(roofId, canvas)
|
||||
}
|
||||
|
||||
console.log('points:', roofLineContactPoints)
|
||||
const geoJSONPolygon = toGeoJSON(roofLineContactPoints)
|
||||
// changRoofLinePoints 좌표를 roof.skeletonPoints에 저장 (원본 roof.points는 유지)
|
||||
roof.skeletonPoints = changRoofLinePoints.map(p => ({ x: p.x, y: p.y }))
|
||||
|
||||
console.log('points:', changRoofLinePoints)
|
||||
const geoJSONPolygon = toGeoJSON(changRoofLinePoints)
|
||||
|
||||
try {
|
||||
// SkeletonBuilder는 닫히지 않은 폴리곤을 기대하므로 마지막 점 제거
|
||||
@ -440,7 +487,7 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
||||
// 스켈레톤 데이터를 기반으로 내부선 생성
|
||||
roof.innerLines = roof.innerLines || []
|
||||
roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode)
|
||||
|
||||
//console.log("roofInnerLines:::", roof.innerLines);
|
||||
// 캔버스에 스켈레톤 상태 저장
|
||||
if (!canvas.skeletonStates) {
|
||||
canvas.skeletonStates = {}
|
||||
@ -1722,10 +1769,28 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) {
|
||||
}
|
||||
|
||||
let eavesLines = []
|
||||
// 확장된 외곽선 판별용
|
||||
const skPts = roof.skeletonPoints || []
|
||||
const isSkeletonOuterEdge = (p1, p2, tolerance = 0.5) => {
|
||||
for (let si = 0; si < skPts.length; si++) {
|
||||
const sp1 = skPts[si]
|
||||
const sp2 = skPts[(si + 1) % skPts.length]
|
||||
if ((Math.abs(p1.x - sp1.x) < tolerance && Math.abs(p1.y - sp1.y) < tolerance &&
|
||||
Math.abs(p2.x - sp2.x) < tolerance && Math.abs(p2.y - sp2.y) < tolerance) ||
|
||||
(Math.abs(p1.x - sp2.x) < tolerance && Math.abs(p1.y - sp2.y) < tolerance &&
|
||||
Math.abs(p2.x - sp1.x) < tolerance && Math.abs(p2.y - sp1.y) < tolerance)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (let i = 0; i < polygonPoints.length; i++) {
|
||||
const p1 = polygonPoints[i];
|
||||
const p2 = polygonPoints[(i + 1) % polygonPoints.length];
|
||||
|
||||
// 확장된 외곽선에 해당하는 edge는 스킵
|
||||
if (skPts.length > 0 && isSkeletonOuterEdge(p1, p2)) continue
|
||||
|
||||
// 지붕 경계선과 교차 확인 및 클리핑
|
||||
const clippedLine = clipLineToRoofBoundary(p1, p2, roof.lines, roof.moveSelectLine);
|
||||
@ -1900,7 +1965,7 @@ function addRawLine(id, skeletonLines, p1, p2, lineType, color, width, pitch, is
|
||||
};
|
||||
|
||||
skeletonLines.push(newLine);
|
||||
console.log('skeletonLines', skeletonLines);
|
||||
//console.log('skeletonLines', skeletonLines);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user