확장1
This commit is contained in:
parent
89a6787aee
commit
e20892188a
@ -411,37 +411,14 @@ export function useRoofAllocationSetting(id) {
|
|||||||
obj.name === 'eaveHelpLine' && obj.roofId === roofBase.id
|
obj.name === 'eaveHelpLine' && obj.roofId === roofBase.id
|
||||||
);
|
);
|
||||||
|
|
||||||
const mergedEaveLines = processEaveHelpLines(roofEaveHelpLines);
|
|
||||||
// 기존 라인 제거
|
// 기존 라인 제거
|
||||||
roofEaveHelpLines.forEach(line => canvas.remove(line));
|
roofEaveHelpLines.forEach(line => canvas.remove(line));
|
||||||
|
|
||||||
mergedEaveLines.forEach(line => {
|
|
||||||
const newLine = new QLine([line.x1, line.y1, line.x2, line.y2], {
|
|
||||||
// 필요한 속성들 유지
|
|
||||||
parentId : roofBase.id,
|
|
||||||
fontSize : 10,
|
|
||||||
stroke : 'blue',
|
|
||||||
strokeWidth: 4,
|
|
||||||
name : 'eaveHelpLine',
|
|
||||||
lineName : 'eaveHelpLine',
|
|
||||||
selectable : true,
|
|
||||||
visible : true,
|
|
||||||
roofId : roofBase.id,
|
|
||||||
attributes : {
|
|
||||||
type: 'eaveHelpLine'
|
|
||||||
}
|
|
||||||
// 기타 속성들...
|
|
||||||
});
|
|
||||||
canvas.add(newLine);
|
|
||||||
});
|
|
||||||
|
|
||||||
canvas.renderAll();
|
|
||||||
|
|
||||||
|
|
||||||
if (roofBase.lines) {
|
if (roofBase.lines) {
|
||||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||||
const existingEaveLineIds = new Set(roofBase.lines.map(line => line.id));
|
const existingEaveLineIds = new Set(roofBase.lines.map(line => line.id));
|
||||||
const newEaveLines = mergedEaveLines.filter(line => !existingEaveLineIds.has(line.id));
|
const newEaveLines = roofEaveHelpLines.filter(line => !existingEaveLineIds.has(line.id));
|
||||||
roofBase.lines = [...roofBase.lines, ...newEaveLines];
|
roofBase.lines = [...roofBase.lines, ...newEaveLines];
|
||||||
} else {
|
} else {
|
||||||
roofBase.lines = [...roofEaveHelpLines];
|
roofBase.lines = [...roofEaveHelpLines];
|
||||||
|
|||||||
@ -810,6 +810,11 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
//현재 roof는 무조건 시계방향
|
//현재 roof는 무조건 시계방향
|
||||||
|
|
||||||
const getAddLine = (p1, p2, stroke = '#1083E3') => {
|
const getAddLine = (p1, p2, stroke = '#1083E3') => {
|
||||||
|
movedLines.push({ index, p1, p2 })
|
||||||
|
|
||||||
|
// Usage:
|
||||||
|
let mergeLines = mergeMovedLines(movedLines);
|
||||||
|
console.log("mergeLines:::::::", mergeLines);
|
||||||
const line = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
const line = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
||||||
parentId : roof.id,
|
parentId : roof.id,
|
||||||
fontSize : roof.fontSize,
|
fontSize : roof.fontSize,
|
||||||
@ -898,7 +903,7 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
getAddLine(newPStart, newPEnd, 'red')
|
getAddLine(newPStart, newPEnd, 'red')
|
||||||
movedLines.push({ index, newPStart, newPEnd })
|
|
||||||
|
|
||||||
} else if (movedStart) { //end 변경경
|
} else if (movedStart) { //end 변경경
|
||||||
|
|
||||||
@ -926,7 +931,7 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
movedLines.push({ index, newPStart, newPEnd })
|
//movedLines.push({ index, newPStart, newPEnd })
|
||||||
console.log("moveStart:::::::::::::", origin, newPStart, newPEnd)
|
console.log("moveStart:::::::::::::", origin, newPStart, newPEnd)
|
||||||
getAddLine(newPStart, newPEnd, 'red')
|
getAddLine(newPStart, newPEnd, 'red')
|
||||||
|
|
||||||
@ -956,7 +961,7 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
}
|
}
|
||||||
console.log("movedEnd:::::::::::::", origin, newPStart, newPEnd)
|
console.log("movedEnd:::::::::::::", origin, newPStart, newPEnd)
|
||||||
getAddLine(newPStart, newPEnd, 'orange')
|
getAddLine(newPStart, newPEnd, 'orange')
|
||||||
movedLines.push({ index, newPStart, newPEnd })
|
//movedLines.push({ index, newPStart, newPEnd })
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,679 +980,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
// canvas.renderAll
|
// canvas.renderAll
|
||||||
return innerLines;
|
return innerLines;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
let p1,p2,p3, p4
|
|
||||||
let idx = 0;
|
|
||||||
let isMoveLine = false;
|
|
||||||
|
|
||||||
if (wallLine.startPoint.x !== wallLine.x1) wallLine.startPoint.x = wallLine.x1
|
|
||||||
if (wallLine.startPoint.y !== wallLine.y1) wallLine.startPoint.y = wallLine.y1
|
|
||||||
if (wallLine.endPoint.x !== wallLine.x2) wallLine.endPoint.x = wallLine.x2
|
|
||||||
if (wallLine.endPoint.y !== wallLine.y2) wallLine.endPoint.y = wallLine.y2
|
|
||||||
|
|
||||||
const wallLineStartPoint = {x:wallLine.x1, y:wallLine.y1}
|
|
||||||
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
|
||||||
const moveLine = wall.baseLines[index] //이동한 wall 존재여부 (초기 wall line = base line)
|
|
||||||
|
|
||||||
if(index === 2){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// // 사용자가 라인을 드래그하기 시작할 때
|
|
||||||
// baseLine.on('moving', () => {
|
|
||||||
// baseLine.attributes.isUserMoved = true
|
|
||||||
// })
|
|
||||||
|
|
||||||
// 판별할 때
|
|
||||||
// const movedLines = wall.baseLines
|
|
||||||
// .map((line, index) => ({ index, line }))
|
|
||||||
// .filter(({ line }) => line.attributes.isUserMoved)
|
|
||||||
|
|
||||||
|
|
||||||
// Then in your code:
|
|
||||||
|
|
||||||
if (!moveLine?.attributes?.originPoint) return
|
|
||||||
|
|
||||||
const { originPoint } = moveLine.attributes
|
|
||||||
const moved =
|
|
||||||
(Math.abs(moveLine.x1 - originPoint.x1) > 0.1 ||
|
|
||||||
Math.abs(moveLine.y1 - originPoint.y1) > 0.1 )||(
|
|
||||||
Math.abs(moveLine.x2 - originPoint.x2) > 0.1 ||
|
|
||||||
Math.abs(moveLine.y2 - originPoint.y2) > 0.1)
|
|
||||||
|
|
||||||
if (moved) {
|
|
||||||
|
|
||||||
const p1moveLine = findClosestRoofLine(moveLine.startPoint, currentRoofLines)
|
|
||||||
const p2moveLine = findClosestRoofLine(moveLine.endPoint, currentRoofLines)
|
|
||||||
const p1RoofLine = findClosestRoofLine(currentRoofLine.startPoint,roof.lines)
|
|
||||||
const p2RoofLine = findClosestRoofLine(currentRoofLine.endPoint,roof.lines)
|
|
||||||
|
|
||||||
const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines)
|
|
||||||
const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getPolygonOrientation = baseLines => {
|
|
||||||
if (!baseLines?.length) return 0
|
|
||||||
|
|
||||||
const area2 = baseLines.reduce((sum, line) => {
|
|
||||||
const x1 = line.get('x1')
|
|
||||||
const y1 = line.get('y1')
|
|
||||||
const x2 = line.get('x2')
|
|
||||||
const y2 = line.get('y2')
|
|
||||||
return sum + (x2 - x1) * (y2 + y1) // shoelace 변형
|
|
||||||
}, 0)
|
|
||||||
|
|
||||||
return Math.sign(area2) // +1: CCW, -1: CW, 0: 불명
|
|
||||||
}
|
|
||||||
|
|
||||||
const lineOrientation = (line, polygonOrientation) => {
|
|
||||||
const x1 = line.get('x1')
|
|
||||||
const y1 = line.get('y1')
|
|
||||||
const x2 = line.get('x2')
|
|
||||||
const y2 = line.get('y2')
|
|
||||||
const cross = (x2 - x1) * (y2 + y1) // shoelace 기여
|
|
||||||
const sameDirection = Math.sign(cross) === polygonOrientation
|
|
||||||
return sameDirection ? 'up' : 'down'
|
|
||||||
}
|
|
||||||
|
|
||||||
const polygonOrientation = getPolygonOrientation(wall.baseLines)
|
|
||||||
|
|
||||||
|
|
||||||
movedLines.push({
|
|
||||||
index,
|
|
||||||
wallLine,
|
|
||||||
moveLine,
|
|
||||||
coords: {
|
|
||||||
x1: moveLine.get('x1'),
|
|
||||||
y1: moveLine.get('y1'),
|
|
||||||
x2: moveLine.get('x2'),
|
|
||||||
y2: moveLine.get('y2'),
|
|
||||||
},
|
|
||||||
orientation: getOrientation(moveLine), // 'vertical' / 'horizontal' / ...
|
|
||||||
direction: lineOrientation(moveLine, polygonOrientation), // 'up = right' or 'down = left'
|
|
||||||
})
|
|
||||||
// 기존 로직도 이어서 실행
|
|
||||||
console.log("moveLine", movedLines)
|
|
||||||
|
|
||||||
|
|
||||||
movedLines.forEach(({ index, moveLine, wallLine }) => {
|
|
||||||
console.log(`사용자가 움직인 선 index: ${index}, wallLineId: ${wallLine.id}`)
|
|
||||||
// 여기에서만 보조선, 텍스트, highlight 등 수행
|
|
||||||
})
|
|
||||||
|
|
||||||
const EPS = 0.1
|
|
||||||
|
|
||||||
const shareEndpoint = (a, b, eps = 0.1) => {
|
|
||||||
const same = (ax, ay, bx, by) => Math.hypot(ax - bx, ay - by) < eps
|
|
||||||
return (
|
|
||||||
same(a.x1, a.y1, b.x1, b.y1) ||
|
|
||||||
same(a.x1, a.y1, b.x2, b.y2) ||
|
|
||||||
same(a.x2, a.y2, b.x1, b.y1) ||
|
|
||||||
same(a.x2, a.y2, b.x2, b.y2)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const angleBetween = a => b => {
|
|
||||||
const va = { x: a.x2 - a.x1, y: a.y2 - a.y1 }
|
|
||||||
const vb = { x: b.x2 - b.x1, y: b.y2 - b.y1 }
|
|
||||||
const dot = va.x * vb.x + va.y * vb.y
|
|
||||||
const mag = Math.hypot(va.x, va.y) * Math.hypot(vb.x, vb.y)
|
|
||||||
return Math.acos(Math.min(Math.max(dot / mag, -1), 1)) * 180 / Math.PI
|
|
||||||
}
|
|
||||||
|
|
||||||
const rightAngles = []
|
|
||||||
movedLines.forEach((a, i) => {
|
|
||||||
movedLines.slice(i + 1).forEach(b => {
|
|
||||||
if (!shareEndpoint(a.coords, b.coords)) return
|
|
||||||
const angle = angleBetween(a.coords)(b.coords)
|
|
||||||
if (Math.abs(angle - 90) < 2) rightAngles.push({ a, b, angle })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
if(rightAngles.length > 0){
|
|
||||||
let testLine = new QLine([rightAngles[0].x1, rightAngles[0].y1, rightAngles[0].x2, rightAngles[0].y2], {
|
|
||||||
stroke: 'yellow',
|
|
||||||
strokeWidth: 10,
|
|
||||||
property: 'normal',
|
|
||||||
fontSize: 14,
|
|
||||||
});
|
|
||||||
canvas.add(testLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
// movedLines => [{ line: moveLineObj, index }, ...] : 이동된 것만 담김
|
|
||||||
|
|
||||||
if (moved) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(isMoveLine){
|
|
||||||
//wallLine 의 index는 맨 왼쪽 부터 0으로 변경
|
|
||||||
|
|
||||||
const roofIndex = (wallLine.idx === 0)? wall.lines.length : wallLine.idx //(0-6, 1-1, 2-2, 3-3
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const roofLines = canvas.getObjects().filter(obj => obj.name === 'roof' && obj.id === roofId).map(obj => obj.lines).flat();
|
|
||||||
const roofLine = roofLines[roofIndex-1];
|
|
||||||
|
|
||||||
const currentRoofLines = canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => obj.lineName === 'roofLine' && obj.parentId === roofId)
|
|
||||||
|
|
||||||
const currentRoofLine = findClosestParallelLine(roofLine, currentRoofLines);
|
|
||||||
|
|
||||||
const testLine2 = new QLine([roofLine.x1, roofLine.y1, roofLine.x2, roofLine.y2], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 10,
|
|
||||||
property: 'normal',
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
const testLine3 = new QLine([currentRoofLine.x1, currentRoofLine.y1, currentRoofLine.x2, currentRoofLine.y2], {
|
|
||||||
stroke: 'blue',
|
|
||||||
strokeWidth: 10,
|
|
||||||
property: 'normal',
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
//canvas.add(testLine2);
|
|
||||||
canvas.add(testLine);
|
|
||||||
//canvas.add(testLine3);
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//roof 접점
|
|
||||||
const p1RoofLine = findClosestRoofLine(wallLineStartPoint,roof.lines)
|
|
||||||
const p2RoofLine = findClosestRoofLine(wallLineEndPoint,roof.lines)
|
|
||||||
//wall 접점
|
|
||||||
const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines)
|
|
||||||
const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines)
|
|
||||||
//move 접점
|
|
||||||
|
|
||||||
//wall move 접점
|
|
||||||
const p1outerLine = findClosestRoofLine(wallLineStartPoint, currentRoofLines)
|
|
||||||
const p2outerLine = findClosestRoofLine(wallLineEndPoint, currentRoofLines)
|
|
||||||
|
|
||||||
|
|
||||||
// console.log("p1RoofLineV",p1RoofLine)
|
|
||||||
// console.log("p2RoofLineV",p2RoofLine)
|
|
||||||
// console.log("p1wallLineV",p1wallLine)
|
|
||||||
// console.log("p2wallLineV",p2wallLine)
|
|
||||||
// console.log("p1moveLineV",p1moveLine)
|
|
||||||
// console.log("p2moveLineV",p2moveLine)
|
|
||||||
// console.log("p1outerLine",p1outerLine)
|
|
||||||
// console.log("p2outerLine",p2outerLine)
|
|
||||||
// const outerLines= canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.attributes.roofId === roofId)
|
|
||||||
// const outerLine = outerLines[index]
|
|
||||||
// canvas.remove(outerLine)
|
|
||||||
// canvas.renderAll()
|
|
||||||
if(Math.abs(p1moveLine.distance - p1outerLine.distance) < 0.1){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate vectors from moveLine endpoints to wall line
|
|
||||||
const v1 = {x: wallLine.x1 - moveLine.x1, y: wallLine.y1 - moveLine.y1};
|
|
||||||
const v2 = {x: wallLine.x2 - moveLine.x1, y: wallLine.y2 - moveLine.y1};
|
|
||||||
const v3 = {x: wallLine.x1 - moveLine.x2, y: wallLine.y1 - moveLine.y2};
|
|
||||||
const v4 = {x: wallLine.x2 - moveLine.x2, y: wallLine.y2 - moveLine.y2};
|
|
||||||
|
|
||||||
// Calculate dot products
|
|
||||||
const dot1 = v1.x * v2.x + v1.y * v2.y; // For start point
|
|
||||||
const dot2 = v3.x * v4.x + v3.y * v4.y; // For end point
|
|
||||||
|
|
||||||
const angles = [];
|
|
||||||
// Check right angles with tolerance
|
|
||||||
if (Math.abs(dot1) < 0.1) {
|
|
||||||
angles.push({
|
|
||||||
wall: wall,
|
|
||||||
endpoint: 'start',
|
|
||||||
point: {x: moveLine.x1, y: moveLine.y1}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (Math.abs(dot2) < 0.1) {
|
|
||||||
angles.push({
|
|
||||||
wall: wall,
|
|
||||||
endpoint: 'end',
|
|
||||||
point: {x: moveLine.x2, y: moveLine.y2}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("angels::::::::", angles)
|
|
||||||
|
|
||||||
// currentOuterLines.forEach((line) => {
|
|
||||||
// line.set('stroke', 'green') // 원하는 색으로 변경
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// if (currentOuterLines.length > 0) {
|
|
||||||
// canvas.requestRenderAll()
|
|
||||||
// }
|
|
||||||
// const candidates = canvas.getObjects().filter((obj) => obj.roofId === roofId)
|
|
||||||
// console.log('candidates', candidates.map((obj) => obj.lineName))
|
|
||||||
|
|
||||||
const addHelpLine = (roofLine, wallLine, outerLineA, outerLineB = null) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLineStartPoint = {x:roofLine.x1, y:roofLine.y1}
|
|
||||||
const roofLineEndPoint = {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const wallLineStartPoint = {x:wallLine.x1, y:wallLine.y1}
|
|
||||||
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
|
||||||
const isVertical = wallLineStartPoint.x === wallLineEndPoint.x;
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
if(isVertical){
|
|
||||||
newP1 = roofLineStartPoint
|
|
||||||
newP3 = wallLineStartPoint
|
|
||||||
newP2 = {x:newP1.x, y: newP3.y}
|
|
||||||
newP4 = {x:Math.abs(outerLineA?.intersectionPoint.y - newP1.y) < 0.1 ? outerLineA?.intersectionPoint.x : newP3.x, y:newP1.y}
|
|
||||||
}else{
|
|
||||||
newP1 = roofLineStartPoint
|
|
||||||
newP3 = wallLineStartPoint
|
|
||||||
newP2 = {x:newP3.x, y: newP1.y}
|
|
||||||
newP4 = {x:newP1.x, y: (Math.abs(outerLineA?.intersectionPoint.x - newP1.x) < 0.1) ? outerLineA?.intersectionPoint.y : newP3.y}
|
|
||||||
|
|
||||||
}
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addHelpLine2 = (roofLine, wallLine, outerLineA, outerLineB=null) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLineStartPoint = {x:roofLine.x1, y:roofLine.y1}
|
|
||||||
const roofLineEndPoint = {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const wallLineStartPoint = {x:wallLine.x1, y:wallLine.y1}
|
|
||||||
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
|
||||||
const isVertical = wallLineStartPoint.x === wallLineEndPoint.x;
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
if(isVertical){
|
|
||||||
newP1 = roofLineEndPoint
|
|
||||||
newP3 = wallLineEndPoint
|
|
||||||
newP2 = {x:newP1.x, y: newP3.y}
|
|
||||||
newP4 = {x:Math.abs(outerLineB?.intersectionPoint.y - newP1.y) < 0.1 ? outerLineB?.intersectionPoint.x : newP3.x, y:newP1.y}
|
|
||||||
}else{
|
|
||||||
newP1 = roofLineEndPoint
|
|
||||||
newP3 = wallLineEndPoint
|
|
||||||
newP2 = {x:newP3.x, y: newP1.y}
|
|
||||||
newP4 = {x:newP1.x, y: (Math.abs(outerLineB?.intersectionPoint.x - newP1.x) < 0.1) ? outerLineB?.intersectionPoint.y : newP3.y}
|
|
||||||
|
|
||||||
}
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addHelpLineBottom = (roofLine, wallLine, moveLine, outerLine, target) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLinePoint = (target === 'S') ? {x:roofLine.x1, y:roofLine.y1} : {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const moveLinePoint = (target === 'S') ? {x:moveLine.x1, y:moveLine.y1} : {x:moveLine.x2, y:moveLine.y2}
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
|
|
||||||
newP1 = roofLinePoint
|
|
||||||
newP3 = moveLinePoint
|
|
||||||
newP2 = {x:newP3.x, y: newP1.y}
|
|
||||||
newP4 = {x:newP1.x, y: (Math.abs(outerLine?.intersectionPoint.x - newP1.x) < 0.1) ? outerLine?.intersectionPoint.y : newP3.y}
|
|
||||||
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addHelpLineTop = (roofLine, wallLine, moveLine, outerLine, target) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLinePoint = (target === 'S') ? {x:roofLine.x1, y:roofLine.y1} : {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const moveLinePoint = (target === 'S') ? {x:moveLine.x1, y:moveLine.y1} : {x:moveLine.x2, y:moveLine.y2}
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
|
|
||||||
newP1 = roofLinePoint
|
|
||||||
newP3 = moveLinePoint
|
|
||||||
newP2 = {x:newP3.x, y: newP1.y}
|
|
||||||
newP4 = {x:newP1.x, y: (Math.abs(outerLine?.intersectionPoint.x - newP1.x) < 0.1) ? outerLine?.intersectionPoint.y : newP3.y}
|
|
||||||
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addHelpLineLeft = (roofLine, wallLine, moveLine, outerLine, target) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLinePoint = (target === 'S') ? {x:roofLine.x1, y:roofLine.y1} : {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const moveLinePoint = (target === 'S') ? {x:moveLine.x1, y:moveLine.y1} : {x:moveLine.x2, y:moveLine.y2}
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
|
|
||||||
newP1 = roofLinePoint
|
|
||||||
newP3 = moveLinePoint
|
|
||||||
newP2 = {x:newP1.x, y: newP3.y}
|
|
||||||
newP4 = {x:Math.abs(outerLine?.intersectionPoint.y - newP1.y) < 0.1 ? outerLine?.intersectionPoint.x : newP3.x, y:newP1.y}
|
|
||||||
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addHelpLineRight = (roofLine, wallLine, moveLine, outerLine, target) => {
|
|
||||||
//반시계방향
|
|
||||||
const roofLinePoint = (target === 'S') ? {x:roofLine.x1, y:roofLine.y1} : {x:roofLine.x2, y:roofLine.y2}
|
|
||||||
const moveLinePoint = (target === 'S') ? {x:moveLine.x1, y:moveLine.y1} : {x:moveLine.x2, y:moveLine.y2}
|
|
||||||
|
|
||||||
let newP1, newP2, newP3, newP4;
|
|
||||||
|
|
||||||
newP1 = roofLinePoint
|
|
||||||
newP3 = moveLinePoint
|
|
||||||
newP2 = {x:newP1.x, y: newP3.y}
|
|
||||||
newP4 = {x:Math.abs(outerLine?.intersectionPoint.y - newP1.y) < 0.1 ? outerLine?.intersectionPoint.x : newP3.x, y:newP1.y}
|
|
||||||
|
|
||||||
return {newP1, newP2, newP3, newP4}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
let isPolygon;
|
|
||||||
|
|
||||||
// Calculate the movement direction
|
|
||||||
const dx1 = wallLine.x1 - moveLine.x1;
|
|
||||||
const dy1 = wallLine.y1 - moveLine.y1;
|
|
||||||
const dx2 = wallLine.x2 - moveLine.x2;
|
|
||||||
const dy2 = wallLine.y2 - moveLine.y2;
|
|
||||||
|
|
||||||
// Determine movement direction
|
|
||||||
let moveDirection = 'none';
|
|
||||||
|
|
||||||
// Check if it's a vertical wall line (x coordinates are equal)
|
|
||||||
if (Math.abs(wallLine.x1 - wallLine.x2) < 0.1) {
|
|
||||||
// For vertical lines, check x movement
|
|
||||||
if (dx1 > 0 || dx2 > 0) {
|
|
||||||
moveDirection = 'left';
|
|
||||||
} else if (dx1 < 0 || dx2 < 0) {
|
|
||||||
moveDirection = 'right';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check if it's a horizontal wall line (y coordinates are equal)
|
|
||||||
else if (Math.abs(wallLine.y1 - wallLine.y2) < 0.1) {
|
|
||||||
// For horizontal lines, check y movement
|
|
||||||
if (dy1 > 0 || dy2 > 0) {
|
|
||||||
moveDirection = 'top';
|
|
||||||
} else if (dy1 < 0 || dy2 < 0) {
|
|
||||||
moveDirection = 'bottom';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`Wall line moved ${moveDirection}`);
|
|
||||||
|
|
||||||
|
|
||||||
let changeLine
|
|
||||||
switch (moveDirection) {
|
|
||||||
case 'left':
|
|
||||||
// Handle left movement
|
|
||||||
if(p1moveLine.distance > p2moveLine.distance) {
|
|
||||||
changeLine = addHelpLineLeft(roofLine, wallLine, moveLine, p1moveLine, 'S')
|
|
||||||
|
|
||||||
console.log('p1moveLine.distance', p1moveLine.distance);
|
|
||||||
}else{
|
|
||||||
changeLine = addHelpLineLeft(roofLine, wallLine, moveLine, p2moveLine, 'E')
|
|
||||||
console.log('p2moveLine.distance', p2moveLine.distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
|
|
||||||
isPolygon = true
|
|
||||||
// const testLine2 = new QLine([wallLine.x1, wallLine.y1, wallLine.x2, wallLine.y2], {
|
|
||||||
// stroke: 'red',
|
|
||||||
// strokeWidth: 10,
|
|
||||||
// property: 'normal',
|
|
||||||
// fontSize: 14,
|
|
||||||
// })
|
|
||||||
// const testLine = new QLine([moveLine.x1, moveLine.y1, moveLine.x2, moveLine.y2], {
|
|
||||||
// stroke: 'yellow',
|
|
||||||
// strokeWidth: 10,
|
|
||||||
// property: 'normal',
|
|
||||||
// fontSize: 14,
|
|
||||||
// })
|
|
||||||
// canvas.add(testLine2);
|
|
||||||
// canvas.add(testLine);
|
|
||||||
// canvas.renderAll()
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'right':
|
|
||||||
|
|
||||||
if(p1moveLine.distance > p2moveLine.distance) {
|
|
||||||
changeLine = addHelpLineRight(roofLine, wallLine, moveLine, p1moveLine, 'S')
|
|
||||||
|
|
||||||
console.log('p1moveLine.distance', p1moveLine.distance);
|
|
||||||
}else{
|
|
||||||
changeLine = addHelpLineRight(roofLine, wallLine, moveLine, p2moveLine, 'E')
|
|
||||||
console.log('p2moveLine.distance', p2moveLine.distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
|
|
||||||
isPolygon = true
|
|
||||||
break;
|
|
||||||
case 'top':
|
|
||||||
// Handle upward movement
|
|
||||||
if(p1moveLine.distance > p2moveLine.distance) {
|
|
||||||
changeLine = addHelpLineTop(roofLine, wallLine, moveLine, p1moveLine, 'S')
|
|
||||||
console.log('p1moveLine.distance', p1moveLine.distance);
|
|
||||||
}else{
|
|
||||||
changeLine = addHelpLineTop(roofLine, wallLine, moveLine, p2moveLine, 'E')
|
|
||||||
console.log('p2moveLine.distance', p2moveLine.distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
|
|
||||||
isPolygon = true
|
|
||||||
break;
|
|
||||||
case 'bottom':
|
|
||||||
// Handle downward movement
|
|
||||||
if(p1moveLine.distance > p2moveLine.distance) {
|
|
||||||
changeLine = addHelpLineBottom(roofLine, wallLine, moveLine, p1moveLine, 'S')
|
|
||||||
console.log('p1moveLine.distance', p1moveLine.distance);
|
|
||||||
}else{
|
|
||||||
changeLine = addHelpLineBottom(roofLine, wallLine, moveLine, p2moveLine, 'E')
|
|
||||||
console.log('p2moveLine.distance', p2moveLine.distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
|
|
||||||
isPolygon = true
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// No movement or movement is too small to detect
|
|
||||||
isPolygon = false
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`Wall line moved ${moveDirection}`);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
if(p1wallLine.distance > 0 && p2wallLine.distance === 0) {
|
|
||||||
|
|
||||||
console.log("왼쪽 수평 / 오른쪽 수직")
|
|
||||||
const changeLine = addHelpLine(roofLine, wallLine, p1outerLine, p2outerLine)
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
|
|
||||||
isPolygon = true
|
|
||||||
|
|
||||||
|
|
||||||
}else if(p2wallLine.distance > 0 && p1wallLine.distance === 0) {
|
|
||||||
console.log("오른쪽 수평 / 왼쪽 수직")
|
|
||||||
const changeLine = addHelpLine2(roofLine, wallLine, p1outerLine, p2outerLine)
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
|
|
||||||
canvas.remove(p1outerLine.line)
|
|
||||||
canvas.remove(p2outerLine.line)
|
|
||||||
isPolygon = true
|
|
||||||
}else if(p1wallLine.distance > 0 && p2wallLine.distance > 0) {
|
|
||||||
|
|
||||||
if(p1wallLine.distance > p2wallLine.distance){
|
|
||||||
const changeLine = addHelpLine(roofLine, wallLine, p1outerLine, p2outerLine)
|
|
||||||
console.log("1왼쪽 수평 / 1오른쪽 수직")
|
|
||||||
console.log("1p1wallLine.distance", p1wallLine.distance);
|
|
||||||
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
}else{
|
|
||||||
const changeLine = addHelpLine2(roofLine, wallLine, p1outerLine, p2outerLine)
|
|
||||||
console.log("1오른쪽 수평 / 1왼쪽 수직")
|
|
||||||
console.log("1p2wallLine.distance", p2wallLine.distance);
|
|
||||||
p1 = changeLine.newP1
|
|
||||||
p2 = changeLine.newP2
|
|
||||||
p3 = changeLine.newP3
|
|
||||||
p4 = changeLine.newP4
|
|
||||||
}
|
|
||||||
isPolygon = true
|
|
||||||
|
|
||||||
}else {
|
|
||||||
console.log("p1wallLine.distance", p1wallLine.distance);
|
|
||||||
console.log("p2wallLine.distance", p2wallLine.distance);
|
|
||||||
|
|
||||||
isPolygon = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// //targetLines를 p1, p2 로 바꾸고 싶다..
|
|
||||||
// const editLine = (targetLines, p1, p2) => {
|
|
||||||
// targetLines.forEach((line) => {
|
|
||||||
// line.set({
|
|
||||||
// x1: p1.x,
|
|
||||||
// y1: p1.y,
|
|
||||||
// x2: p2.x,
|
|
||||||
// y2: p2.y,
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // QLine은 startPoint/endPoint도 쓰므로 같이 갱신
|
|
||||||
// if (line.startPoint) {
|
|
||||||
// line.startPoint.x = p1.x
|
|
||||||
// line.startPoint.y = p1.y
|
|
||||||
// }
|
|
||||||
// if (line.endPoint) {
|
|
||||||
// line.endPoint.x = p2.x
|
|
||||||
// line.endPoint.y = p2.y
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // originPoint 같은 커스텀 속성을 쓰면 여기도 맞춰줌
|
|
||||||
// if (line.attributes?.originPoint) {
|
|
||||||
// line.attributes.originPoint = { x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// canvas.requestRenderAll()
|
|
||||||
// // 1) 고유 ID로 찾기
|
|
||||||
// const lineToUpdate = targetLines.find((line) => line.id === someLineId)
|
|
||||||
// if (lineToUpdate) { //특정라인인
|
|
||||||
// lineToUpdate.set({
|
|
||||||
// x1: newP1.x,
|
|
||||||
// y1: newP1.y,
|
|
||||||
// x2: newP2.x,
|
|
||||||
// y2: newP2.y,
|
|
||||||
// })
|
|
||||||
// lineToUpdate.startPoint.x = newP1.x
|
|
||||||
// lineToUpdate.startPoint.y = newP1.y
|
|
||||||
// lineToUpdate.endPoint.x = newP2.x
|
|
||||||
// lineToUpdate.endPoint.y = newP2.y
|
|
||||||
// canvas.requestRenderAll()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// const drawPolygon = (p1,p2,p3,p4) => {
|
|
||||||
// const rect = new QPolygon([p1, p2, p3, p4], {
|
|
||||||
// type: POLYGON_TYPE.ROOF,
|
|
||||||
// fill: 'transparent',
|
|
||||||
// stroke: 'black',
|
|
||||||
// strokeWidth: 3,
|
|
||||||
// selectable: false,
|
|
||||||
// evented: false,
|
|
||||||
// name: 'roofLineRect',
|
|
||||||
// roofId: roofId,
|
|
||||||
// })
|
|
||||||
// canvas.add(rect)
|
|
||||||
// canvas.renderAll()
|
|
||||||
// }
|
|
||||||
// if(isPolygon){
|
|
||||||
// drawPolygon( p1,p2,p3, p4)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const wallLine = wall.baseLines[roofLine.idx - 1];
|
|
||||||
|
|
||||||
|
|
||||||
// if(p1RoofLine.distance > p2RoofLine.distance){
|
|
||||||
// p1 = p2RoofLine.line.endPoint //loofLine.startPoint
|
|
||||||
// p3 = p2RoofLine.line.endPoint //wallLine.startPoint
|
|
||||||
// p2 = { x: p1.x, y: p3.y } //x고정, y변동
|
|
||||||
// p4 = { x: p3.x, y: p1.y } //x변동 y고정
|
|
||||||
// }else{
|
|
||||||
// p1 = loofLine.startPoint //loofLine.startPoint
|
|
||||||
// p3 = wallLine.startPoint //wallLine.startPoint
|
|
||||||
// p2 = { x: p3.x, y: p1.y } //x고정, y변동
|
|
||||||
// p4 = { x: p1.x, y: p3.y } //x변동 y고정
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
//wallLine이 baseLine의 위 또는 오른쪽에 있을때
|
|
||||||
|
|
||||||
|
|
||||||
// let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.attributes.roofId === roofId)
|
|
||||||
// outerLines.forEach((outerLine) => {
|
|
||||||
// canvas.remove(outerLine)
|
|
||||||
// canvas.renderAll()
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// return innerLines;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EAVES(처마) Edge를 처리하여 내부 스켈레톤 선을 추가합니다.
|
* EAVES(처마) Edge를 처리하여 내부 스켈레톤 선을 추가합니다.
|
||||||
@ -4083,21 +3415,26 @@ function findConnectedLines(aLines, bLines, canvas, roofId, roof) {
|
|||||||
export const processEaveHelpLines = (lines) => {
|
export const processEaveHelpLines = (lines) => {
|
||||||
if (!lines || lines.length === 0) return [];
|
if (!lines || lines.length === 0) return [];
|
||||||
|
|
||||||
// 수직/수평 라인 분류
|
// 수직/수평 라인 분류 (부동소수점 오차 고려)
|
||||||
const verticalLines = lines.filter(line => line.x1 === line.x2);
|
const verticalLines = lines.filter(line => Math.abs(line.x1 - line.x2) < 0.1);
|
||||||
const horizontalLines = lines.filter(line => line.y1 === line.y2);
|
const horizontalLines = lines.filter(line => Math.abs(line.y1 - line.y2) < 0.1);
|
||||||
|
|
||||||
// 라인 정렬 및 병합
|
// 라인 병합 (더 엄격한 조건으로)
|
||||||
const mergedVertical = mergeLines(verticalLines, 'vertical');
|
const mergedVertical = mergeLines(verticalLines, 'vertical');
|
||||||
const mergedHorizontal = mergeLines(horizontalLines, 'horizontal');
|
const mergedHorizontal = mergeLines(horizontalLines, 'horizontal');
|
||||||
|
|
||||||
|
// 결과 확인용 로그
|
||||||
|
console.log('Original lines:', lines.length);
|
||||||
|
console.log('Merged vertical:', mergedVertical.length);
|
||||||
|
console.log('Merged horizontal:', mergedHorizontal.length);
|
||||||
|
|
||||||
return [...mergedVertical, ...mergedHorizontal];
|
return [...mergedVertical, ...mergedHorizontal];
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergeLines = (lines, direction) => {
|
const mergeLines = (lines, direction) => {
|
||||||
if (lines.length < 2) return lines;
|
if (!lines || lines.length < 2) return lines || [];
|
||||||
|
|
||||||
// 방향에 따라 정렬
|
// 방향에 따라 정렬 (수직: y1 기준, 수평: x1 기준)
|
||||||
lines.sort((a, b) => {
|
lines.sort((a, b) => {
|
||||||
const aPos = direction === 'vertical' ? a.y1 : a.x1;
|
const aPos = direction === 'vertical' ? a.y1 : a.x1;
|
||||||
const bPos = direction === 'vertical' ? b.y1 : b.x1;
|
const bPos = direction === 'vertical' ? b.y1 : b.x1;
|
||||||
@ -4109,11 +3446,18 @@ const mergeLines = (lines, direction) => {
|
|||||||
|
|
||||||
for (let i = 1; i < lines.length; i++) {
|
for (let i = 1; i < lines.length; i++) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
const isConnected = direction === 'vertical'
|
|
||||||
? current.y2 >= line.y1 - 1
|
|
||||||
: current.x2 >= line.x1 - 1;
|
|
||||||
|
|
||||||
if (isConnected) {
|
// 같은 선상에 있는지 확인 (부동소수점 오차 고려)
|
||||||
|
const isSameLine = direction === 'vertical'
|
||||||
|
? Math.abs(current.x1 - line.x1) < 0.1
|
||||||
|
: Math.abs(current.y1 - line.y1) < 0.1;
|
||||||
|
|
||||||
|
// 연결 가능한지 확인 (약간의 겹침 허용)
|
||||||
|
const isConnected = direction === 'vertical'
|
||||||
|
? current.y2 + 0.1 >= line.y1 // 약간의 오차 허용
|
||||||
|
: current.x2 + 0.1 >= line.x1;
|
||||||
|
|
||||||
|
if (isSameLine && isConnected) {
|
||||||
// 라인 병합
|
// 라인 병합
|
||||||
current.y2 = Math.max(current.y2, line.y2);
|
current.y2 = Math.max(current.y2, line.y2);
|
||||||
current.x2 = direction === 'vertical' ? current.x1 : current.x2;
|
current.x2 = direction === 'vertical' ? current.x1 : current.x2;
|
||||||
@ -4123,6 +3467,93 @@ const mergeLines = (lines, direction) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
merged.push(current);
|
merged.push(current);
|
||||||
|
|
||||||
|
// 병합 결과 로그
|
||||||
|
console.log(`Merged ${direction} lines:`, merged);
|
||||||
|
|
||||||
return merged;
|
return merged;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function mergeMovedLines(movedLines) {
|
||||||
|
if (!movedLines || movedLines.length < 2) return movedLines;
|
||||||
|
|
||||||
|
const result = [...movedLines]; // Start with all original lines
|
||||||
|
const processed = new Set();
|
||||||
|
|
||||||
|
// First pass: find and merge connected lines
|
||||||
|
for (let i = 0; i < result.length; i++) {
|
||||||
|
if (processed.has(i)) continue;
|
||||||
|
|
||||||
|
for (let j = i + 1; j < result.length; j++) {
|
||||||
|
if (processed.has(j)) continue;
|
||||||
|
|
||||||
|
const line1 = result[i];
|
||||||
|
const line2 = result[j];
|
||||||
|
|
||||||
|
// Skip if lines are not the same type (vertical/horizontal)
|
||||||
|
const line1Type = getLineType(line1);
|
||||||
|
const line2Type = getLineType(line2);
|
||||||
|
if (line1Type !== line2Type) continue;
|
||||||
|
|
||||||
|
if (areLinesConnected(line1, line2, line1Type)) {
|
||||||
|
// Merge the lines
|
||||||
|
const merged = mergeTwoLines(line1, line2, line1Type);
|
||||||
|
|
||||||
|
// Replace the first line with merged result
|
||||||
|
result[i] = merged;
|
||||||
|
// Mark the second line for removal
|
||||||
|
processed.add(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove processed lines and keep the order
|
||||||
|
return result.filter((_, index) => !processed.has(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLineType(line) {
|
||||||
|
if (Math.abs(line.p1.x - line.p2.x) < 0.1) return 'vertical';
|
||||||
|
if (Math.abs(line.p1.y - line.p2.y) < 0.1) return 'horizontal';
|
||||||
|
return 'other';
|
||||||
|
}
|
||||||
|
|
||||||
|
function areLinesConnected(line1, line2, type) {
|
||||||
|
if (type === 'vertical') {
|
||||||
|
// For vertical lines, check if x coordinates are the same and y ranges overlap
|
||||||
|
return Math.abs(line1.p1.x - line2.p1.x) < 0.1 &&
|
||||||
|
Math.min(line1.p2.y, line2.p2.y) >= Math.max(line1.p1.y, line2.p1.y) - 0.1;
|
||||||
|
} else if (type === 'horizontal') {
|
||||||
|
// For horizontal lines, check if y coordinates are the same and x ranges overlap
|
||||||
|
return Math.abs(line1.p1.y - line2.p1.y) < 0.1 &&
|
||||||
|
Math.min(line1.p2.x, line2.p2.x) >= Math.max(line1.p1.x, line2.p1.x) - 0.1;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeTwoLines(line1, line2, type) {
|
||||||
|
if (type === 'vertical') {
|
||||||
|
return {
|
||||||
|
...line1, // Preserve original properties
|
||||||
|
p1: {
|
||||||
|
x: line1.p1.x,
|
||||||
|
y: Math.min(line1.p1.y, line1.p2.y, line2.p1.y, line2.p2.y)
|
||||||
|
},
|
||||||
|
p2: {
|
||||||
|
x: line1.p1.x,
|
||||||
|
y: Math.max(line1.p1.y, line1.p2.y, line2.p1.y, line2.p2.y)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else { // horizontal
|
||||||
|
return {
|
||||||
|
...line1, // Preserve original properties
|
||||||
|
p1: {
|
||||||
|
x: Math.min(line1.p1.x, line1.p2.x, line2.p1.x, line2.p2.x),
|
||||||
|
y: line1.p1.y
|
||||||
|
},
|
||||||
|
p2: {
|
||||||
|
x: Math.max(line1.p1.x, line1.p2.x, line2.p1.x, line2.p2.x),
|
||||||
|
y: line1.p1.y
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user