좌우상하직선 구분완료
This commit is contained in:
parent
89aa772a01
commit
3663636b5d
@ -952,7 +952,8 @@ if((roof.moveUpDown??0 > 0) ) {
|
|||||||
// 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 })
|
||||||
|
|
||||||
} 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;
|
// newPEnd.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 })
|
||||||
// newPStart.y = wallBaseLine.y2;
|
// newPStart.y = wallBaseLine.y2;
|
||||||
@ -969,17 +970,33 @@ if((roof.moveUpDown??0 > 0) ) {
|
|||||||
? 'in' : 'out';
|
? 'in' : 'out';
|
||||||
|
|
||||||
const condition = `${mLine.position}_${positionType}`;
|
const condition = `${mLine.position}_${positionType}`;
|
||||||
|
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
|
||||||
|
|
||||||
switch (condition) {
|
switch (condition) {
|
||||||
case 'top_in':
|
case 'top_in':
|
||||||
newPStart.x = wallBaseLine.x1;
|
|
||||||
//추가 수직
|
console.log("findInteriorPoint result:::::::", isStartEnd);
|
||||||
getAddLine({ x: wallBaseLine.x1, y: newPEnd.y }, { x: wallBaseLine.x1, y: wallBaseLine.y1 })
|
|
||||||
//추가 라인?
|
let sPoint, ePoint;
|
||||||
findPoints.push({ x: wallBaseLine.x1, y: wallBaseLine.y1 });
|
if (isStartEnd.start ) {
|
||||||
|
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
|
||||||
|
newPStart.x = wallBaseLine.x1;
|
||||||
|
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;
|
break;
|
||||||
case 'top_out':
|
case 'top_out':
|
||||||
|
|
||||||
|
console.log("findInteriorPoint result:::::::", isStartEnd);
|
||||||
|
|
||||||
const moveY = Math.abs(wallLine.y1 - wallBaseLine.y1)
|
const moveY = Math.abs(wallLine.y1 - wallBaseLine.y1)
|
||||||
const dist = Math.abs(roofLine.y1 - wallLine.y1)
|
const dist = Math.abs(roofLine.y1 - wallLine.y1)
|
||||||
const aStartX = Math.abs(newPStart.x + moveY)
|
const aStartX = Math.abs(newPStart.x + moveY)
|
||||||
@ -4232,3 +4249,133 @@ function PointBasedOnBaseLength(x1, y1, x2, y2) {
|
|||||||
{ x: thirdX2, y: thirdY2 }
|
{ 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;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user