확장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
|
||||
);
|
||||
|
||||
const mergedEaveLines = processEaveHelpLines(roofEaveHelpLines);
|
||||
// 기존 라인 제거
|
||||
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) {
|
||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||
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];
|
||||
} else {
|
||||
roofBase.lines = [...roofEaveHelpLines];
|
||||
|
||||
@ -810,6 +810,11 @@ if(roof.moveUpDown??0 > 0) {
|
||||
//현재 roof는 무조건 시계방향
|
||||
|
||||
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], {
|
||||
parentId : roof.id,
|
||||
fontSize : roof.fontSize,
|
||||
@ -898,7 +903,7 @@ if(roof.moveUpDown??0 > 0) {
|
||||
}
|
||||
}
|
||||
getAddLine(newPStart, newPEnd, 'red')
|
||||
movedLines.push({ index, newPStart, newPEnd })
|
||||
|
||||
|
||||
} 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)
|
||||
getAddLine(newPStart, newPEnd, 'red')
|
||||
|
||||
@ -956,7 +961,7 @@ if(roof.moveUpDown??0 > 0) {
|
||||
}
|
||||
console.log("movedEnd:::::::::::::", origin, newPStart, newPEnd)
|
||||
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
|
||||
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를 처리하여 내부 스켈레톤 선을 추가합니다.
|
||||
@ -4083,21 +3415,26 @@ function findConnectedLines(aLines, bLines, canvas, roofId, roof) {
|
||||
export const processEaveHelpLines = (lines) => {
|
||||
if (!lines || lines.length === 0) return [];
|
||||
|
||||
// 수직/수평 라인 분류
|
||||
const verticalLines = lines.filter(line => line.x1 === line.x2);
|
||||
const horizontalLines = lines.filter(line => line.y1 === line.y2);
|
||||
// 수직/수평 라인 분류 (부동소수점 오차 고려)
|
||||
const verticalLines = lines.filter(line => Math.abs(line.x1 - line.x2) < 0.1);
|
||||
const horizontalLines = lines.filter(line => Math.abs(line.y1 - line.y2) < 0.1);
|
||||
|
||||
// 라인 정렬 및 병합
|
||||
// 라인 병합 (더 엄격한 조건으로)
|
||||
const mergedVertical = mergeLines(verticalLines, 'vertical');
|
||||
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];
|
||||
};
|
||||
|
||||
const mergeLines = (lines, direction) => {
|
||||
if (lines.length < 2) return lines;
|
||||
if (!lines || lines.length < 2) return lines || [];
|
||||
|
||||
// 방향에 따라 정렬
|
||||
// 방향에 따라 정렬 (수직: y1 기준, 수평: x1 기준)
|
||||
lines.sort((a, b) => {
|
||||
const aPos = direction === 'vertical' ? a.y1 : a.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++) {
|
||||
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.x2 = direction === 'vertical' ? current.x1 : current.x2;
|
||||
@ -4123,6 +3467,93 @@ const mergeLines = (lines, direction) => {
|
||||
}
|
||||
}
|
||||
merged.push(current);
|
||||
|
||||
// 병합 결과 로그
|
||||
console.log(`Merged ${direction} lines:`, 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