Merge pull request 'dev' (#414) from dev into prd-deploy
Reviewed-on: #414
This commit is contained in:
commit
81f9945b72
@ -16,6 +16,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
|
|||||||
children: [],
|
children: [],
|
||||||
padding: 5,
|
padding: 5,
|
||||||
textVisible: true,
|
textVisible: true,
|
||||||
|
textBaseline: 'alphabetic',
|
||||||
initialize: function (points, options, length = 0) {
|
initialize: function (points, options, length = 0) {
|
||||||
// 소수점 전부 제거
|
// 소수점 전부 제거
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { calculateAngle, drawGableRoof, drawRidgeRoof, drawShedRoof, toGeoJSON }
|
|||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||||
import Big from 'big.js'
|
import Big from 'big.js'
|
||||||
|
import { drawSkeletonRidgeRoof } from '@/util/skeleton-utils'
|
||||||
|
|
||||||
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||||
type: 'QPolygon',
|
type: 'QPolygon',
|
||||||
|
|||||||
@ -370,7 +370,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, pla
|
|||||||
}}
|
}}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: false,
|
allowNegative: false,
|
||||||
allowDecimal: false //(index !== 0),
|
allowDecimal: true //(index !== 0),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -470,7 +470,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
/*
|
||||||
//2. 연결이 끊어진 스켈레톤 선을 찾아 연장합니다.
|
//2. 연결이 끊어진 스켈레톤 선을 찾아 연장합니다.
|
||||||
const { disconnectedLines } = findDisconnectedSkeletonLines(skeletonLines, roof.lines);
|
const { disconnectedLines } = findDisconnectedSkeletonLines(skeletonLines, roof.lines);
|
||||||
|
|
||||||
@ -492,8 +492,9 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
trimIntersectingExtendedLines(skeletonLines, disconnectedLines);
|
trimIntersectingExtendedLines(skeletonLines, disconnectedLines);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//2. 연결이 끊어진 라인이 있을경우 찾아서 추가한다(동 이동일때)
|
||||||
|
|
||||||
// 3. 최종적으로 정리된 스켈레톤 선들을 QLine 객체로 변환하여 캔버스에 추가합니다.
|
// 3. 최종적으로 정리된 스켈레톤 선들을 QLine 객체로 변환하여 캔버스에 추가합니다.
|
||||||
const innerLines = [];
|
const innerLines = [];
|
||||||
@ -539,6 +540,135 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
innerLine.bringToFront();
|
innerLine.bringToFront();
|
||||||
existingLines.add(lineKey); // 추가된 라인을 추적
|
existingLines.add(lineKey); // 추가된 라인을 추적
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
|
|
||||||
|
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)))) { // 끝점도 다른 경우
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 (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,
|
||||||
|
});
|
||||||
|
|
||||||
|
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 = [];
|
||||||
|
|
||||||
|
|
||||||
|
if (!wall.lines || !wall.baseLines) {
|
||||||
|
return wall.baseLines || wall.lines || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 길이가 다른 경우 baseLines 반환
|
||||||
|
if (wall.lines.length !== wall.baseLines.length) {
|
||||||
|
return wall.baseLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//그려지는 처마라인이 처마 && 포인터모두가 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, // 좌표점에서 약간 위로 이동
|
||||||
@ -582,8 +712,8 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) {
|
|||||||
|
|
||||||
);
|
);
|
||||||
if(!outerLine) {
|
if(!outerLine) {
|
||||||
outerLine = findMatchingLine(edgeResult.Polygon, roof, roof.points);
|
outerLine = findMatchingLine(edgeResult.Polygon, roof, roof.points);
|
||||||
//console.log('Has matching line:', outerLine);
|
console.log('Has matching line:', outerLine);
|
||||||
}
|
}
|
||||||
let pitch = outerLine?.attributes?.pitch??0
|
let pitch = outerLine?.attributes?.pitch??0
|
||||||
|
|
||||||
@ -615,7 +745,7 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) {
|
|||||||
|
|
||||||
// 지붕 경계선과 교차 확인 및 클리핑
|
// 지붕 경계선과 교차 확인 및 클리핑
|
||||||
const clippedLine = clipLineToRoofBoundary(p1, p2, roof.lines, roof.moveSelectLine);
|
const clippedLine = clipLineToRoofBoundary(p1, p2, roof.lines, roof.moveSelectLine);
|
||||||
//console.log('clipped line', clippedLine.p1, clippedLine.p2);
|
console.log('clipped line', clippedLine.p1, clippedLine.p2);
|
||||||
const isOuterLine = isOuterEdge(clippedLine.p1, clippedLine.p2, [edgeResult.Edge])
|
const isOuterLine = isOuterEdge(clippedLine.p1, clippedLine.p2, [edgeResult.Edge])
|
||||||
addRawLine(roof.id, skeletonLines, clippedLine.p1, clippedLine.p2, 'ridge', 'red', 5, pitch, isOuterLine);
|
addRawLine(roof.id, skeletonLines, clippedLine.p1, clippedLine.p2, 'ridge', 'red', 5, pitch, isOuterLine);
|
||||||
// }
|
// }
|
||||||
@ -734,13 +864,13 @@ function isOuterEdge(p1, p2, edges) {
|
|||||||
* 스켈레톤 라인 배열에 새로운 라인을 추가합니다. (중복 방지)
|
* 스켈레톤 라인 배열에 새로운 라인을 추가합니다. (중복 방지)
|
||||||
* @param id
|
* @param id
|
||||||
* @param {Array} skeletonLines - 스켈레톤 라인 배열
|
* @param {Array} skeletonLines - 스켈레톤 라인 배열
|
||||||
* @param {Set} processedInnerEdges - 처리된 Edge 키 Set
|
|
||||||
* @param {object} p1 - 시작점
|
* @param {object} p1 - 시작점
|
||||||
* @param {object} p2 - 끝점
|
* @param {object} p2 - 끝점
|
||||||
* @param {string} lineType - 라인 타입
|
* @param {string} lineType - 라인 타입
|
||||||
* @param {string} color - 색상
|
* @param {string} color - 색상
|
||||||
* @param {number} width - 두께
|
* @param {number} width - 두께
|
||||||
* @param currentDegree
|
* @param pitch
|
||||||
|
* @param isOuterLine
|
||||||
*/
|
*/
|
||||||
function addRawLine(id, skeletonLines, p1, p2, lineType, color, width, pitch, isOuterLine) {
|
function addRawLine(id, skeletonLines, p1, p2, lineType, color, width, pitch, isOuterLine) {
|
||||||
// const edgeKey = [`${p1.x.toFixed(1)},${p1.y.toFixed(1)}`, `${p2.x.toFixed(1)},${p2.y.toFixed(1)}`].sort().join('|');
|
// const edgeKey = [`${p1.x.toFixed(1)},${p1.y.toFixed(1)}`, `${p2.x.toFixed(1)},${p2.y.toFixed(1)}`].sort().join('|');
|
||||||
@ -1560,14 +1690,14 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) {
|
|||||||
// p2가 다각형 내부에 있는지 확인
|
// p2가 다각형 내부에 있는지 확인
|
||||||
const p2Inside = isPointInsidePolygon(p2, roofLines);
|
const p2Inside = isPointInsidePolygon(p2, roofLines);
|
||||||
|
|
||||||
console.log('p1Inside:', p1Inside, 'p2Inside:', p2Inside);
|
//console.log('p1Inside:', p1Inside, 'p2Inside:', p2Inside);
|
||||||
|
|
||||||
// 두 점 모두 내부에 있으면 그대로 반환
|
// 두 점 모두 내부에 있으면 그대로 반환
|
||||||
if (p1Inside && p2Inside) {
|
if (p1Inside && p2Inside) {
|
||||||
if(!selectLine || isDiagonal){
|
if(!selectLine || isDiagonal){
|
||||||
return { p1: clippedP1, p2: clippedP2 };
|
return { p1: clippedP1, p2: clippedP2 };
|
||||||
}
|
}
|
||||||
console.log('평행선::', clippedP1, clippedP2)
|
//console.log('평행선::', clippedP1, clippedP2)
|
||||||
return { p1: clippedP1, p2: clippedP2 };
|
return { p1: clippedP1, p2: clippedP2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1600,20 +1730,20 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) {
|
|||||||
if (!p1Inside && !p2Inside) {
|
if (!p1Inside && !p2Inside) {
|
||||||
// 두 점 모두 외부에 있는 경우
|
// 두 점 모두 외부에 있는 경우
|
||||||
if (intersections.length >= 2) {
|
if (intersections.length >= 2) {
|
||||||
console.log('Both outside, using intersection points');
|
//console.log('Both outside, using intersection points');
|
||||||
clippedP1.x = intersections[0].point.x;
|
clippedP1.x = intersections[0].point.x;
|
||||||
clippedP1.y = intersections[0].point.y;
|
clippedP1.y = intersections[0].point.y;
|
||||||
clippedP2.x = intersections[1].point.x;
|
clippedP2.x = intersections[1].point.x;
|
||||||
clippedP2.y = intersections[1].point.y;
|
clippedP2.y = intersections[1].point.y;
|
||||||
} else {
|
} else {
|
||||||
console.log('Both outside, no valid intersections - returning original');
|
//console.log('Both outside, no valid intersections - returning original');
|
||||||
// 교차점이 충분하지 않으면 원본 반환
|
// 교차점이 충분하지 않으면 원본 반환
|
||||||
return { p1: clippedP1, p2: clippedP2 };
|
return { p1: clippedP1, p2: clippedP2 };
|
||||||
}
|
}
|
||||||
} else if (!p1Inside && p2Inside) {
|
} else if (!p1Inside && p2Inside) {
|
||||||
// p1이 외부, p2가 내부
|
// p1이 외부, p2가 내부
|
||||||
if (intersections.length > 0) {
|
if (intersections.length > 0) {
|
||||||
console.log('p1 outside, p2 inside - moving p1 to intersection');
|
//console.log('p1 outside, p2 inside - moving p1 to intersection');
|
||||||
clippedP1.x = intersections[0].point.x;
|
clippedP1.x = intersections[0].point.x;
|
||||||
clippedP1.y = intersections[0].point.y;
|
clippedP1.y = intersections[0].point.y;
|
||||||
// p2는 이미 내부에 있으므로 원본 유지
|
// p2는 이미 내부에 있으므로 원본 유지
|
||||||
@ -1623,7 +1753,7 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) {
|
|||||||
} else if (p1Inside && !p2Inside) {
|
} else if (p1Inside && !p2Inside) {
|
||||||
// p1이 내부, p2가 외부
|
// p1이 내부, p2가 외부
|
||||||
if (intersections.length > 0) {
|
if (intersections.length > 0) {
|
||||||
console.log('p1 inside, p2 outside - moving p2 to intersection');
|
//console.log('p1 inside, p2 outside - moving p2 to intersection');
|
||||||
// p1은 이미 내부에 있으므로 원본 유지
|
// p1은 이미 내부에 있으므로 원본 유지
|
||||||
clippedP1.x = p1.x;
|
clippedP1.x = p1.x;
|
||||||
clippedP1.y = p1.y;
|
clippedP1.y = p1.y;
|
||||||
@ -1641,7 +1771,7 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) {
|
|||||||
* @param {Array} roofLines - 다각형을 구성하는 선분들
|
* @param {Array} roofLines - 다각형을 구성하는 선분들
|
||||||
* @returns {boolean} 점이 다각형 내부에 있으면 true
|
* @returns {boolean} 점이 다각형 내부에 있으면 true
|
||||||
*/
|
*/
|
||||||
function isPointInsidePolygon(point, roofLines) {
|
function isPointInsidePolygon2(point, roofLines) {
|
||||||
let inside = false;
|
let inside = false;
|
||||||
const x = point.x;
|
const x = point.x;
|
||||||
const y = point.y;
|
const y = point.y;
|
||||||
@ -1661,6 +1791,72 @@ function isPointInsidePolygon(point, roofLines) {
|
|||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isPointInsidePolygon(point, roofLines) {
|
||||||
|
// 1. 먼저 경계선 위에 있는지 확인 (방향 무관)
|
||||||
|
if (isOnBoundaryDirectionIndependent(point, roofLines)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 내부/외부 판단 (기존 알고리즘)
|
||||||
|
let winding = 0;
|
||||||
|
const x = point.x;
|
||||||
|
const y = point.y;
|
||||||
|
|
||||||
|
for (let i = 0; i < roofLines.length; i++) {
|
||||||
|
const line = roofLines[i];
|
||||||
|
const x1 = line.x1, y1 = line.y1;
|
||||||
|
const x2 = line.x2, y2 = line.y2;
|
||||||
|
|
||||||
|
if (y1 <= y) {
|
||||||
|
if (y2 > y) {
|
||||||
|
const orientation = (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1);
|
||||||
|
if (orientation > 0) winding++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (y2 <= y) {
|
||||||
|
const orientation = (x2 - x1) * (y - y1) - (x - x1) * (y2 - y1);
|
||||||
|
if (orientation < 0) winding--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return winding !== 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 방향에 무관한 경계선 검사
|
||||||
|
function isOnBoundaryDirectionIndependent(point, roofLines) {
|
||||||
|
const tolerance = 1e-10;
|
||||||
|
|
||||||
|
for (const line of roofLines) {
|
||||||
|
if (isPointOnLineSegmentDirectionIndependent(point, line, tolerance)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 핵심: 방향에 무관한 선분 위 점 검사
|
||||||
|
function isPointOnLineSegmentDirectionIndependent(point, line, tolerance) {
|
||||||
|
const x = point.x, y = point.y;
|
||||||
|
const x1 = line.x1, y1 = line.y1;
|
||||||
|
const x2 = line.x2, y2 = line.y2;
|
||||||
|
|
||||||
|
// 방향에 무관하게 경계 상자 체크
|
||||||
|
const minX = Math.min(x1, x2);
|
||||||
|
const maxX = Math.max(x1, x2);
|
||||||
|
const minY = Math.min(y1, y2);
|
||||||
|
const maxY = Math.max(y1, y2);
|
||||||
|
|
||||||
|
if (x < minX - tolerance || x > maxX + tolerance ||
|
||||||
|
y < minY - tolerance || y > maxY + tolerance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 외적을 이용한 직선 위 판단 (방향 무관)
|
||||||
|
const cross = (y - y1) * (x2 - x1) - (x - x1) * (y2 - y1);
|
||||||
|
return Math.abs(cross) < tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 선분 위의 점에 대한 매개변수 t를 계산합니다.
|
* 선분 위의 점에 대한 매개변수 t를 계산합니다.
|
||||||
* p = p1 + t * (p2 - p1)에서 t 값을 구합니다.
|
* p = p1 + t * (p2 - p1)에서 t 값을 구합니다.
|
||||||
@ -1989,19 +2185,19 @@ export const getSelectLinePosition = (wall, selectLine, options = {}) => {
|
|||||||
|
|
||||||
const { x1, y1, x2, y2 } = lineCoords;
|
const { x1, y1, x2, y2 } = lineCoords;
|
||||||
|
|
||||||
console.log('wall.points', wall.baseLines);
|
//console.log('wall.points', wall.baseLines);
|
||||||
for(const line of wall.baseLines) {
|
for(const line of wall.baseLines) {
|
||||||
console.log('line', line);
|
//console.log('line', line);
|
||||||
const basePoint = extractLineCoords(line);
|
const basePoint = extractLineCoords(line);
|
||||||
const { x1: bx1, y1: by1, x2: bx2, y2: by2 } = basePoint;
|
const { x1: bx1, y1: by1, x2: bx2, y2: by2 } = basePoint;
|
||||||
console.log('x1, y1, x2, y2', bx1, by1, bx2, by2);
|
//console.log('x1, y1, x2, y2', bx1, by1, bx2, by2);
|
||||||
|
|
||||||
// 객체 비교 대신 좌표값 비교
|
// 객체 비교 대신 좌표값 비교
|
||||||
if (Math.abs(bx1 - x1) < 0.1 &&
|
if (Math.abs(bx1 - x1) < 0.1 &&
|
||||||
Math.abs(by1 - y1) < 0.1 &&
|
Math.abs(by1 - y1) < 0.1 &&
|
||||||
Math.abs(bx2 - x2) < 0.1 &&
|
Math.abs(bx2 - x2) < 0.1 &&
|
||||||
Math.abs(by2 - y2) < 0.1) {
|
Math.abs(by2 - y2) < 0.1) {
|
||||||
console.log('basePoint 일치!!!', basePoint);
|
//console.log('basePoint 일치!!!', basePoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2009,11 +2205,11 @@ export const getSelectLinePosition = (wall, selectLine, options = {}) => {
|
|||||||
// 라인 방향 분석
|
// 라인 방향 분석
|
||||||
const lineInfo = analyzeLineOrientation(x1, y1, x2, y2, epsilon);
|
const lineInfo = analyzeLineOrientation(x1, y1, x2, y2, epsilon);
|
||||||
|
|
||||||
if (debug) {
|
// if (debug) {
|
||||||
console.log('=== getSelectLinePosition ===');
|
// console.log('=== getSelectLinePosition ===');
|
||||||
console.log('selectLine 좌표:', lineCoords);
|
// console.log('selectLine 좌표:', lineCoords);
|
||||||
console.log('라인 방향:', lineInfo.orientation);
|
// console.log('라인 방향:', lineInfo.orientation);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 라인의 중점
|
// 라인의 중점
|
||||||
const midX = (x1 + x2) / 2;
|
const midX = (x1 + x2) / 2;
|
||||||
@ -2032,11 +2228,11 @@ export const getSelectLinePosition = (wall, selectLine, options = {}) => {
|
|||||||
const topIsInside = checkPointInPolygon(topTestPoint, wall);
|
const topIsInside = checkPointInPolygon(topTestPoint, wall);
|
||||||
const bottomIsInside = checkPointInPolygon(bottomTestPoint, wall);
|
const bottomIsInside = checkPointInPolygon(bottomTestPoint, wall);
|
||||||
|
|
||||||
if (debug) {
|
// if (debug) {
|
||||||
console.log('수평선 테스트:');
|
// console.log('수평선 테스트:');
|
||||||
console.log(' 위쪽 포인트:', topTestPoint, '-> 내부:', topIsInside);
|
// console.log(' 위쪽 포인트:', topTestPoint, '-> 내부:', topIsInside);
|
||||||
console.log(' 아래쪽 포인트:', bottomTestPoint, '-> 내부:', bottomIsInside);
|
// console.log(' 아래쪽 포인트:', bottomTestPoint, '-> 내부:', bottomIsInside);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// top 조건: 위쪽이 외부, 아래쪽이 내부
|
// top 조건: 위쪽이 외부, 아래쪽이 내부
|
||||||
if (!topIsInside && bottomIsInside) {
|
if (!topIsInside && bottomIsInside) {
|
||||||
@ -2094,9 +2290,9 @@ export const getSelectLinePosition = (wall, selectLine, options = {}) => {
|
|||||||
midPoint: { x: midX, y: midY }
|
midPoint: { x: midX, y: midY }
|
||||||
};
|
};
|
||||||
|
|
||||||
if (debug) {
|
// if (debug) {
|
||||||
console.log('최종 결과:', result);
|
// console.log('최종 결과:', result);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user