좌우상하직선 구분완료

This commit is contained in:
yscha 2025-12-04 00:59:24 +09:00
parent 89aa772a01
commit 3663636b5d

View File

@ -952,7 +952,8 @@ if((roof.moveUpDown??0 > 0) ) {
// newPStart.y = wallBaseLine.y1;
// getAddLine({ x: newPEnd.x, y: wallBaseLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
} else if (wallBaseLine.y1 <= newPStart.y && newPStart.y <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) { // 아래가운데
} else if (wallBaseLine.y1 <= newPStart.y && newPStart.y <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {
// 아래가운데
// newPEnd.y = wallBaseLine.y1;
// getAddLine({ x: newPEnd.x, y: wallBaseLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
// newPStart.y = wallBaseLine.y2;
@ -969,17 +970,33 @@ if((roof.moveUpDown??0 > 0) ) {
? 'in' : 'out';
const condition = `${mLine.position}_${positionType}`;
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
switch (condition) {
case 'top_in':
console.log("findInteriorPoint result:::::::", isStartEnd);
let sPoint, ePoint;
if (isStartEnd.start ) {
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
newPStart.x = wallBaseLine.x1;
//추가 수직
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
//추가 라인?
findPoints.push({ x: wallBaseLine.x1, y: wallBaseLine.y1 });
getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y })
findPoints.push({ x: sPoint.x, y: sPoint.y });
}
if(isStartEnd.end){
ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2};
newPEnd.x = wallBaseLine.x2;
getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y })
findPoints.push({ x: ePoint.x, y: ePoint.y });
}
break;
case 'top_out':
console.log("findInteriorPoint result:::::::", isStartEnd);
const moveY = Math.abs(wallLine.y1 - wallBaseLine.y1)
const dist = Math.abs(roofLine.y1 - wallLine.y1)
const aStartX = Math.abs(newPStart.x + moveY)
@ -4232,3 +4249,133 @@ function PointBasedOnBaseLength(x1, y1, x2, y2) {
{ x: thirdX2, y: thirdY2 }
];
}
/**
* 선분의 시작점과 끝점 어느 쪽이 내부를 향하는지 반환
* @param {Object} line - {x1, y1, x2, y2} 형태의 선분
* @param {Array} polygonLines - 폴리곤을 구성하는 선분들의 배열
* @returns {Object} - { start: boolean, end: boolean } 시작점과 끝점의 내부 여부
*/
function findInteriorPoint(line, polygonLines) {
const { x1, y1, x2, y2 } = line;
// 선분의 방향 벡터
const dx = x2 - x1;
const dy = y2 - y1;
// 수직 벡터 (왼쪽으로 90도 회전)
const perpX = -dy;
const perpY = dx;
// 정규화
const length = Math.sqrt(perpX * perpX + perpY * perpY);
const nx = perpX / length;
const ny = perpY / length;
// 오프셋 계산 (선분 길이의 1% 또는 최소 0.1)
const lineLength = Math.sqrt(dx*dx + dy*dy);
const offset = Math.max(0.1, lineLength * 0.01);
// 시작점에서 수직 방향으로 약간 떨어진 점
const testPoint = {
x: x1 + nx * offset,
y: y1 + ny * offset
};
// 이 점이 폴리곤 내부에 있는지 확인
const isInside = isPointInPolygon(testPoint, polygonLines);
// 시작점이 내부를 향하는지 여부
return {
start: isInside,
// 끝점 방향은 시작점과 반대
end: !isInside
};
}
// 점이 선분의 어느 쪽에 있는지 확인
function isPointInDirection(line, point) {
const {x1, y1, x2, y2} = line;
const {x, y} = point;
return ((x2 - x1) * (y - y1) - (y2 - y1) * (x - x1)) > 0;
}
/**
* 점이 폴리곤 내부에 있는지 확인 (Ray Casting 알고리즘)
* @param {Object} point - {x, y} 형태의
* @param {Array} polygonLines - 폴리곤을 구성하는 선분들의 배열
* @returns {boolean} - 점이 폴리곤 내부에 있으면 true, 아니면 false
*/
function isPointInPolygon(point, polygonLines) {
if (!polygonLines || polygonLines.length === 0) {
console.log("경고: 폴리곤 선분이 비어있습니다.");
return false;
}
const x = point.x;
const y = point.y;
let inside = false;
let intersections = 0;
// 폴리곤의 모든 선분에 대해 반복
for (let i = 0; i < polygonLines.length; i++) {
const line = polygonLines[i];
const x1 = line.x1;
const y1 = line.y1;
const x2 = line.x2;
const y2 = line.y2;
// 점이 선분 위에 있는지 확인
if (isPointOnLineSegment2(point, {x: x1, y: y1}, {x: x2, y: y2}, 0.1)) {
console.log(`점 (${x}, ${y})은 선분 [(${x1}, ${y1}), (${x2}, ${y2})] 위에 있습니다.`);
return true; // 경계선 위의 점은 내부로 간주
}
// Ray casting 알고리즘
// 점의 y 좌표가 선분의 y 범위 내에 있는지 확인
const yInRange = (y1 > y) !== (y2 > y);
if (yInRange) {
// x 교차점 계산
const xIntersect = (y - y1) * (x2 - x1) / (y2 - y1) + x1;
// 교차점이 점의 오른쪽에 있는지 확인
if (x <= xIntersect) {
inside = !inside;
intersections++;
}
}
}
console.log(`폴리곤 검사 결과: 점 (${x}, ${y})은 ${inside ? '내부' : '외부'}에 있습니다. (교차점 수: ${intersections})`);
return inside;
}
/**
* 점이 선분 위에 있는지 확인
* @param {Object} point - 확인할 {x, y}
* @param {Object} lineStart - 선분의 시작점 {x, y}
* @param {Object} lineEnd - 선분의 끝점 {x, y}
* @param {number} tolerance - 오차 허용 범위
* @returns {boolean} - 점이 선분 위에 있으면 true, 아니면 false
*/
function isPointOnLineSegment2(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);
// 점이 선분 위에 있는지 확인 (오차 허용 범위 내에서)
const isOnSegment = Math.abs((dist1 + dist2) - lineLength) <= tolerance;
if (isOnSegment) {
console.log(`점 (${px}, ${py})은 선분 [(${x1}, ${y1}), (${x2}, ${y2})] 위에 있습니다.`);
}
return isOnSegment;
}