라인머지

This commit is contained in:
ysCha 2025-12-30 10:52:22 +09:00
parent ee3998c795
commit 175a177f4d

View File

@ -692,51 +692,51 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const sortRoofLines = ensureCounterClockwiseLines(roofLines)
// roofLines의 방향에 맞춰 currentRoofLines의 방향을 조정
const alignLineDirection = (sourceLines, targetLines) => {
return sourceLines.map((sourceLine) => {
// 가장 가까운 targetLine 찾기
const nearestTarget = targetLines.reduce((nearest, targetLine) => {
const sourceCenter = {
x: (sourceLine.x1 + sourceLine.x2) / 2,
y: (sourceLine.y1 + sourceLine.y2) / 2,
}
const targetCenter = {
x: (targetLine.x1 + targetLine.x2) / 2,
y: (targetLine.y1 + targetLine.y2) / 2,
}
const distance = Math.hypot(sourceCenter.x - targetCenter.x, sourceCenter.y - targetCenter.y)
return !nearest || distance < nearest.distance ? { line: targetLine, distance } : nearest
}, null)?.line
if (!nearestTarget) return sourceLine
// 방향이 반대인지 확인 (벡터 내적을 사용)
const sourceVec = {
x: sourceLine.x2 - sourceLine.x1,
y: sourceLine.y2 - sourceLine.y1,
}
const targetVec = {
x: nearestTarget.x2 - nearestTarget.x1,
y: nearestTarget.y2 - nearestTarget.y1,
}
const dotProduct = sourceVec.x * targetVec.x + sourceVec.y * targetVec.y
// 내적이 음수이면 방향이 반대이므로 뒤집기
if (dotProduct < 0) {
return {
...sourceLine,
x1: sourceLine.x2,
y1: sourceLine.y2,
x2: sourceLine.x1,
y2: sourceLine.y1,
}
}
return sourceLine
})
}
// const alignLineDirection = (sourceLines, targetLines) => {
// return sourceLines.map((sourceLine) => {
// // 가장 가까운 targetLine 찾기
// const nearestTarget = targetLines.reduce((nearest, targetLine) => {
// const sourceCenter = {
// x: (sourceLine.x1 + sourceLine.x2) / 2,
// y: (sourceLine.y1 + sourceLine.y2) / 2,
// }
// const targetCenter = {
// x: (targetLine.x1 + targetLine.x2) / 2,
// y: (targetLine.y1 + targetLine.y2) / 2,
// }
// const distance = Math.hypot(sourceCenter.x - targetCenter.x, sourceCenter.y - targetCenter.y)
//
// return !nearest || distance < nearest.distance ? { line: targetLine, distance } : nearest
// }, null)?.line
//
// if (!nearestTarget) return sourceLine
//
// // 방향이 반대인지 확인 (벡터 내적을 사용)
// const sourceVec = {
// x: sourceLine.x2 - sourceLine.x1,
// y: sourceLine.y2 - sourceLine.y1,
// }
// const targetVec = {
// x: nearestTarget.x2 - nearestTarget.x1,
// y: nearestTarget.y2 - nearestTarget.y1,
// }
//
// const dotProduct = sourceVec.x * targetVec.x + sourceVec.y * targetVec.y
//
// // 내적이 음수이면 방향이 반대이므로 뒤집기
// if (dotProduct < 0) {
// return {
// ...sourceLine,
// x1: sourceLine.x2,
// y1: sourceLine.y2,
// x2: sourceLine.x1,
// y2: sourceLine.y1,
// }
// }
//
// return sourceLine
// })
// }
console.log('wallBaseLines', wall.baseLines)
@ -762,9 +762,31 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
console.log('wallBaseLine:', wallBaseLine.x1, wallBaseLine.y1, wallBaseLine.x2, wallBaseLine.y2)
console.log('isSamePoint result:', isSameLine2(wallBaseLine, wallLine))
const isCollinear = (l1, l2, tolerance = 0.1) => {
const slope1 = Math.abs(l1.x2 - l1.x1) < tolerance ? Infinity : (l1.y2 - l1.y1) / (l1.x2 - l1.x1)
const slope2 = Math.abs(l2.x2 - l2.x1) < tolerance ? Infinity : (l2.y2 - l2.y1) / (l2.x2 - l2.x1)
if (slope1 === Infinity && slope2 === Infinity) {
return Math.abs(l1.x1 - l2.x1) < tolerance
}
if (Math.abs(slope1 - slope2) > tolerance) return false
const yIntercept1 = l1.y1 - slope1 * l1.x1
const yIntercept2 = l2.y1 - slope2 * l2.x1
return Math.abs(yIntercept1 - yIntercept2) < tolerance
}
if (isCollinear(wallBaseLine, wallLine)) {
return
}
if (isSameLine2(wallBaseLine, wallLine)) {
return
}
const movedStart = Math.abs(wallBaseLine.x1 - wallLine.x1) > EPSILON || Math.abs(wallBaseLine.y1 - wallLine.y1) > EPSILON
const movedEnd = Math.abs(wallBaseLine.x2 - wallLine.x2) > EPSILON || Math.abs(wallBaseLine.y2 - wallLine.y2) > EPSILON
@ -3572,6 +3594,7 @@ function isValleyVertex(targetPoint, connectedLine, allLines, isStartVertex) {
}
const crossProduct = getTurnDirection(p1, p2, p3);
console.log('crossProduct:', crossProduct);
return crossProduct > 0;
}
@ -3595,32 +3618,11 @@ function findInteriorPoint(line, polygonLines) {
// 2. 끝점이 골짜기인지 확인
const endIsValley = isValleyVertex(currentLine.endPoint, currentLine, polygonLines, false);
// 3. 라인의 방향성 확인
const isHorizontal = y1 === y2; // 정확히 수평
const isVertical = x1 === x2; // 정확히 수직
const isLeftToRight = x1 < x2; // 왼쪽에서 오른쪽 방향
const isTopToBottom = y1 < y2; // 위에서 아래 방향
// 4. 평행한 라인 중에서 start 또는 end가 true인 경우 isParallelWithValley = true
let isParallelWithValley = false;
if (isHorizontal || isVertical) {
if (isHorizontal) {
// 수평선인 경우: 왼쪽이 start, 오른쪽이 end
if ((isLeftToRight && startIsValley) || (!isLeftToRight && endIsValley)) {
isParallelWithValley = true;
}
} else {
// 수직선인 경우: 위가 start, 아래가 end
if ((isTopToBottom && startIsValley) || (!isTopToBottom && endIsValley)) {
isParallelWithValley = true;
}
}
}
return {
start: startIsValley,
end: endIsValley,
isParallel: isParallelWithValley
end: endIsValley
};
}