This commit is contained in:
ysCha 2025-11-07 18:34:16 +09:00
parent 88632a4619
commit 881fcb91f6
2 changed files with 137 additions and 137 deletions

View File

@ -336,8 +336,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
// 용마루 -- straight-skeleton
console.log('용마루 지붕')
drawRidgeRoof(this.id, this.canvas, textMode)
//drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
//drawRidgeRoof(this.id, this.canvas, textMode)
drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
} else if (isGableRoof(types)) {
// A형, B형 박공 지붕
console.log('패턴 지붕')

View File

@ -231,19 +231,19 @@ const movingLineFromSkeleton = (roofId, canvas) => {
newPoints.forEach((point, index) => {
if(position === 'bottom'){
if (moveDirection === 'in') {
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
point.y = Big(point.y).minus(absMove).toNumber();
}
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
point.y = Big(point.y).minus(absMove).toNumber();
}
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
// point.y = Big(point.y).minus(absMove).toNumber();
// }
}else if (moveDirection === 'out'){
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
point.y = Big(point.y).plus(absMove).toNumber();
}
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
point.y = Big(point.y).plus(absMove).toNumber();
}
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
// point.y = Big(point.y).plus(absMove).toNumber();
// }
}
}else if (position === 'top'){
@ -265,19 +265,19 @@ const movingLineFromSkeleton = (roofId, canvas) => {
}else if(position === 'left'){
if(moveDirection === 'in'){
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
point.x = Big(point.x).plus(absMove).toNumber();
}
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
point.x = Big(point.x).plus(absMove).toNumber();
}
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
// point.x = Big(point.x).plus(absMove).toNumber();
// }
}else if(moveDirection === 'out'){
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
point.x = Big(point.x).minus(absMove).toNumber();
}
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
if(isSamePoint(roof.basePoints[index], originalStartPoint) || isSamePoint(roof.basePoints[index], originalEndPoint)) {
point.x = Big(point.x).minus(absMove).toNumber();
}
// if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
// point.x = Big(point.x).minus(absMove).toNumber();
// }
}
}else if(position === 'right'){
@ -426,7 +426,8 @@ export const skeletonBuilder = (roofId, canvas, textMode) => {
*/
const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
if (!skeleton?.Edges) return []
let roof = canvas?.getObjects().find((object) => object.id === roofId)
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 skeletonLines = []
const processedInnerEdges = new Set()
@ -535,140 +536,69 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
});
//skeleton 라인에서 처마선은 삭제
if(innerLine.lineName !== 'outerLine'){
canvas.add(innerLine);
innerLine.bringToFront();
existingLines.add(lineKey); // 추가된 라인을 추적
}else{
if(innerLine.lineName === 'outerLine'){
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
const wallLines = wall.baseLines
// 현재 지점과 다음 지점을 비교하기 위한 변수
let changedLine = roof.moveSelectLine;
const roofLines = [];
if (!wall.lines || !wall.baseLines) {
return wall.baseLines || wall.lines || [];
}
// 길이가 다른 경우 baseLines 반환
if (wall.lines.length !== wall.baseLines.length) {
return wall.baseLines;
}
for (let i = 0; i < wall.baseLines.length; i++) {
const baseLine = wall.baseLines[i];
const line = wall.lines[i];
if (!line ||
((!isSamePoint(baseLine.startPoint, line.startPoint)) && // 시작점이 다르고
(!isSamePoint(baseLine.endPoint, line.endPoint)))) { // 끝점도 다른 경우
let idx = 0;
//const orgWallLine = wall.lines
//console.log("outLine:::::", p1, p2, line)
for(const orgLine of roof.lines){
console.log("a::::",isSamePoint(p1,orgLine.startPoint), p1, orgLine.startPoint)
console.log("b::::",isSamePoint(p2,orgLine.endPoint), p2, orgLine.endPoint)
console.log("c::::",isSamePoint(p2,orgLine.startPoint), p2, orgLine.startPoint)
console.log("d::::",isSamePoint(p1,orgLine.endPoint), p1, orgLine.endPoint)
let isSampe1 = false
let isSampe2 = false
const orgOuterLine = orgLine
if(isSamePoint(p1,orgLine.startPoint) && isSamePoint(p2,orgLine.endPoint)){
isSampe1 = true;
break;
}
}
orgOuterLine.startPoint = orgLine.endPoint
orgOuterLine.endPoint = orgLine.startPoint
const startClosest = findClosestRoofLine(p1, roof.lines);
const endClosest = findClosestRoofLine(p2, roof.lines);
const { point, closest, selectPoint, otherPoint } =
startClosest.distance > endClosest.distance
? {
point : p2,
closest : endClosest,
otherPoint: p1
}
: {
point : p1,
closest : startClosest,
otherPoint: p2
};
// Log the relevant information
console.log("Point:", point);
console.log("Closest intersection:", closest);
console.log("moveSelectLinePoint:", selectPoint);
let isTarget = false;
for(const roofLine of roof.lines){
if( isSamePoint(p1, roofLine.startPoint) ||
isSamePoint(p2, roofLine.endPoint) ||
isSamePoint(p1, roofLine.endPoint) ||
isSamePoint(p2, roofLine.startPoint) ) {
isTarget = true ;
break
if(isSamePoint(p1,orgLine.endPoint) && isSamePoint(p2,orgLine.startPoint)){
isSampe2 = true
return;
}
}
if (isTarget) {
console.warn("matching line found in roof.lines");
return; // 또는 적절한 오류 처리
}
const innerLine2 = new QLine([p1.x, p1.y, p2.x, p2.y], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: lineStyle.width,
name: (line.attributes.isOuterEdge)?'eaves': attributes.type,
attributes: attributes,
direction: direction,
isBaseLine: line.attributes.isOuterEdge,
lineName: (line.attributes.isOuterEdge)?'addLine': attributes.type,
selectable:(!line.attributes.isOuterEdge),
roofId: roofId,
});
const innerLine2 = new QLine([orgOuterLine.startPoint.x, orgOuterLine.startPoint.y, orgOuterLine.endPoint.x, orgOuterLine.endPoint.y], {
parentId : roof.id,
fontSize : roof.fontSize,
stroke : 'yellow',
strokeWidth: lineStyle.width,
name : (line.attributes.isOuterEdge) ? 'eaves' : attributes.type,
attributes : attributes,
direction : direction,
isBaseLine : line.attributes.isOuterEdge,
lineName : (line.attributes.isOuterEdge) ? 'addLine' : attributes.type,
selectable : (!line.attributes.isOuterEdge),
roofId : roofId,
});
canvas.add(innerLine2);
//existingLines.add(lineKey); // 추가된 라인을 추적
/*
//라인추가(까지 못할때때) 외벽선에서 추가
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
const wallLines = wall.baseLines
// 현재 지점과 다음 지점을 비교하기 위한 변수
let changedLine = roof.moveSelectLine;
const roofLines = [];
//orgOuterLine.setCoords()
//canvas.renderAll()
canvas.add(innerLine2);
}
if (!wall.lines || !wall.baseLines) {
return wall.baseLines || wall.lines || [];
}
// 길이가 다른 경우 baseLines 반환
if (wall.lines.length !== wall.baseLines.length) {
return wall.baseLines;
for(const orgWallLine of wall.lines){
// console.log("orgWallLine::::;",orgWallLine.startPoint, orgWallLine.endPoint);
// if(isSamePoint(orgWallLine.startPoint, p1) ||
// isSamePoint(orgWallLine.endPoint, p2) ||
// isSamePoint(orgWallLine.endPoint, p1) ||
// isSamePoint(orgWallLine.startPoint, p2)){
// idx = orgWallLine.idx
// break
// }
}
//그려지는 처마라인이 처마 && 포인터모두가 wall.baseLine에 들어가 있는 경우
const checkPoint = {x1:line.x1, y1:line.y1, x2:line.x2, y2:line.y2}
if(line.attributes.type === 'hip' && !checkPointInPolygon(checkPoint, wall)) {
const startClosest = findClosestRoofLine(p1, roof.lines);
const endClosest = findClosestRoofLine(p2, roof.lines);
console.log("Lindd::::",line)
const { point, closest, selectPoint, otherPoint } =
startClosest.distance > endClosest.distance
? {
point : p2,
closest : endClosest,
//selectPoint : changedLine.endPoint,
otherPoint: p1
}
: {
point : p1,
closest : startClosest,
//selectPoint : changedLine.startPoint,
otherPoint: p2
};
// Log the relevant information
console.log("Point:", point);
console.log("Closest intersection:", closest);
console.log("moveSelectLinePoint:", selectPoint);
}
*/
//초기외곽라인?
const coordinateText = new fabric.Text(`(${Math.round(p1.x)}, ${Math.round(p1.y)})`, {
left: p1.x + 5, // 좌표점에서 약간 오른쪽으로 이동
top: p1.y - 20, // 좌표점에서 약간 위로 이동
@ -685,6 +615,11 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
})
canvas?.add(coordinateText)
}else{
canvas.add(innerLine);
innerLine.bringToFront();
existingLines.add(lineKey); // 추가된 라인을 추적
}
innerLines.push(innerLine)
canvas.renderAll();
@ -2569,4 +2504,69 @@ function hasIntersectionWithOtherLines(point, skeletonLines, currentLine, tolera
// 1개 이상의 다른 라인과 연결되어 있으면 교점으로 간주
return connectionCount >= 1;
}
function findClosestRoofLine(point, roofLines) {
let closestLine = null;
let minDistance = Infinity;
let roofLineIndex = 0;
let interPoint = null;
roofLines.forEach((roofLine, index) => {
const lineP1 = roofLine.startPoint;
const lineP2 = roofLine.endPoint;
// 점에서 선분까지의 최단 거리 계산
const distance = pointToLineDistance(point, lineP1, lineP2);
// 점에서 수직으로 내린 교점 계산
const intersection = getProjectionPoint(point, {
x1: lineP1.x,
y1: lineP1.y,
x2: lineP2.x,
y2: lineP2.y
});
if (distance < minDistance) {
minDistance = distance < 0.1 ? 0 : distance; //거리가 0.1보다 작으면 0으로 처리
closestLine = roofLine;
roofLineIndex = index
interPoint = intersection;
}
});
return { line: closestLine, distance: minDistance, index: roofLineIndex, intersectionPoint: interPoint };
}
// 점에서 선분까지의 최단 거리를 계산하는 도우미 함수
function pointToLineDistance(point, lineP1, lineP2) {
const A = point.x - lineP1.x;
const B = point.y - lineP1.y;
const C = lineP2.x - lineP1.x;
const D = lineP2.y - lineP1.y;
const dot = A * C + B * D;
const lenSq = C * C + D * D;
let param = -1;
if (lenSq !== 0) {
param = dot / lenSq;
}
let xx, yy;
if (param < 0) {
xx = lineP1.x;
yy = lineP1.y;
} else if (param > 1) {
xx = lineP2.x;
yy = lineP2.y;
} else {
xx = lineP1.x + param * C;
yy = lineP1.y + param * D;
}
const dx = point.x - xx;
const dy = point.y - yy;
return Math.sqrt(dx * dx + dy * dy);
}