Compare commits
No commits in common. "2ac1e80964cff3845b0e34de49e595c1ff660c5c" and "fc6bf3a01d2908169a07c3d0742476367784af83" have entirely different histories.
2ac1e80964
...
fc6bf3a01d
@ -407,21 +407,29 @@ export function useRoofAllocationSetting(id) {
|
|||||||
roofBases.forEach((roofBase) => {
|
roofBases.forEach((roofBase) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const roofEaveHelpLines = canvas.getObjects().filter((obj) => obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id)
|
const roofEaveHelpLines = canvas.getObjects().filter(obj =>
|
||||||
if (roofEaveHelpLines.length > 0) {
|
obj.lineName === 'eaveHelpLine' && obj.roofId === roofBase.id
|
||||||
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 = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
if (roofBase.lines) {
|
||||||
roofBase.lines = [...newEaveLines]
|
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||||
} else {
|
const existingEaveLineIds = new Set(roofBase.lines.map(line => line.id));
|
||||||
roofBase.lines = [...roofEaveHelpLines]
|
const newEaveLines = roofEaveHelpLines.filter(line => !existingEaveLineIds.has(line.id));
|
||||||
}
|
roofBase.lines = [...newEaveLines];
|
||||||
if (!roofBase.innerLines) {
|
} else {
|
||||||
roofBase.innerLines = []
|
roofBase.lines = [...roofEaveHelpLines];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!roofBase.innerLines) {
|
||||||
|
roofBase.innerLines = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add only eaveHelpLines that belong to this roofBase
|
||||||
|
// const baseEaveHelpLines = roofEaveHelpLines.filter(line => line.roofId === roofBase.id);
|
||||||
|
// roofBase.innerLines = [...new Set([...roofBase.innerLines, ...baseEaveHelpLines])];
|
||||||
|
|
||||||
if (roofBase.separatePolygon.length > 0) {
|
if (roofBase.separatePolygon.length > 0) {
|
||||||
splitPolygonWithSeparate(roofBase.separatePolygon)
|
splitPolygonWithSeparate(roofBase.separatePolygon)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -845,8 +845,6 @@ export const usePolygon = () => {
|
|||||||
polygonLines.forEach((line) => {
|
polygonLines.forEach((line) => {
|
||||||
line.need = true
|
line.need = true
|
||||||
})
|
})
|
||||||
// 순서에 의존하지 않도록 모든 조합을 먼저 확인한 후 처리
|
|
||||||
const innerLineMapping = new Map() // innerLine -> polygonLine 매핑 저장
|
|
||||||
|
|
||||||
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
||||||
innerLines.forEach((innerLine) => {
|
innerLines.forEach((innerLine) => {
|
||||||
@ -856,28 +854,14 @@ export const usePolygon = () => {
|
|||||||
if (innerLine.attributes && polygonLine.attributes.type) {
|
if (innerLine.attributes && polygonLine.attributes.type) {
|
||||||
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
||||||
if (polygonLine.length < innerLine.length) {
|
if (polygonLine.length < innerLine.length) {
|
||||||
if(polygonLine.lineName !== 'eaveHelpLine'){
|
polygonLine.need = false
|
||||||
polygonLine.need = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
||||||
// innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
||||||
// innerLine.attributes.type = polygonLine.attributes.type
|
innerLine.attributes.type = polygonLine.attributes.type
|
||||||
// innerLine.direction = polygonLine.direction
|
innerLine.direction = polygonLine.direction
|
||||||
// innerLine.attributes.isStart = true
|
innerLine.attributes.isStart = true
|
||||||
// innerLine.parentLine = polygonLine
|
innerLine.parentLine = polygonLine
|
||||||
|
|
||||||
|
|
||||||
// 매핑된 innerLine의 attributes를 변경 (교차점 계산 전에 적용)
|
|
||||||
innerLineMapping.forEach((polygonLine, innerLine) => {
|
|
||||||
innerLine.attributes.planeSize = innerLine.attributes.planeSize ?? polygonLine.attributes.planeSize
|
|
||||||
innerLine.attributes.actualSize = innerLine.attributes.actualSize ?? polygonLine.attributes.actualSize
|
|
||||||
innerLine.attributes.type = polygonLine.attributes.type
|
|
||||||
innerLine.direction = polygonLine.direction
|
|
||||||
innerLine.attributes.isStart = true
|
|
||||||
innerLine.parentLine = polygonLine
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,387 +0,0 @@
|
|||||||
import { useEffect } from 'react'
|
|
||||||
import { useRecoilState } from 'recoil'
|
|
||||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
||||||
import Big from 'big.js'
|
|
||||||
import { isSamePoint, toGeoJSON } from '@/util/qpolygon-utils'
|
|
||||||
import { SkeletonBuilder } from '@/lib/skeletons'
|
|
||||||
import {
|
|
||||||
preprocessPolygonCoordinates,
|
|
||||||
findOppositeLine,
|
|
||||||
createOrderedBasePoints,
|
|
||||||
createInnerLinesFromSkeleton
|
|
||||||
} from '@/util/skeleton-utils'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function useSkeleton(canvas, roofId, textMode = false) {
|
|
||||||
// 2. 스켈레톤 생성 및 그리기
|
|
||||||
//처마
|
|
||||||
if (!canvas) {
|
|
||||||
console.warn('Canvas is not available');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
|
||||||
|
|
||||||
if (!roof) {
|
|
||||||
console.warn(`Roof with id ${roofId} not found`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roof.points || roof.points.length < 3) {
|
|
||||||
console.warn('Roof points are invalid');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const eavesType = [LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.HIPANDGABLE]
|
|
||||||
const gableType = [LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.WALLLINE.JERKINHEAD]
|
|
||||||
|
|
||||||
/** 외벽선 */
|
|
||||||
const wall = canvas.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
|
|
||||||
//const baseLines = wall.baseLines.filter((line) => line.attributes.planeSize > 0)
|
|
||||||
|
|
||||||
const baseLines = canvas.getObjects().filter((object) => object.name === 'baseLine' && object.parentId === roofId) || [];
|
|
||||||
const baseLinePoints = baseLines.map((line) => ({x:line.left, y:line.top}));
|
|
||||||
|
|
||||||
const outerLines = canvas.getObjects().filter((object) => object.name === 'outerLinePoint') || [];
|
|
||||||
const outerLinePoints = outerLines.map((line) => ({x:line.left, y:line.top}))
|
|
||||||
|
|
||||||
const hipLines = canvas.getObjects().filter((object) => object.name === 'hip' && object.parentId === roofId) || [];
|
|
||||||
const ridgeLines = canvas.getObjects().filter((object) => object.name === 'ridge' && object.parentId === roofId) || [];
|
|
||||||
|
|
||||||
//const skeletonLines = [];
|
|
||||||
// 1. 지붕 폴리곤 좌표 전처리
|
|
||||||
const coordinates = preprocessPolygonCoordinates(roof.points);
|
|
||||||
if (coordinates.length < 3) {
|
|
||||||
console.warn("Polygon has less than 3 unique points. Cannot generate skeleton.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const moveFlowLine = roof.moveFlowLine || 0; // Provide a default value
|
|
||||||
const moveUpDown = roof.moveUpDown || 0; // Provide a default value
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let points = roof.points;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//마루이동
|
|
||||||
if (moveFlowLine !== 0 || moveUpDown !== 0) {
|
|
||||||
const movingLineFromSkeleton = (roofId, canvas) => {
|
|
||||||
if (!canvas) {
|
|
||||||
console.warn('Canvas is not available in movingLineFromSkeleton');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let roof = canvas?.getObjects().find((object) => object.id === roofId)
|
|
||||||
|
|
||||||
if (!roof) {
|
|
||||||
console.warn(`Roof with id ${roofId} not found in movingLineFromSkeleton`);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let moveDirection = roof.moveDirect;
|
|
||||||
let moveFlowLine = roof.moveFlowLine??0;
|
|
||||||
let moveUpDown = roof.moveUpDown??0;
|
|
||||||
const getSelectLine = () => roof.moveSelectLine;
|
|
||||||
const selectLine = getSelectLine();
|
|
||||||
|
|
||||||
if (!selectLine || !selectLine.startPoint || !selectLine.endPoint) {
|
|
||||||
console.warn('SelectLine is not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let movePosition = roof.movePosition;
|
|
||||||
|
|
||||||
const startPoint = selectLine.startPoint
|
|
||||||
const endPoint = selectLine.endPoint
|
|
||||||
const orgRoofPoints = roof.points; // orgPoint를 orgPoints로 변경
|
|
||||||
|
|
||||||
if (!canvas.skeleton || !canvas.skeleton.Edges) {
|
|
||||||
console.warn('Skeleton edges are not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldPoints = canvas?.skeleton.lastPoints ?? orgRoofPoints // 여기도 변경
|
|
||||||
const oppositeLine = findOppositeLine(canvas.skeleton.Edges, startPoint, endPoint, oldPoints);
|
|
||||||
|
|
||||||
const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
|
||||||
|
|
||||||
if (!wall || !wall.baseLines) {
|
|
||||||
console.warn('Wall or baseLines are not available');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseLines = wall.baseLines
|
|
||||||
roof.basePoints = createOrderedBasePoints(roof.points, baseLines)
|
|
||||||
|
|
||||||
const skeletonPolygon = canvas.getObjects().filter((object) => object.skeletonType === 'polygon' && object.parentId === roofId)
|
|
||||||
const skeletonLines = canvas.getObjects().filter((object) => object.skeletonType === 'line' && object.parentId === roofId)
|
|
||||||
|
|
||||||
if (oppositeLine) {
|
|
||||||
console.log('Opposite line found:', oppositeLine);
|
|
||||||
} else {
|
|
||||||
console.log('No opposite line found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(moveFlowLine !== 0) {
|
|
||||||
return oldPoints.map((point, index) => {
|
|
||||||
console.log('Point:', point);
|
|
||||||
const newPoint = { ...point };
|
|
||||||
const absMove = Big(moveFlowLine).times(2).div(10);
|
|
||||||
|
|
||||||
console.log('skeletonBuilder moveDirection:', moveDirection);
|
|
||||||
|
|
||||||
switch (moveDirection) {
|
|
||||||
case 'left':
|
|
||||||
// Move left: decrease X
|
|
||||||
if (moveFlowLine !== 0) {
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'left') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.x = Big(line.start.x).plus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.x = Big(line.end.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else if (moveUpDown !== 0) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'right':
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'right') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.x = Big(line.start.x).minus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.x = Big(line.end.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
break
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'up':
|
|
||||||
// Move up: decrease Y (toward top of screen)
|
|
||||||
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
if (line.position === 'top') {
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.y = Big(line.start.y).minus(absMove).toNumber();
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.y = Big(line.end.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 'down':
|
|
||||||
// Move down: increase Y (toward bottom of screen)
|
|
||||||
for (const line of oppositeLine) {
|
|
||||||
|
|
||||||
if (line.position === 'bottom') {
|
|
||||||
|
|
||||||
console.log('oldPoint:', point);
|
|
||||||
|
|
||||||
if (isSamePoint(newPoint, line.start)) {
|
|
||||||
newPoint.y = Big(line.start.y).minus(absMove).toNumber();
|
|
||||||
|
|
||||||
} else if (isSamePoint(newPoint, line.end)) {
|
|
||||||
newPoint.y = Big(line.end.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('newPoint:', newPoint);
|
|
||||||
//baseline 변경
|
|
||||||
return newPoint;
|
|
||||||
})
|
|
||||||
} else if(moveUpDown !== 0) {
|
|
||||||
|
|
||||||
const position = movePosition //result.position;
|
|
||||||
const absMove = Big(moveUpDown).times(1).div(10);
|
|
||||||
const modifiedStartPoints = [];
|
|
||||||
// oldPoints를 복사해서 새로운 points 배열 생성
|
|
||||||
let newPoints = oldPoints.map(point => ({...point}));
|
|
||||||
|
|
||||||
// selectLine과 일치하는 baseLines 찾기
|
|
||||||
const matchingLines = baseLines
|
|
||||||
.map((line, index) => ({ ...line, findIndex: index }))
|
|
||||||
.filter(line =>
|
|
||||||
(isSamePoint(line.startPoint, selectLine.startPoint) &&
|
|
||||||
isSamePoint(line.endPoint, selectLine.endPoint)) ||
|
|
||||||
(isSamePoint(line.startPoint, selectLine.endPoint) &&
|
|
||||||
isSamePoint(line.endPoint, selectLine.startPoint))
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
matchingLines.forEach(line => {
|
|
||||||
const originalStartPoint = line.startPoint;
|
|
||||||
const originalEndPoint = line.endPoint;
|
|
||||||
const offset = line.attributes.offset
|
|
||||||
// 새로운 좌표 계산
|
|
||||||
let newStartPoint = {...originalStartPoint};
|
|
||||||
let newEndPoint = {...originalEndPoint};
|
|
||||||
|
|
||||||
|
|
||||||
// 원본 라인 업데이트
|
|
||||||
// newPoints 배열에서 일치하는 포인트들을 찾아서 업데이트
|
|
||||||
console.log('absMove::', absMove);
|
|
||||||
newPoints.forEach((point, index) => {
|
|
||||||
if(position === 'bottom'){
|
|
||||||
if (moveDirection === 'in') {
|
|
||||||
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) || 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'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}else if(moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.y = Big(point.y).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(position === 'left'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
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) || 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'){
|
|
||||||
if(moveDirection === 'in'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).minus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}else if(moveDirection === 'out'){
|
|
||||||
if(isSamePoint(roof.basePoints[index], originalStartPoint)) {
|
|
||||||
point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
if (isSamePoint(roof.basePoints[index], originalEndPoint)) {
|
|
||||||
point.x = Big(point.x).plus(absMove).toNumber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// 원본 baseLine도 업데이트
|
|
||||||
line.startPoint = newStartPoint;
|
|
||||||
line.endPoint = newEndPoint;
|
|
||||||
});
|
|
||||||
return newPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const result = movingLineFromSkeleton(roofId, canvas);
|
|
||||||
if (result) {
|
|
||||||
points = result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
console.log('points:', points);
|
|
||||||
const geoJSONPolygon = toGeoJSON(points)
|
|
||||||
|
|
||||||
try {
|
|
||||||
// SkeletonBuilder는 닫히지 않은 폴리곤을 기대하므로 마지막 점 제거
|
|
||||||
geoJSONPolygon.pop()
|
|
||||||
const skeleton = SkeletonBuilder.BuildFromGeoJSON([[geoJSONPolygon]])
|
|
||||||
|
|
||||||
// 스켈레톤 데이터를 기반으로 내부선 생성
|
|
||||||
roof.innerLines = roof.innerLines || [];
|
|
||||||
roof.innerLines = createInnerLinesFromSkeleton(roofId, canvas, skeleton, textMode)
|
|
||||||
|
|
||||||
// 캔버스에 스켈레톤 상태 저장
|
|
||||||
if (!canvas.skeletonStates) {
|
|
||||||
canvas.skeletonStates = {}
|
|
||||||
canvas.skeletonLines = []
|
|
||||||
}
|
|
||||||
canvas.skeletonStates[roofId] = true
|
|
||||||
canvas.skeletonLines = [];
|
|
||||||
canvas.skeletonLines.push(...roof.innerLines)
|
|
||||||
roof.skeletonLines = canvas.skeletonLines;
|
|
||||||
|
|
||||||
const cleanSkeleton = {
|
|
||||||
Edges: skeleton.Edges.map(edge => ({
|
|
||||||
X1: edge.Edge.Begin.X,
|
|
||||||
Y1: edge.Edge.Begin.Y,
|
|
||||||
X2: edge.Edge.End.X,
|
|
||||||
Y2: edge.Edge.End.Y,
|
|
||||||
Polygon: edge.Polygon,
|
|
||||||
|
|
||||||
// Add other necessary properties, but skip circular references
|
|
||||||
})),
|
|
||||||
roofId: roofId,
|
|
||||||
// Add other necessary top-level properties
|
|
||||||
};
|
|
||||||
canvas.skeleton = [];
|
|
||||||
canvas.skeleton = cleanSkeleton
|
|
||||||
canvas.skeleton.lastPoints = points
|
|
||||||
canvas.set("skeleton", cleanSkeleton);
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
|
|
||||||
console.log('skeleton rendered.', canvas);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('스켈레톤 생성 중 오류 발생:', e)
|
|
||||||
if (canvas.skeletonStates) {
|
|
||||||
canvas.skeletonStates[roofId] = false
|
|
||||||
canvas.skeletonStates = {}
|
|
||||||
canvas.skeletonLines = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,9 +2,14 @@ import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|||||||
import { SkeletonBuilder } from '@/lib/skeletons'
|
import { SkeletonBuilder } from '@/lib/skeletons'
|
||||||
import { calcLineActualSize, calcLinePlaneSize, toGeoJSON } from '@/util/qpolygon-utils'
|
import { calcLineActualSize, calcLinePlaneSize, toGeoJSON } from '@/util/qpolygon-utils'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { findClosestLineToPoint, findOrthogonalPoint, getDegreeByChon } from '@/util/canvas-util'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
|
import { line } from 'framer-motion/m'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import { point } from '@turf/turf'
|
||||||
|
import { add, forEach } from 'mathjs'
|
||||||
|
import wallLine from '@/components/floor-plan/modal/wallLineOffset/type/WallLine'
|
||||||
|
import * as conole from 'mathjs'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 지붕 폴리곤의 스켈레톤(중심선)을 생성하고 캔버스에 그립니다.
|
* 지붕 폴리곤의 스켈레톤(중심선)을 생성하고 캔버스에 그립니다.
|
||||||
@ -429,7 +434,6 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
let roof = canvas?.getObjects().find((object) => object.id === 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 wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId)
|
||||||
let skeletonLines = []
|
let skeletonLines = []
|
||||||
let findPoints = [];
|
|
||||||
|
|
||||||
const processedInnerEdges = new Set()
|
const processedInnerEdges = new Set()
|
||||||
|
|
||||||
@ -760,7 +764,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
//wall.baseLine은 움직인라인
|
//wall.baseLine은 움직인라인
|
||||||
const movedLines = []
|
const movedLines = []
|
||||||
|
|
||||||
|
|
||||||
sortedWallLines.forEach((wallLine, index) => {
|
sortedWallLines.forEach((wallLine, index) => {
|
||||||
|
|
||||||
|
|
||||||
@ -837,34 +840,67 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
getAddLine(roofLine.startPoint, roofLine.endPoint, )
|
getAddLine(roofLine.startPoint, roofLine.endPoint)
|
||||||
|
|
||||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||||
|
|
||||||
const getInnerLines = (lines, point) => {
|
// Usage in your code:
|
||||||
|
// if (fullyMoved) {
|
||||||
}
|
// const result = adjustLinePoints({
|
||||||
|
// roofLine,
|
||||||
|
// currentRoofLine,
|
||||||
|
// wallBaseLine,
|
||||||
|
// origin,
|
||||||
|
// moveType: 'both' // Adjust both start and end points
|
||||||
|
// });
|
||||||
|
// newPStart = result.newPStart;
|
||||||
|
// newPEnd = result.newPEnd;
|
||||||
|
// getAddLine(newPStart, newPEnd, 'red');
|
||||||
|
// }
|
||||||
|
// else if (movedStart) {
|
||||||
|
// const result = adjustLinePoints({
|
||||||
|
// roofLine,
|
||||||
|
// currentRoofLine,
|
||||||
|
// wallBaseLine,
|
||||||
|
// origin,
|
||||||
|
// moveType: 'start' // Only adjust start point
|
||||||
|
// });
|
||||||
|
// newPStart = result.newPStart;
|
||||||
|
// getAddLine(newPStart, newPEnd, 'green');
|
||||||
|
// }
|
||||||
|
// else if (movedEnd) {
|
||||||
|
// const result = adjustLinePoints({
|
||||||
|
// roofLine,
|
||||||
|
// currentRoofLine,
|
||||||
|
// wallBaseLine,
|
||||||
|
// origin,
|
||||||
|
// moveType: 'end' // Only adjust end point
|
||||||
|
// });
|
||||||
|
// newPEnd = result.newPEnd;
|
||||||
|
// getAddLine(newPStart, newPEnd, 'orange');
|
||||||
|
// }
|
||||||
|
// canvas.renderAll()
|
||||||
//두 포인트가 변경된 라인인
|
//두 포인트가 변경된 라인인
|
||||||
if (fullyMoved) {
|
if (fullyMoved) {
|
||||||
//반시계방향향
|
//반시계방향향
|
||||||
|
|
||||||
|
|
||||||
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
|
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
|
||||||
|
|
||||||
if (getOrientation(roofLine) === 'vertical') {
|
if (getOrientation(roofLine) === 'vertical') {
|
||||||
//왼쪽 부터 roofLine, wallBaseLine
|
//왼쪽 부터 roofLine, wallBaseLine
|
||||||
if (newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top right
|
if (newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) {
|
||||||
newPStart.y = wallBaseLine.y1;
|
newPStart.y = wallBaseLine.y1;
|
||||||
getAddLine({ x: newPEnd.x, y: wallBaseLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
getAddLine({ x: newPEnd.x, y: wallBaseLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
||||||
findPoints.push({ x: wallBaseLine.x1, y: wallBaseLine.y1 });
|
|
||||||
} else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) {
|
} else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) {
|
||||||
newPEnd.y = wallBaseLine.y2;
|
newPEnd.y = wallBaseLine.y2;
|
||||||
getAddLine({ x: newPEnd.x, y: wallBaseLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
getAddLine({ x: newPEnd.x, y: wallBaseLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||||
|
|
||||||
} else if (newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) { //top left
|
} else if (newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {
|
||||||
newPEnd.y = wallBaseLine.y2;
|
newPEnd.y = wallBaseLine.y2;
|
||||||
getAddLine({ x: newPEnd.x, y: wallBaseLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
getAddLine({ x: newPEnd.x, y: wallBaseLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||||
findPoints.push({ x: wallBaseLine.x2, y: wallBaseLine.y2 });
|
|
||||||
|
|
||||||
} else if (wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) {
|
} else if (wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) {
|
||||||
newPStart.y = wallBaseLine.y1;
|
newPStart.y = wallBaseLine.y1;
|
||||||
@ -887,20 +923,13 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
} else if (getOrientation(roofLine) === 'horizontal') {
|
} else if (getOrientation(roofLine) === 'horizontal') {
|
||||||
|
|
||||||
|
|
||||||
if (newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPStart.x && newPStart.x <= wallBaseLine.x1) { //top left
|
if (newPEnd.x <= wallBaseLine.x2 && wallBaseLine.x2 <= newPStart.x && newPStart.x <= wallBaseLine.x1) { //위 왼쪽
|
||||||
newPStart.x = wallBaseLine.x1;
|
newPStart.x = wallBaseLine.x1;
|
||||||
//추가 수직
|
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
||||||
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 }, )
|
} else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x) { //아래오르쪽
|
||||||
//추가 라인?
|
|
||||||
|
|
||||||
findPoints.push({ x: wallBaseLine.x1, y: wallBaseLine.y1 });
|
|
||||||
|
|
||||||
} else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x) { //top right
|
|
||||||
newPEnd.x = wallBaseLine.x2;
|
newPEnd.x = wallBaseLine.x2;
|
||||||
//추가 수직
|
|
||||||
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||||
//추가 라인?
|
|
||||||
findPoints.push({ x: wallBaseLine.x2, y: wallBaseLine.y2 });
|
|
||||||
} else if (newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) { //위 오른쪽
|
} else if (newPStart.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) { //위 오른쪽
|
||||||
newPEnd.x = wallBaseLine.x2;
|
newPEnd.x = wallBaseLine.x2;
|
||||||
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||||
@ -909,15 +938,13 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
newPStart.x = wallBaseLine.x1;
|
newPStart.x = wallBaseLine.x1;
|
||||||
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
||||||
|
|
||||||
} else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= newPStart.x && newPStart.x <= wallBaseLine.x1) { // top center
|
} else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= newPStart.x && newPStart.x <= wallBaseLine.x1) { // 위가운데
|
||||||
|
|
||||||
newPEnd.x = wallBaseLine.x2;
|
newPEnd.x = wallBaseLine.x2;
|
||||||
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
getAddLine({ x: wallBaseLine.x2, y: newPEnd.y }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||||
newPStart.x = wallBaseLine.x1;
|
newPStart.x = wallBaseLine.x1;
|
||||||
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
||||||
//추가 라인?
|
|
||||||
findPoints.push({ x: wallBaseLine.x2, y: wallBaseLine.y2 });
|
|
||||||
findPoints.push({ x: wallBaseLine.x1, y: wallBaseLine.y1 });
|
|
||||||
} else if (wallBaseLine.x1 <= newPStart.x && newPStart.x <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) { // 아래가운데
|
} else if (wallBaseLine.x1 <= newPStart.x && newPStart.x <= newPEnd.x && newPEnd.x <= wallBaseLine.x2) { // 아래가운데
|
||||||
newPEnd.x = wallBaseLine.x1;
|
newPEnd.x = wallBaseLine.x1;
|
||||||
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
||||||
@ -947,16 +974,11 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||||
|
|
||||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top right
|
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //상단 왼쪽v
|
||||||
|
|
||||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||||
|
|
||||||
//대각선 라인을 보조라인으로 그린다.
|
|
||||||
if(isCross){
|
|
||||||
getAddLine({ x: roofLine.x1, y: currentRoofLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 }, 'yellow')
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//상단 오르쪽
|
}else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//상단 오르쪽
|
||||||
|
|
||||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||||
@ -1008,10 +1030,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
|
|
||||||
newPStart = { y: roofLine.y1, x: roofLine.x1 }
|
newPStart = { y: roofLine.y1, x: roofLine.x1 }
|
||||||
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 }
|
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 }
|
||||||
}else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= newPStart.x && newPStart.x <= wallBaseLine.x1) { //right / top
|
|
||||||
|
|
||||||
newPStart = { y: roofLine.y1, x: (isCross) ? currentRoofLine.x1 : wallBaseLine.x1 }
|
|
||||||
newPEnd ={ y: roofLine.y2, x: roofLine.x2 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//newPEnd = { x: (isCross) ? currentRoofLine.x1 : origin.x1, y: roofLine.y1 } //수직라인 접점까지지
|
//newPEnd = { x: (isCross) ? currentRoofLine.x1 : origin.x1, y: roofLine.y1 } //수직라인 접점까지지
|
||||||
@ -1023,7 +1041,7 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
|
|
||||||
} else if (movedEnd) { //start변경
|
} else if (movedEnd) { //start변경
|
||||||
|
|
||||||
//반시계방향 오렌지
|
//반시계방향
|
||||||
|
|
||||||
|
|
||||||
if (getOrientation(roofLine) === 'vertical') {
|
if (getOrientation(roofLine) === 'vertical') {
|
||||||
@ -1041,8 +1059,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top / left
|
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top / left
|
||||||
|
|
||||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||||
@ -1053,11 +1069,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||||
|
|
||||||
//대각선 라인을 보조라인으로 그린다.
|
|
||||||
if(isCross){
|
|
||||||
getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 }, 'yellow')
|
|
||||||
}
|
|
||||||
|
|
||||||
}else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { //하단 오른쪽v
|
}else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { //하단 오른쪽v
|
||||||
|
|
||||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||||
@ -1105,10 +1116,6 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
|
|
||||||
newPStart = { y: roofLine.y1, x: roofLine.x1 }
|
newPStart = { y: roofLine.y1, x: roofLine.x1 }
|
||||||
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 }
|
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 }
|
||||||
|
|
||||||
}else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= newPStart.x && newPStart.x <= wallBaseLine.x1){ //top center
|
|
||||||
newPStart = { y: roofLine.y1, x: roofLine.x1 }
|
|
||||||
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newPStart = { x: roofLine.x2, y: roofLine.y2 }
|
// newPStart = { x: roofLine.x2, y: roofLine.y2 }
|
||||||
@ -1129,22 +1136,12 @@ if(roof.moveUpDown??0 > 0) {
|
|||||||
//polygon 만들기
|
//polygon 만들기
|
||||||
console.log("innerLines:::::", innerLines)
|
console.log("innerLines:::::", innerLines)
|
||||||
console.log("movedLines", movedLines)
|
console.log("movedLines", movedLines)
|
||||||
// console.log("updateLines:::::", updateLines)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// --- 사용 예시 ---
|
// --- 사용 예시 ---
|
||||||
// const polygons = findConnectedLines(movedLines, innerLines, canvas, roofId, roof);
|
// const polygons = findConnectedLines(movedLines, innerLines, canvas, roofId, roof);
|
||||||
// console.log("polygon", polygons);
|
// console.log("polygon", polygons);
|
||||||
// canvas.renderAll
|
// canvas.renderAll
|
||||||
if (findPoints.length > 0) {
|
return innerLines;
|
||||||
// 모든 점에 대해 라인 업데이트를 누적
|
|
||||||
return findPoints.reduce((lines, point) => {
|
|
||||||
return updateAndAddLine(lines, point);
|
|
||||||
}, [...innerLines]);
|
|
||||||
|
|
||||||
}
|
|
||||||
return innerLines;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1853,11 +1850,7 @@ const isPointOnSegment = (point, segStart, segEnd) => {
|
|||||||
export {
|
export {
|
||||||
findAllIntersections,
|
findAllIntersections,
|
||||||
collectAllPoints,
|
collectAllPoints,
|
||||||
createPolygonsFromSkeletonLines,
|
createPolygonsFromSkeletonLines
|
||||||
preprocessPolygonCoordinates,
|
|
||||||
findOppositeLine,
|
|
||||||
createOrderedBasePoints,
|
|
||||||
createInnerLinesFromSkeleton
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -2414,41 +2407,41 @@ function getLineDirectionWithOrientation(p1, p2, wall) {
|
|||||||
* @param {number} epsilon - 허용 오차
|
* @param {number} epsilon - 허용 오차
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
// function isPointOnLineSegment(point, lineStart, lineEnd, epsilon = 0.1) {
|
function isPointOnLineSegment(point, lineStart, lineEnd, epsilon = 0.1) {
|
||||||
// const dx = lineEnd.x - lineStart.x;
|
const dx = lineEnd.x - lineStart.x;
|
||||||
// const dy = lineEnd.y - lineStart.y;
|
const dy = lineEnd.y - lineStart.y;
|
||||||
// const length = Math.sqrt(dx * dx + dy * dy);
|
const length = Math.sqrt(dx * dx + dy * dy);
|
||||||
//
|
|
||||||
// if (length === 0) {
|
if (length === 0) {
|
||||||
// // 선분의 길이가 0이면 시작점과의 거리만 확인
|
// 선분의 길이가 0이면 시작점과의 거리만 확인
|
||||||
// return Math.abs(point.x - lineStart.x) < epsilon && Math.abs(point.y - lineStart.y) < epsilon;
|
return Math.abs(point.x - lineStart.x) < epsilon && Math.abs(point.y - lineStart.y) < epsilon;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// // 점에서 선분의 시작점까지의 벡터
|
// 점에서 선분의 시작점까지의 벡터
|
||||||
// const toPoint = { x: point.x - lineStart.x, y: point.y - lineStart.y };
|
const toPoint = { x: point.x - lineStart.x, y: point.y - lineStart.y };
|
||||||
//
|
|
||||||
// // 선분 방향으로의 투영 길이
|
// 선분 방향으로의 투영 길이
|
||||||
// const t = (toPoint.x * dx + toPoint.y * dy) / (length * length);
|
const t = (toPoint.x * dx + toPoint.y * dy) / (length * length);
|
||||||
//
|
|
||||||
// // t가 0과 1 사이에 있어야 선분 위에 있음
|
// t가 0과 1 사이에 있어야 선분 위에 있음
|
||||||
// if (t < 0 || t > 1) {
|
if (t < 0 || t > 1) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// // 선분 위의 가장 가까운 점
|
// 선분 위의 가장 가까운 점
|
||||||
// const closestPoint = {
|
const closestPoint = {
|
||||||
// x: lineStart.x + t * dx,
|
x: lineStart.x + t * dx,
|
||||||
// y: lineStart.y + t * dy
|
y: lineStart.y + t * dy
|
||||||
// };
|
};
|
||||||
//
|
|
||||||
// // 점과 가장 가까운 점 사이의 거리
|
// 점과 가장 가까운 점 사이의 거리
|
||||||
// const dist = Math.sqrt(
|
const dist = Math.sqrt(
|
||||||
// Math.pow(point.x - closestPoint.x, 2) +
|
Math.pow(point.x - closestPoint.x, 2) +
|
||||||
// Math.pow(point.y - closestPoint.y, 2)
|
Math.pow(point.y - closestPoint.y, 2)
|
||||||
// );
|
);
|
||||||
//
|
|
||||||
// return dist < epsilon;
|
return dist < epsilon;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// selectLine과 baseLines 비교하여 방향 찾기
|
// selectLine과 baseLines 비교하여 방향 찾기
|
||||||
function findLineDirection(selectLine, baseLines) {
|
function findLineDirection(selectLine, baseLines) {
|
||||||
@ -3794,101 +3787,3 @@ function adjustLinePoints({ roofLine, currentRoofLine, wallBaseLine, origin, mov
|
|||||||
return { newPStart, newPEnd };
|
return { newPStart, newPEnd };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 주어진 점을 포함하는 라인을 찾는 함수
|
|
||||||
* @param {Array} lines - 검색할 라인 배열 (각 라인은 x1, y1, x2, y2 속성을 가져야 함)
|
|
||||||
* @param {Object} point - 찾고자 하는 점 {x, y}
|
|
||||||
* @param {number} [tolerance=0.1] - 점이 선분 위에 있는지 판단할 때의 허용 오차
|
|
||||||
* @returns {Object|null} 점을 포함하는 첫 번째 라인 또는 null
|
|
||||||
*/
|
|
||||||
function findLineContainingPoint(lines, point, tolerance = 0.1) {
|
|
||||||
if (!point || !lines || !lines.length) return null;
|
|
||||||
|
|
||||||
return lines.find(line => {
|
|
||||||
const { x1, y1, x2, y2 } = line;
|
|
||||||
return isPointOnLineSegment(point, {x: x1, y: y1}, {x: x2, y: y2}, tolerance);
|
|
||||||
}) || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 점이 선분 위에 있는지 확인하는 함수
|
|
||||||
* @param {Object} point - 확인할 점 {x, y}
|
|
||||||
* @param {Object} lineStart - 선분의 시작점 {x, y}
|
|
||||||
* @param {Object} lineEnd - 선분의 끝점 {x, y}
|
|
||||||
* @param {number} tolerance - 허용 오차
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
function isPointOnLineSegment(point, lineStart, lineEnd, tolerance = 0.1) {
|
|
||||||
const { x: px, y: py } = point;
|
|
||||||
const { x: x1, y: y1 } = lineStart;
|
|
||||||
const { x: x2, y: y2 } = lineEnd;
|
|
||||||
|
|
||||||
// 선분의 길이
|
|
||||||
const lineLength = Math.hypot(x2 - x1, y2 - y1);
|
|
||||||
|
|
||||||
// 점에서 선분의 양 끝점까지의 거리 합
|
|
||||||
const dist1 = Math.hypot(px - x1, py - y1);
|
|
||||||
const dist2 = Math.hypot(px - x2, py - y2);
|
|
||||||
|
|
||||||
// 점이 선분 위에 있는지 확인 (허용 오차 범위 내에서)
|
|
||||||
return Math.abs(dist1 + dist2 - lineLength) <= tolerance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a line in the innerLines array and returns the updated array
|
|
||||||
* @param {Array} innerLines - Array of line objects to update
|
|
||||||
* @param {Object} targetPoint - The point to find the line {x, y}
|
|
||||||
* @param {Object} wallBaseLine - The base line containing new coordinates
|
|
||||||
* @param {Function} getAddLine - Function to add a new line
|
|
||||||
* @returns {Array} Updated array of lines
|
|
||||||
*/
|
|
||||||
function updateAndAddLine(innerLines, targetPoint) {
|
|
||||||
|
|
||||||
// 1. Find the line containing the target point
|
|
||||||
const foundLine = findLineContainingPoint(innerLines, targetPoint);
|
|
||||||
if (!foundLine) {
|
|
||||||
console.warn('No line found containing the target point');
|
|
||||||
return [...innerLines];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Create a new array without the found line
|
|
||||||
const updatedLines = innerLines.filter(line =>
|
|
||||||
line !== foundLine &&
|
|
||||||
!(line.x1 === foundLine.x1 &&
|
|
||||||
line.y1 === foundLine.y1 &&
|
|
||||||
line.x2 === foundLine.x2 &&
|
|
||||||
line.y2 === foundLine.y2)
|
|
||||||
);
|
|
||||||
|
|
||||||
let isCurrentLine = false;
|
|
||||||
if(foundLine.y1 <= targetPoint.y && targetPoint.y <= foundLine.y2){
|
|
||||||
isCurrentLine = true;
|
|
||||||
}
|
|
||||||
const updatedLine = {
|
|
||||||
...foundLine,
|
|
||||||
left: (isCurrentLine)?targetPoint.x:foundLine.left,
|
|
||||||
top: (isCurrentLine)?targetPoint.y:foundLine.top,
|
|
||||||
x1: (isCurrentLine)?targetPoint.x:foundLine.x1,
|
|
||||||
y1: (isCurrentLine)?targetPoint.y:foundLine.y1,
|
|
||||||
x2: (isCurrentLine)?foundLine.x2:targetPoint.x,
|
|
||||||
y2: (isCurrentLine)?foundLine.y2:targetPoint.y,
|
|
||||||
startPoint: (isCurrentLine)?{ x: targetPoint.x, y: targetPoint.y }:foundLine.startPoint,
|
|
||||||
endPoint: (isCurrentLine)?foundLine.endPoint : { x: targetPoint.x, y: targetPoint.y}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 4. If it's a Fabric.js object, use set method if available
|
|
||||||
if (typeof foundLine.set === 'function') {
|
|
||||||
foundLine.set({
|
|
||||||
x1: (isCurrentLine)?targetPoint.x:foundLine.x1,
|
|
||||||
y1: (isCurrentLine)?targetPoint.y:foundLine.y1,
|
|
||||||
x2: (isCurrentLine)?foundLine.x2:targetPoint.x,
|
|
||||||
y2: (isCurrentLine)?foundLine.y2:targetPoint.y,
|
|
||||||
});
|
|
||||||
updatedLines.push(foundLine);
|
|
||||||
} else {
|
|
||||||
updatedLines.push(updatedLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return updatedLines;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user