집추가작업6
This commit is contained in:
parent
7d33d0875d
commit
77c0fe7edc
@ -610,12 +610,18 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
const currentRoofLines = canvas.getObjects().filter((obj) => obj.lineName === 'roofLine' && obj.attributes.roofId === roofId)
|
||||
let roofLineRects = canvas.getObjects().filter((obj) => obj.name === 'roofLineRect' && obj.roofId === roofId)
|
||||
|
||||
|
||||
|
||||
|
||||
roofLineRects.forEach((roofLineRect) => {
|
||||
canvas.remove(roofLineRect)
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
|
||||
let helpLines = canvas.getObjects().filter((obj) => obj.lineName === 'helpLine' && obj.roofId === roofId)
|
||||
helpLines.forEach((helpLine) => {
|
||||
canvas.remove(helpLine)
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
function sortCurrentRoofLines(lines) {
|
||||
return [...lines].sort((a, b) => {
|
||||
@ -666,70 +672,187 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//wall.lines 는 기본 벽 라인
|
||||
//wall.baseLine은 움직인라인
|
||||
const movedLines = []
|
||||
|
||||
sortedWallLines.forEach((wallLine, index) => {
|
||||
|
||||
|
||||
|
||||
const roofLine = sortedRoofLines[index];
|
||||
const currentRoofLine = sortedCurrentRoofLines[index];
|
||||
const moveLine = sortedWallBaseLines[index]
|
||||
|
||||
const wallBaseLine = sortedWallBaseLines[index]
|
||||
|
||||
const origin = moveLine.attributes?.originPoint
|
||||
if (!origin) return
|
||||
|
||||
const movedStart =
|
||||
Math.abs(moveLine.x1 - origin.x1) > EPSILON ||
|
||||
Math.abs(moveLine.y1 - origin.y1) > EPSILON
|
||||
if(isSamePoint(moveLine, wallLine)) {
|
||||
return false
|
||||
}
|
||||
|
||||
const movedEnd =
|
||||
Math.abs(moveLine.x2 - origin.x2) > EPSILON ||
|
||||
Math.abs(moveLine.y2 - origin.y2) > EPSILON
|
||||
const movedStart = Math.abs(moveLine.x1 - origin.x1) > EPSILON || Math.abs(moveLine.y1 - origin.y1) > EPSILON
|
||||
const movedEnd = Math.abs(moveLine.x2 - origin.x2) > EPSILON || Math.abs(moveLine.y2 - origin.y2) > EPSILON
|
||||
|
||||
const fullyMoved = movedStart && movedEnd
|
||||
const fullyMoved = movedStart && movedEnd
|
||||
|
||||
|
||||
|
||||
//반시계 방향
|
||||
let newPStart //= {x:roofLine.x1, y:roofLine.y1}
|
||||
let newPEnd //= {x:movedLines.x2, y:movedLines.y2}
|
||||
|
||||
//현재 roof는 무조건 시계방향
|
||||
|
||||
//두 포인트가 변경된 라인인
|
||||
if (fullyMoved) {
|
||||
movedLines.push({ index, moveLine })
|
||||
//반시계방향향
|
||||
newPStart = {x:roofLine.x1, y:roofLine.y1}
|
||||
newPEnd = {x:roofLine.x2, y:roofLine.y2}
|
||||
|
||||
|
||||
|
||||
const p1roofLine = findClosestRoofLine(roofLine.startPoint,sortedRoofLines)
|
||||
const p2roofLine = findClosestRoofLine(roofLine.endPoint,sortedRoofLines)
|
||||
const p1currentRoofLine = findClosestRoofLine(currentRoofLine.startPoint,sortedCurrentRoofLines)
|
||||
const p2currentRoofLine = findClosestRoofLine(currentRoofLine.endPoint,sortedCurrentRoofLines)
|
||||
const p1moveLine = findClosestRoofLine(moveLine.startPoint,sortedWallBaseLines)
|
||||
const p2moveLine = findClosestRoofLine(moveLine.endPoint,sortedWallBaseLines)
|
||||
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
|
||||
|
||||
console.log('::::::',p1roofLine, p2roofLine, p1currentRoofLine, p2currentRoofLine, p1moveLine, p2moveLine)
|
||||
if(getOrientation(roofLine) === 'vertical'){
|
||||
|
||||
let testLine = new QLine([moveLine.x1, moveLine.y1, moveLine.x2, moveLine.y2], {
|
||||
if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1){
|
||||
newPStart.y = wallBaseLine.y1;
|
||||
} else if(wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y){
|
||||
newPEnd.y = wallBaseLine.y2;
|
||||
} else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2){
|
||||
newPEnd.y = wallBaseLine.y2;
|
||||
} else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y){
|
||||
newPStart.y = wallBaseLine.y1;
|
||||
}
|
||||
|
||||
|
||||
}else if(getOrientation(roofLine) === 'horizontal') {
|
||||
|
||||
|
||||
if(newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPStart.x && newPStart.x <= wallBaseLine.x1){
|
||||
newPStart.x = wallBaseLine.x1;
|
||||
} else if(wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x){
|
||||
newPEnd.x = wallBaseLine.x2;
|
||||
} else if(newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPEnd.x && newPEnd.x <= wallBaseLine.x2){
|
||||
newPEnd.x = wallBaseLine.x2;
|
||||
} else if(wallBaseLine.x1 <= newPStart.x && newPStart.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPEnd.x){
|
||||
newPStart.x = wallBaseLine.x1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
movedLines.push({ index, newPStart, newPEnd })
|
||||
let testLine = new QLine([newPStart.x, newPStart.y, newPEnd.x, newPEnd.y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 10,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
lineName: 'helpLine',
|
||||
roofId: roofId,
|
||||
parentId: roof.id,
|
||||
});
|
||||
canvas.add(testLine)
|
||||
|
||||
}
|
||||
|
||||
else if(movedStart) { //end 변경경
|
||||
|
||||
|
||||
newPStart = {x:roofLine.x1, y:roofLine.y1}
|
||||
|
||||
if(getOrientation(roofLine) === 'vertical'){
|
||||
|
||||
let isCross = false
|
||||
if(Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1){
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
|
||||
newPEnd = {x:roofLine.x1, y:(isCross)? currentRoofLine.y2:origin.y1}
|
||||
|
||||
}else if(getOrientation(roofLine) === 'horizontal') {
|
||||
|
||||
let isCross = false
|
||||
if(Math.abs(currentRoofLine.y1 - roofLine.y2) < 0.1 || Math.abs(currentRoofLine.y2 - roofLine.y1) < 0.1){
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
newPEnd = {x:(isCross)? currentRoofLine.x2:origin.x1, y:roofLine.y1} //수직라인 접점까지지
|
||||
|
||||
}
|
||||
|
||||
movedLines.push({ index, newPStart, newPEnd })
|
||||
console.log("moveStart:::::::::::::", origin, newPStart, newPEnd)
|
||||
|
||||
let testLine = new QLine([newPStart.x, newPStart.y, newPEnd.x, newPEnd.y], {
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 10,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
lineName: 'helpLine',
|
||||
roofId: roofId,
|
||||
parentId: roof.id,
|
||||
});
|
||||
let testLine2 = new QLine([roofLine.x1, roofLine.y1, roofLine.x2, roofLine.y2], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 10,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
});
|
||||
let testLine3 = new QLine([currentRoofLine.x1, currentRoofLine.y1, currentRoofLine.x2, currentRoofLine.y2], {
|
||||
canvas.add(testLine)
|
||||
|
||||
|
||||
}else if(movedEnd) { //start변경
|
||||
|
||||
//반시계방향
|
||||
newPStart = {x:roofLine.x2, y:roofLine.y2}
|
||||
|
||||
if(getOrientation(roofLine) === 'vertical'){
|
||||
|
||||
let isCross = false
|
||||
if(Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1){
|
||||
isCross = true;
|
||||
}
|
||||
newPEnd = {x:roofLine.x2, y:(isCross)? currentRoofLine.y1:origin.y2} //수직라인 접점까지지
|
||||
|
||||
}else if(getOrientation(roofLine) === 'horizontal') {
|
||||
|
||||
let isCross = false
|
||||
if(Math.abs(currentRoofLine.y2 - roofLine.y1) < 0.1 || Math.abs(currentRoofLine.y1 - roofLine.y2) < 0.1){
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
newPEnd = {x:(isCross)? currentRoofLine.x1:origin.x2, y:roofLine.y2} //수직라인 접점까지지
|
||||
|
||||
}
|
||||
console.log("movedEnd:::::::::::::", origin, newPStart, newPEnd)
|
||||
let testLine = new QLine([newPStart.x, newPStart.y, newPEnd.x, newPEnd.y], {
|
||||
stroke: 'orange',
|
||||
strokeWidth: 10,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
lineName: 'helpLine',
|
||||
roofId:roofId,
|
||||
parentId: roof.id,
|
||||
|
||||
});
|
||||
canvas.add(testLine)
|
||||
canvas.add(testLine2)
|
||||
canvas.add(testLine3)
|
||||
movedLines.push({ index, newPStart, newPEnd })
|
||||
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
canvas.renderAll()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
//polygon 만들기
|
||||
console.log("innerLines:::::", innerLines)
|
||||
console.log("movedLines", movedLines)
|
||||
|
||||
// --- 사용 예시 ---
|
||||
const polygons = findConnectedLines(movedLines, innerLines, canvas, roofId, roof);
|
||||
console.log("polygon", polygons);
|
||||
canvas.renderAll
|
||||
return innerLines;
|
||||
}
|
||||
/*
|
||||
@ -799,6 +922,7 @@ const fullyMoved = movedStart && movedEnd
|
||||
|
||||
return Math.sign(area2) // +1: CCW, -1: CW, 0: 불명
|
||||
}
|
||||
|
||||
const lineOrientation = (line, polygonOrientation) => {
|
||||
const x1 = line.get('x1')
|
||||
const y1 = line.get('y1')
|
||||
@ -3716,3 +3840,123 @@ const getOrientation = (line, eps = 0.1) => {
|
||||
if (dx < eps && dy < eps) return 'point'
|
||||
return 'diagonal'
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 선분이 교차하는지 확인하는 헬퍼 함수
|
||||
* (끝점이 닿아있는 경우도 교차로 간주)
|
||||
*/
|
||||
function checkIntersection(p1, p2, p3, p4) {
|
||||
// CCW (Counter Clockwise) 알고리즘을 이용한 교차 판별
|
||||
function ccw(a, b, c) {
|
||||
const val = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
|
||||
if (val < 0) return -1;
|
||||
if (val > 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const abc = ccw(p1, p2, p3);
|
||||
const abd = ccw(p1, p2, p4);
|
||||
const cda = ccw(p3, p4, p1);
|
||||
const cdb = ccw(p3, p4, p2);
|
||||
|
||||
// 두 선분이 일직선 상에 있을 때 (겹치는지 확인)
|
||||
if (abc === 0 && abd === 0) {
|
||||
// x축, y축 순서대로 정렬하여 겹침 여부 확인
|
||||
if (p1.x > p2.x || (p1.x === p2.x && p1.y > p2.y)) [p1, p2] = [p2, p1];
|
||||
if (p3.x > p4.x || (p3.x === p4.x && p3.y > p4.y)) [p3, p4] = [p4, p3];
|
||||
return p2.x >= p3.x && p2.y >= p3.y && p4.x >= p1.x && p4.y >= p1.y;
|
||||
}
|
||||
|
||||
return abc * abd <= 0 && cda * cdb <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* aLine의 좌표를 추출하는 함수
|
||||
*/
|
||||
function getACoords(line) {
|
||||
return {
|
||||
start: { x: line.newPStart.x, y: line.newPStart.y },
|
||||
end: { x: line.newPEnd.x, y: line.newPEnd.y }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* bLine의 좌표를 추출하는 함수
|
||||
* (left, top을 시작점으로 보고 width, height를 더해 끝점을 계산)
|
||||
*/
|
||||
function getBCoords(line) {
|
||||
// QLine 데이터 구조상 left/top이 시작점, width/height가 델타값으로 가정
|
||||
return {
|
||||
start: { x: line.left, y: line.top },
|
||||
end: { x: line.left + line.width, y: line.top + line.height }
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 메인 로직 함수
|
||||
* 1. aLines 순회
|
||||
* 2. aLine과 교차하는 bLines 찾기 (Level 1)
|
||||
* 3. 찾은 bLine과 교차하는 또 다른 bLines 찾기 (Level 2)
|
||||
*/
|
||||
function findConnectedLines(aLines, bLines, canvas, roofId, roof) {
|
||||
const results = [];
|
||||
|
||||
aLines.forEach(aLine => {
|
||||
const aCoords = getACoords(aLine);
|
||||
const intersections = [];
|
||||
|
||||
// 1단계: aLine과 교차하는 bLines 찾기
|
||||
bLines.forEach(bLine1 => {
|
||||
const bCoords1 = getBCoords(bLine1);
|
||||
|
||||
if (checkIntersection(aCoords.start, aCoords.end, bCoords1.start, bCoords1.end)) {
|
||||
|
||||
// 2단계: 위에서 찾은 bLine1과 교차하는 다른 bLines 찾기
|
||||
const connectedToB1 = [];
|
||||
bLines.forEach(bLine2 => {
|
||||
// 자기 자신은 제외
|
||||
if (bLine1 === bLine2) return;
|
||||
|
||||
const bCoords2 = getBCoords(bLine2);
|
||||
if (checkIntersection(bCoords1.start, bCoords1.end, bCoords2.start, bCoords2.end)) {
|
||||
connectedToB1.push(bLine2);
|
||||
|
||||
let testLine = new QLine([bLine2.x1, bLine2.y1, bLine2.x2, bLine2.y2], {
|
||||
stroke: 'orange',
|
||||
strokeWidth: 10,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
lineName: 'helpLine',
|
||||
roofId:roofId,
|
||||
parentId: roof.id,
|
||||
|
||||
});
|
||||
canvas.add(testLine)
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
intersections.push({
|
||||
targetBLine: bLine1, // aLine과 만난 녀석
|
||||
connectedBLines: connectedToB1 // 그 녀석과 만난 다른 bLines
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// 결과가 있는 경우에만 저장 (필요에 따라 조건 제거 가능)
|
||||
if (intersections.length > 0) {
|
||||
results.push({
|
||||
sourceALine: aLine,
|
||||
intersections: intersections
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user