sk
This commit is contained in:
parent
88632a4619
commit
881fcb91f6
@ -336,8 +336,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
if (types.every((type) => type === LINE_TYPE.WALLLINE.EAVES)) {
|
||||||
// 용마루 -- straight-skeleton
|
// 용마루 -- straight-skeleton
|
||||||
console.log('용마루 지붕')
|
console.log('용마루 지붕')
|
||||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
//drawRidgeRoof(this.id, this.canvas, textMode)
|
||||||
//drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
drawSkeletonRidgeRoof(this.id, this.canvas, textMode);
|
||||||
} else if (isGableRoof(types)) {
|
} else if (isGableRoof(types)) {
|
||||||
// A형, B형 박공 지붕
|
// A형, B형 박공 지붕
|
||||||
console.log('패턴 지붕')
|
console.log('패턴 지붕')
|
||||||
|
|||||||
@ -231,19 +231,19 @@ const movingLineFromSkeleton = (roofId, canvas) => {
|
|||||||
newPoints.forEach((point, index) => {
|
newPoints.forEach((point, index) => {
|
||||||
if(position === 'bottom'){
|
if(position === 'bottom'){
|
||||||
if (moveDirection === 'in') {
|
if (moveDirection === 'in') {
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
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();
|
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'){
|
}else if (moveDirection === 'out'){
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
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();
|
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'){
|
}else if (position === 'top'){
|
||||||
@ -265,19 +265,19 @@ const movingLineFromSkeleton = (roofId, canvas) => {
|
|||||||
|
|
||||||
}else if(position === 'left'){
|
}else if(position === 'left'){
|
||||||
if(moveDirection === 'in'){
|
if(moveDirection === 'in'){
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
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();
|
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'){
|
}else if(moveDirection === 'out'){
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
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();
|
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'){
|
}else if(position === 'right'){
|
||||||
@ -426,7 +426,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 []
|
||||||
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 = []
|
let skeletonLines = []
|
||||||
const processedInnerEdges = new Set()
|
const processedInnerEdges = new Set()
|
||||||
|
|
||||||
@ -535,140 +536,69 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//skeleton 라인에서 처마선은 삭제
|
//skeleton 라인에서 처마선은 삭제
|
||||||
if(innerLine.lineName !== 'outerLine'){
|
if(innerLine.lineName === 'outerLine'){
|
||||||
canvas.add(innerLine);
|
|
||||||
innerLine.bringToFront();
|
|
||||||
existingLines.add(lineKey); // 추가된 라인을 추적
|
|
||||||
}else{
|
|
||||||
|
|
||||||
|
|
||||||
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
|
let idx = 0;
|
||||||
const wallLines = wall.baseLines
|
//const orgWallLine = wall.lines
|
||||||
// 현재 지점과 다음 지점을 비교하기 위한 변수
|
//console.log("outLine:::::", p1, p2, line)
|
||||||
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)))) { // 끝점도 다른 경우
|
|
||||||
|
|
||||||
|
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);
|
if(isSamePoint(p1,orgLine.endPoint) && isSamePoint(p2,orgLine.startPoint)){
|
||||||
const endClosest = findClosestRoofLine(p2, roof.lines);
|
isSampe2 = true
|
||||||
|
return;
|
||||||
|
|
||||||
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 (isTarget) {
|
|
||||||
console.warn("matching line found in roof.lines");
|
|
||||||
return; // 또는 적절한 오류 처리
|
|
||||||
}
|
|
||||||
|
|
||||||
const innerLine2 = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
const innerLine2 = new QLine([orgOuterLine.startPoint.x, orgOuterLine.startPoint.y, orgOuterLine.endPoint.x, orgOuterLine.endPoint.y], {
|
||||||
parentId: roof.id,
|
parentId : roof.id,
|
||||||
fontSize: roof.fontSize,
|
fontSize : roof.fontSize,
|
||||||
stroke: 'red',
|
stroke : 'yellow',
|
||||||
strokeWidth: lineStyle.width,
|
strokeWidth: lineStyle.width,
|
||||||
name: (line.attributes.isOuterEdge)?'eaves': attributes.type,
|
name : (line.attributes.isOuterEdge) ? 'eaves' : attributes.type,
|
||||||
attributes: attributes,
|
attributes : attributes,
|
||||||
direction: direction,
|
direction : direction,
|
||||||
isBaseLine: line.attributes.isOuterEdge,
|
isBaseLine : line.attributes.isOuterEdge,
|
||||||
lineName: (line.attributes.isOuterEdge)?'addLine': attributes.type,
|
lineName : (line.attributes.isOuterEdge) ? 'addLine' : attributes.type,
|
||||||
selectable:(!line.attributes.isOuterEdge),
|
selectable : (!line.attributes.isOuterEdge),
|
||||||
roofId: roofId,
|
roofId : roofId,
|
||||||
});
|
});
|
||||||
|
|
||||||
canvas.add(innerLine2);
|
//orgOuterLine.setCoords()
|
||||||
//existingLines.add(lineKey); // 추가된 라인을 추적
|
//canvas.renderAll()
|
||||||
/*
|
canvas.add(innerLine2);
|
||||||
//라인추가(까지 못할때때) 외벽선에서 추가
|
}
|
||||||
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 반환
|
for(const orgWallLine of wall.lines){
|
||||||
if (wall.lines.length !== wall.baseLines.length) {
|
// console.log("orgWallLine::::;",orgWallLine.startPoint, orgWallLine.endPoint);
|
||||||
return wall.baseLines;
|
// 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)})`, {
|
const coordinateText = new fabric.Text(`(${Math.round(p1.x)}, ${Math.round(p1.y)})`, {
|
||||||
left: p1.x + 5, // 좌표점에서 약간 오른쪽으로 이동
|
left: p1.x + 5, // 좌표점에서 약간 오른쪽으로 이동
|
||||||
top: p1.y - 20, // 좌표점에서 약간 위로 이동
|
top: p1.y - 20, // 좌표점에서 약간 위로 이동
|
||||||
@ -685,6 +615,11 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
canvas?.add(coordinateText)
|
canvas?.add(coordinateText)
|
||||||
|
|
||||||
|
}else{
|
||||||
|
canvas.add(innerLine);
|
||||||
|
innerLine.bringToFront();
|
||||||
|
existingLines.add(lineKey); // 추가된 라인을 추적
|
||||||
}
|
}
|
||||||
innerLines.push(innerLine)
|
innerLines.push(innerLine)
|
||||||
canvas.renderAll();
|
canvas.renderAll();
|
||||||
@ -2569,4 +2504,69 @@ function hasIntersectionWithOtherLines(point, skeletonLines, currentLine, tolera
|
|||||||
|
|
||||||
// 1개 이상의 다른 라인과 연결되어 있으면 교점으로 간주
|
// 1개 이상의 다른 라인과 연결되어 있으면 교점으로 간주
|
||||||
return connectionCount >= 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);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user