sortedBaseLines

This commit is contained in:
yscha 2025-12-10 00:40:53 +09:00
parent 5ca4f3d901
commit 540812861d

View File

@ -754,6 +754,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const sortedCurrentRoofLines = sortCurrentRoofLines(alignedCurrentRoofLines);
const sortedRoofLines = sortCurrentRoofLines(roofLines);
const sortedWallBaseLines = sortCurrentRoofLines(wall.baseLines);
const sortedBaseLines = sortBaseLinesByWallLines(wall.baseLines, wallLines);
//wall.lines 는 기본 벽 라인
@ -772,8 +773,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const roofLine = roofLines[index];
const currentRoofLine = currentRoofLines[index];
const moveLine = wall.baseLines[index]
const wallBaseLine = wall.baseLines[index]
const moveLine = sortedBaseLines[index]
const wallBaseLine = sortedBaseLines[index]
//roofline 외곽선 설정
@ -861,14 +862,13 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
//두 포인트가 변경된 라인인
if (fullyMoved ) {
//반시계방향향
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
console.log("moveFully:::::::::::::", roofLine.direction)
const mLine = getSelectLinePosition(wall, wallBaseLine)
if (getOrientation(roofLine) === 'vertical') {
if (['left', 'right'].includes(mLine.position)) {
if(wallLine.x1 === wallBaseLine.x1) {
if(Math.abs(wallLine.x1 - wallBaseLine.x1) < 0.1 || Math.abs(wallLine.x2 - wallBaseLine.x2) < 0.1) {
return false
}
const positionType =
@ -876,7 +876,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
(mLine.position === 'right' && wallLine.x1 > wallBaseLine.x1)
? 'in' : 'out';
const condition = `${mLine.position}_${positionType}`;
let isStartEnd = findInteriorPoint(wallBaseLine, wall.baseLines)
let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines)
let sPoint, ePoint;
if(condition === 'left_in') {
isIn = true
@ -1014,6 +1014,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
}
}
findPoints.push({ y: newPStart.y, x: newPEnd.x, position: 'left_out_end' });
}
}else if(condition === 'right_in') {
if (isStartEnd.start ) {
@ -1165,7 +1166,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
} else if (getOrientation(roofLine) === 'horizontal') { //red
if (['top', 'bottom'].includes(mLine.position)) {
if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1) {
if(Math.abs(wallLine.y1 - wallBaseLine.y1) < 0.1 || Math.abs(wallLine.y2 - wallBaseLine.y2) < 0.1) {
return false
}
const positionType =
@ -1174,7 +1175,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
? 'in' : 'out';
const condition = `${mLine.position}_${positionType}`;
let isStartEnd = findInteriorPoint(wallBaseLine, wall.baseLines)
let isStartEnd = findInteriorPoint(wallBaseLine, sortedBaseLines)
let sPoint, ePoint;
@ -1401,15 +1402,15 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber()
newPEnd.x = aStartX
newPStart.x = Big(roofLine.x1).plus(eLineX).toNumber()
let idx = (0 > index - 1)?roofLines.length:index
const newLine = roofLines[idx-1];
let idx = (roofLines.length < index + 1)?0:index
const newLine = roofLines[idx + 1];
if(Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
if(inLine){
if(inLine.y2 < inLine.y1 ) {
getAddLine({ x: bStartX, y: wallLine.y1 }, { x: inLine.x2, y: inLine.y2 }, 'pink')
}else{
getAddLine({ x: inLine.x2, y: inLine.y2 }, { x: bStartX, y: wallLine.y1 }, 'pink')
getAddLine({ x: inLine.x1, y: inLine.y1 }, { x: bStartX, y: wallLine.y1 }, 'pink')
}
}
getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x2, y: wallLine.y2 }, 'magenta')
@ -3136,7 +3137,7 @@ function updateAndAddLine(innerLines, targetPoint) {
isUpdatingStart = true;
}
}else if(targetPoint.position === "top_out_end"){
if(foundLine.y2 > foundLine.y1){
if(foundLine.y2 >= foundLine.y1){
isUpdatingStart = true;
}
}else if(targetPoint.position === "bottom_out_start"){
@ -3317,4 +3318,82 @@ function findInteriorPoint(line, polygonLines) {
start: startIsValley,
end: endIsValley
};
}
}
/**
* baseLines의 순서를 wallLines의 순서와 일치시킵니다.
* wallLine에 대해 가장 가깝고 평행한 baseLine을 찾아 정렬된 배열을 반환합니다.
*
* @param {Array} baseLines - 정렬할 원본 baseLine 배열
* @param {Array} wallLines - 기준이 되는 wallLine 배열
* @returns {Array} wallLines 순서에 맞춰 정렬된 baseLines
*/
export const sortBaseLinesByWallLines = (baseLines, wallLines) => {
if (!baseLines || !wallLines || baseLines.length === 0 || wallLines.length === 0) {
return baseLines;
}
const sortedBaseLines = [];
const usedIndices = new Set(); // 이미 매칭된 baseLine 인덱스를 추적
wallLines.forEach((wallLine) => {
let bestMatchIndex = -1;
let minDistance = Infinity;
// wallLine의 중점 계산
const wMidX = (wallLine.x1 + wallLine.x2) / 2;
const wMidY = (wallLine.y1 + wallLine.y2) / 2;
// wallLine의 방향 벡터 (평행 확인용)
const wDx = wallLine.x2 - wallLine.x1;
const wDy = wallLine.y2 - wallLine.y1;
const wLen = Math.hypot(wDx, wDy);
baseLines.forEach((baseLine, index) => {
// 이미 매칭된 라인은 건너뜀 (1:1 매칭)
if (usedIndices.has(index)) return;
// baseLine의 중점 계산
const bMidX = (baseLine.x1 + baseLine.x2) / 2;
const bMidY = (baseLine.y1 + baseLine.y2) / 2;
// 두 라인의 중점 사이 거리 계산
const dist = Math.hypot(wMidX - bMidX, wMidY - bMidY);
// 평행 여부 확인 (내적 사용)
const bDx = baseLine.x2 - baseLine.x1;
const bDy = baseLine.y2 - baseLine.y1;
const bLen = Math.hypot(bDx, bDy);
if (wLen > 0 && bLen > 0) {
// 단위 벡터 내적값 (-1 ~ 1)
const dot = (wDx * bDx + wDy * bDy) / (wLen * bLen);
// 내적의 절대값이 1에 가까우면 평행 (약 10도 오차 허용)
if (Math.abs(Math.abs(dot) - 1) < 0.1) {
if (dist < minDistance) {
minDistance = dist;
bestMatchIndex = index;
}
}
}
});
if (bestMatchIndex !== -1) {
sortedBaseLines.push(baseLines[bestMatchIndex]);
usedIndices.add(bestMatchIndex);
} else {
// 매칭되는 라인을 찾지 못한 경우, 아직 사용되지 않은 첫 번째 라인을 할당 (Fallback)
const unusedIndex = baseLines.findIndex((_, idx) => !usedIndices.has(idx));
if (unusedIndex !== -1) {
sortedBaseLines.push(baseLines[unusedIndex]);
usedIndices.add(unusedIndex);
} else {
// 더 이상 남은 라인이 없으면 null 또는 기존 라인 중 하나(에러 방지)
sortedBaseLines.push(baseLines[0]);
}
}
});
return sortedBaseLines;
};