알고리즘 변경

This commit is contained in:
Cha 2025-11-06 23:06:35 +09:00
parent a3d1704390
commit ee79c0e680

View File

@ -532,12 +532,14 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
selectable:(!line.attributes.isOuterEdge),
roofId: roofId,
});
canvas.add(innerLine);
innerLine.bringToFront();
existingLines.add(lineKey); // 추가된 라인을 추적
//skeleton 라인에서 처마선은 삭제
if(innerLine.lineName !== 'outerLine'){
canvas.add(innerLine);
innerLine.bringToFront();
existingLines.add(lineKey); // 추가된 라인을 추적
// canvas.add(innerLine);
// innerLine.bringToFront();
// existingLines.add(lineKey); // 추가된 라인을 추적
}else{
const coordinateText = new fabric.Text(`(${Math.round(p1.x)}, ${Math.round(p1.y)})`, {
left: p1.x + 5, // 좌표점에서 약간 오른쪽으로 이동
@ -615,7 +617,7 @@ function processEavesEdge(roofId, canvas, skeleton, edgeResult, skeletonLines) {
// 지붕 경계선과 교차 확인 및 클리핑
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])
addRawLine(roof.id, skeletonLines, clippedLine.p1, clippedLine.p2, 'ridge', 'red', 5, pitch, isOuterLine);
// }
@ -1641,7 +1643,7 @@ function clipLineToRoofBoundary(p1, p2, roofLines, selectLine) {
* @param {Array} roofLines - 다각형을 구성하는 선분들
* @returns {boolean} 점이 다각형 내부에 있으면 true
*/
function isPointInsidePolygon(point, roofLines) {
function isPointInsidePolygon2(point, roofLines) {
let inside = false;
const x = point.x;
const y = point.y;
@ -1656,11 +1658,78 @@ function isPointInsidePolygon(point, roofLines) {
if (((y1 > y) !== (y2 > y)) && (x < (x2 - x1) * (y - y1) / (y2 - y1) + x1)) {
inside = !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를 계산합니다.
* p = p1 + t * (p2 - p1)에서 t 값을 구합니다.