sortedBaseLines
This commit is contained in:
parent
ca18e790fb
commit
e646f2993b
@ -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;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user