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) => {
|
||||
if (!skeleton?.Edges) return []
|
||||
const roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||
let wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||
let skeletonLines = []
|
||||
|
||||
const processedInnerEdges = new Set()
|
||||
@ -513,7 +513,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//벽라인
|
||||
const wallLines = wall.lines
|
||||
|
||||
skeletonLines.forEach(sktLine => {
|
||||
skeletonLines.forEach((sktLine, skIndex) => {
|
||||
let { p1, p2, attributes, lineStyle } = sktLine;
|
||||
|
||||
// 중복방지 - 라인을 고유하게 식별할 수 있는 키 생성 (정규화된 좌표로 정렬하여 비교)
|
||||
@ -532,6 +532,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
{ x: sktLine.p2.x, y: sktLine.p2.y }
|
||||
);
|
||||
|
||||
//그림을 그릴때 idx 가 필요함 roof는 왼쪽부터 시작됨 - 그림그리는 순서가 필요함
|
||||
|
||||
const skeletonLine = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
||||
parentId: roof.id,
|
||||
fontSize: roof.fontSize,
|
||||
@ -543,7 +545,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
isBaseLine: sktLine.attributes.isOuterEdge,
|
||||
lineName: (sktLine.attributes.isOuterEdge)?'roofLine': attributes.type,
|
||||
selectable:(!sktLine.attributes.isOuterEdge),
|
||||
roofId: roofId,
|
||||
|
||||
});
|
||||
|
||||
|
||||
@ -552,7 +554,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
existingLines.add(lineKey); // 추가된 라인을 추적
|
||||
|
||||
|
||||
|
||||
|
||||
//skeleton 라인에서 처마선은 삭제
|
||||
if(skeletonLine.lineName === 'roofLine'){
|
||||
const coordinateText = new fabric.Text(`(${Math.round(skeletonLine.x1)}, ${Math.round(skeletonLine.y1)})`, {
|
||||
@ -596,11 +598,12 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
//wall.lines 는 기본 벽 라인
|
||||
//wall.baseLine은 움직인라인
|
||||
|
||||
wall.lines.forEach((wallLine, index) => {
|
||||
console.log("wallLine:::::", wallLine, index)
|
||||
let p1,p2,p3, p4
|
||||
let idx = 0;
|
||||
let isMoveLine = true;
|
||||
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
|
||||
@ -611,24 +614,72 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
const wallLineEndPoint = {x:wallLine.x2, y:wallLine.y2}
|
||||
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){
|
||||
//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.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 접점
|
||||
@ -638,21 +689,21 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
const p1wallLine = findClosestRoofLine(wallLineStartPoint,wall.lines)
|
||||
const p2wallLine = findClosestRoofLine(wallLineEndPoint,wall.lines)
|
||||
//move 접점
|
||||
const p1moveLine = findClosestRoofLine(moveLine.startPoint, currentRoofLines)
|
||||
const p1moveLine = findClosestRoofLine(moveLine.startPoint, wall.l)
|
||||
const p2moveLine = findClosestRoofLine(moveLine.endPoint, currentRoofLines)
|
||||
//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)
|
||||
// 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)
|
||||
@ -1080,7 +1131,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
if(isPolygon){
|
||||
drawPolygon( p1,p2,p3, p4)
|
||||
}
|
||||
|
||||
|
||||
// const wallLine = wall.baseLines[roofLine.idx - 1];
|
||||
|
||||
|
||||
@ -1098,7 +1149,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
|
||||
//wallLine이 baseLine의 위 또는 오른쪽에 있을때
|
||||
|
||||
|
||||
|
||||
// let outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine' && obj.attributes.roofId === roofId)
|
||||
// outerLines.forEach((outerLine) => {
|
||||
@ -3286,4 +3337,131 @@ function getMovementInfo(p1, p2, newP1, newP2) {
|
||||
dx: dx1,
|
||||
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