sk line angle
This commit is contained in:
parent
9527e6cf0c
commit
b6f6fd7128
@ -431,8 +431,8 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
|
|||||||
*/
|
*/
|
||||||
const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||||
if (!skeleton?.Edges) return []
|
if (!skeleton?.Edges) return []
|
||||||
const roof = canvas?.getObjects().find((object) => object.id === roofId)
|
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
let wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||||
let skeletonLines = []
|
let skeletonLines = []
|
||||||
|
|
||||||
const processedInnerEdges = new Set()
|
const processedInnerEdges = new Set()
|
||||||
@ -513,7 +513,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//벽라인
|
//벽라인
|
||||||
const wallLines = wall.lines
|
const wallLines = wall.lines
|
||||||
|
|
||||||
skeletonLines.forEach(sktLine => {
|
skeletonLines.forEach((sktLine, skIndex) => {
|
||||||
let { p1, p2, attributes, lineStyle } = sktLine;
|
let { p1, p2, attributes, lineStyle } = sktLine;
|
||||||
|
|
||||||
// 중복방지 - 라인을 고유하게 식별할 수 있는 키 생성 (정규화된 좌표로 정렬하여 비교)
|
// 중복방지 - 라인을 고유하게 식별할 수 있는 키 생성 (정규화된 좌표로 정렬하여 비교)
|
||||||
@ -532,6 +532,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
{ x: sktLine.p2.x, y: sktLine.p2.y }
|
{ x: sktLine.p2.x, y: sktLine.p2.y }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//그림을 그릴때 idx 가 필요함 roof는 왼쪽부터 시작됨 - 그림그리는 순서가 필요함
|
||||||
|
|
||||||
const skeletonLine = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
const skeletonLine = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
||||||
parentId: roof.id,
|
parentId: roof.id,
|
||||||
fontSize: roof.fontSize,
|
fontSize: roof.fontSize,
|
||||||
@ -543,7 +545,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
isBaseLine: sktLine.attributes.isOuterEdge,
|
isBaseLine: sktLine.attributes.isOuterEdge,
|
||||||
lineName: (sktLine.attributes.isOuterEdge)?'roofLine': attributes.type,
|
lineName: (sktLine.attributes.isOuterEdge)?'roofLine': attributes.type,
|
||||||
selectable:(!sktLine.attributes.isOuterEdge),
|
selectable:(!sktLine.attributes.isOuterEdge),
|
||||||
roofId: roofId,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -596,11 +598,12 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
//wall.lines 는 기본 벽 라인
|
//wall.lines 는 기본 벽 라인
|
||||||
//wall.baseLine은 움직인라인
|
//wall.baseLine은 움직인라인
|
||||||
|
|
||||||
wall.lines.forEach((wallLine, index) => {
|
wall.lines.forEach((wallLine, index) => {
|
||||||
console.log("wallLine:::::", wallLine, index)
|
console.log("wallLine:::::", wallLine, index)
|
||||||
let p1,p2,p3, p4
|
let p1,p2,p3, p4
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
let isMoveLine = true;
|
let isMoveLine = false;
|
||||||
|
|
||||||
if (wallLine.startPoint.x !== wallLine.x1) wallLine.startPoint.x = wallLine.x1
|
if (wallLine.startPoint.x !== wallLine.x1) wallLine.startPoint.x = wallLine.x1
|
||||||
if (wallLine.startPoint.y !== wallLine.y1) wallLine.startPoint.y = wallLine.y1
|
if (wallLine.startPoint.y !== wallLine.y1) wallLine.startPoint.y = wallLine.y1
|
||||||
@ -611,24 +614,72 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
||||||
const moveLine = wall.baseLines[index] //이동한 wall 존재여부 (초기 wall line = base line)
|
const moveLine = wall.baseLines[index] //이동한 wall 존재여부 (초기 wall line = base line)
|
||||||
|
|
||||||
if(isSamePoint(moveLine.startPoint, wallLineStartPoint) && isSamePoint(moveLine.endPoint, wallLineEndPoint)){
|
|
||||||
console.log("outerLine1:::::", wallLine, idx)
|
|
||||||
isMoveLine = false;
|
|
||||||
|
let testLine = new QLine([moveLine.x1, moveLine.y1, moveLine.x2, moveLine.y2], {
|
||||||
|
stroke: 'yellow',
|
||||||
|
strokeWidth: 10,
|
||||||
|
property: 'normal',
|
||||||
|
fontSize: 14,
|
||||||
|
});
|
||||||
|
// Then in your code:
|
||||||
|
if (doLinesIntersect(moveLine, wallLine)) {
|
||||||
|
// Lines intersect, don't add the test line
|
||||||
|
if (testLine) {
|
||||||
|
canvas.remove(testLine);
|
||||||
|
canvas.renderAll();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Lines don't intersect, safe to add test line
|
||||||
|
if (testLine) {
|
||||||
|
canvas.remove(testLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
canvas.add(testLine);
|
||||||
|
canvas.renderAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(isMoveLine){
|
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
|
const currentRoofLines = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((obj) => obj.lineName === 'roofLine' && obj.roofId === roofId)
|
.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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const moveLine = wall.baseLines[index]
|
|
||||||
const roofLine = roof.lines[index]
|
|
||||||
|
|
||||||
|
|
||||||
//roof 접점
|
//roof 접점
|
||||||
@ -638,21 +689,21 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines)
|
const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines)
|
||||||
const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines)
|
const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines)
|
||||||
//move 접점
|
//move 접점
|
||||||
const p1moveLine = findClosestRoofLine(moveLine.startPoint, currentRoofLines)
|
const p1moveLine = findClosestRoofLine(moveLine.startPoint, wall.l)
|
||||||
const p2moveLine = findClosestRoofLine(moveLine.endPoint, currentRoofLines)
|
const p2moveLine = findClosestRoofLine(moveLine.endPoint, currentRoofLines)
|
||||||
//wall move 접점
|
//wall move 접점
|
||||||
const p1outerLine = findClosestRoofLine(wallLineStartPoint, currentRoofLines)
|
const p1outerLine = findClosestRoofLine(wallLineStartPoint, currentRoofLines)
|
||||||
const p2outerLine = findClosestRoofLine(wallLineEndPoint, currentRoofLines)
|
const p2outerLine = findClosestRoofLine(wallLineEndPoint, currentRoofLines)
|
||||||
|
|
||||||
|
|
||||||
console.log("p1RoofLineV",p1RoofLine)
|
// console.log("p1RoofLineV",p1RoofLine)
|
||||||
console.log("p2RoofLineV",p2RoofLine)
|
// console.log("p2RoofLineV",p2RoofLine)
|
||||||
console.log("p1wallLineV",p1wallLine)
|
// console.log("p1wallLineV",p1wallLine)
|
||||||
console.log("p2wallLineV",p2wallLine)
|
// console.log("p2wallLineV",p2wallLine)
|
||||||
console.log("p1moveLineV",p1moveLine)
|
// console.log("p1moveLineV",p1moveLine)
|
||||||
console.log("p2moveLineV",p2moveLine)
|
// console.log("p2moveLineV",p2moveLine)
|
||||||
console.log("p1outerLine",p1outerLine)
|
// console.log("p1outerLine",p1outerLine)
|
||||||
console.log("p2outerLine",p2outerLine)
|
// console.log("p2outerLine",p2outerLine)
|
||||||
// const outerLines= canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.attributes.roofId === roofId)
|
// const outerLines= canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.attributes.roofId === roofId)
|
||||||
// const outerLine = outerLines[index]
|
// const outerLine = outerLines[index]
|
||||||
// canvas.remove(outerLine)
|
// canvas.remove(outerLine)
|
||||||
@ -3287,3 +3338,130 @@ function getMovementInfo(p1, p2, newP1, newP2) {
|
|||||||
dy: dy1
|
dy: dy1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLineAngleDirection(line, isLeftSide = true) {
|
||||||
|
const dx = line.x2 - line.x1;
|
||||||
|
const dy = line.y2 - line.y1;
|
||||||
|
|
||||||
|
// 수평선인 경우 (y 좌표가 거의 같은 경우)
|
||||||
|
if (Math.abs(dy) < 0.1) {
|
||||||
|
// x 좌표 비교로 좌우 방향 결정
|
||||||
|
return line.x2 > line.x1 ? 'right' : 'left';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 수직선인 경우 (x 좌표가 거의 같은 경우)
|
||||||
|
if (Math.abs(dx) < 0.1) {
|
||||||
|
// y 좌표 비교로 상하 방향 결정
|
||||||
|
return line.y2 > line.y1 ? 'down' : 'up';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 대각선의 경우 기존 로직 유지
|
||||||
|
const angle = Math.atan2(dy, dx) * (180 / Math.PI);
|
||||||
|
const normalizedAngle = (angle + 360) % 360;
|
||||||
|
|
||||||
|
if (normalizedAngle >= 45 && normalizedAngle < 135) {
|
||||||
|
return 'up';
|
||||||
|
} else if (normalizedAngle >= 135 && normalizedAngle < 225) {
|
||||||
|
return 'left';
|
||||||
|
} else if (normalizedAngle >= 225 && normalizedAngle < 315) {
|
||||||
|
return 'down';
|
||||||
|
} else {
|
||||||
|
return 'right';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function findRoofLineIndex(roof, p1, p2) {
|
||||||
|
if (!roof || !roof.lines || !Array.isArray(roof.lines)) {
|
||||||
|
console.error("Invalid roof object or lines array");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a tolerance for floating point comparison
|
||||||
|
const TOLERANCE = 0.1;
|
||||||
|
|
||||||
|
// Try to find a line that matches either (p1,p2) or (p2,p1)
|
||||||
|
const index = roof.lines.findIndex(line => {
|
||||||
|
// Check if points match in order
|
||||||
|
const matchOrder =
|
||||||
|
(Math.abs(line.x1 - p1.x) < TOLERANCE &&
|
||||||
|
Math.abs(line.y1 - p1.y) < TOLERANCE &&
|
||||||
|
Math.abs(line.x2 - p2.x) < TOLERANCE &&
|
||||||
|
Math.abs(line.y2 - p2.y) < TOLERANCE);
|
||||||
|
|
||||||
|
// Check if points match in reverse order
|
||||||
|
const matchReverse =
|
||||||
|
(Math.abs(line.x1 - p2.x) < TOLERANCE &&
|
||||||
|
Math.abs(line.y1 - p2.y) < TOLERANCE &&
|
||||||
|
Math.abs(line.x2 - p1.x) < TOLERANCE &&
|
||||||
|
Math.abs(line.y2 - p1.y) < TOLERANCE);
|
||||||
|
|
||||||
|
return matchOrder || matchReverse;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (index === -1) {
|
||||||
|
console.warn("No matching roof line found for points:", p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findClosestParallelLine(roofLine, currentRoofLines) {
|
||||||
|
// Determine if the line is horizontal or vertical
|
||||||
|
const isHorizontal = Math.abs(roofLine.y2 - roofLine.y1) < 0.001; // Using a small threshold for floating point comparison
|
||||||
|
const isVertical = Math.abs(roofLine.x2 - roofLine.x1) < 0.001;
|
||||||
|
|
||||||
|
if (!isHorizontal && !isVertical) {
|
||||||
|
console.warn('Line is neither perfectly horizontal nor vertical');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the reference point (midpoint of the line)
|
||||||
|
const refX = (roofLine.x1 + roofLine.x2) / 2;
|
||||||
|
const refY = (roofLine.y1 + roofLine.y2) / 2;
|
||||||
|
|
||||||
|
let closestLine = null;
|
||||||
|
let minDistance = Infinity;
|
||||||
|
|
||||||
|
currentRoofLines.forEach(line => {
|
||||||
|
// Skip the same line
|
||||||
|
if (line === roofLine) return;
|
||||||
|
|
||||||
|
// Check if the line is parallel (same orientation)
|
||||||
|
const lineIsHorizontal = Math.abs(line.y2 - line.y1) < 0.001;
|
||||||
|
const lineIsVertical = Math.abs(line.x2 - line.x1) < 0.001;
|
||||||
|
|
||||||
|
if ((isHorizontal && lineIsHorizontal) || (isVertical && lineIsVertical)) {
|
||||||
|
// Calculate midpoint of the current line
|
||||||
|
const lineMidX = (line.x1 + line.x2) / 2;
|
||||||
|
const lineMidY = (line.y1 + line.y2) / 2;
|
||||||
|
|
||||||
|
// Calculate distance between midpoints
|
||||||
|
const distance = Math.sqrt(
|
||||||
|
Math.pow(lineMidX - refX, 2) +
|
||||||
|
Math.pow(lineMidY - refY, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Update closest line if this one is closer
|
||||||
|
if (distance < minDistance) {
|
||||||
|
minDistance = distance;
|
||||||
|
closestLine = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return closestLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
function doLinesIntersect(line1, line2) {
|
||||||
|
const x1 = line1.x1, y1 = line1.y1;
|
||||||
|
const x2 = line1.x2, y2 = line1.y2;
|
||||||
|
const x3 = line2.x1, y3 = line2.y1;
|
||||||
|
const x4 = line2.x2, y4 = line2.y2;
|
||||||
|
|
||||||
|
// Calculate the direction of the lines
|
||||||
|
const uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
|
||||||
|
const uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
|
||||||
|
|
||||||
|
// If uA and uB are between 0-1, lines are colliding
|
||||||
|
return (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user