sortedPoints 수정

This commit is contained in:
hyojun.choi 2024-07-30 17:55:30 +09:00
parent a614438b27
commit e10e0d5b58

View File

@ -292,56 +292,6 @@ export const getDirectionByPoint = (a, b) => {
}
}
/**
* 선분의 교차점을 찾는 함수입니다. 함수는 선분이 실제로 교차하는 지점 내에서 교차하는지 확인합니다.
* @param {Object} line1 번째 선분, {x1, y1, x2, y2} 형태의 객체
* @param {Object} line2 번째 선분, {x1, y1, x2, y2} 형태의 객체
* @returns {{x: number, y: number}|null} 교차점의 좌표를 반환하거나, 교차점이 없으면 null을 반환합니다.
*/
export function calculateIntersection(line1, line2) {
const { x1: x1_1, y1: y1_1, x2: x2_1, y2: y2_1 } = line1
const { x1: x1_2, y1: y1_2, x2: x2_2, y2: y2_2 } = line2
const denominator = (x1_1 - x2_1) * (y1_2 - y2_2) - (y1_1 - y2_1) * (x1_2 - x2_2)
if (denominator === 0) return null // 선분이 평행하거나 일치하는 경우
const t = ((x1_1 - x1_2) * (y1_2 - y2_2) - (y1_1 - y1_2) * (x1_2 - x2_2)) / denominator
const u = -((x1_1 - x2_1) * (y1_1 - y1_2) - (y1_1 - y2_1) * (x1_1 - x1_2)) / denominator
// t와 u가 모두 0과 1 사이에 있을 때, 선분 내에서 교차
if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
const intersectionX = x1_1 + t * (x2_1 - x1_1)
const intersectionY = y1_1 + t * (y2_1 - y1_1)
// Determine the min and max for line1 and line2 for both x and y
const line1MinX = Math.min(line1.x1, line1.x2)
const line1MaxX = Math.max(line1.x1, line1.x2)
const line2MinX = Math.min(line2.x1, line2.x2)
const line2MaxX = Math.max(line2.x1, line2.x2)
const line1MinY = Math.min(line1.y1, line1.y2)
const line1MaxY = Math.max(line1.y1, line1.y2)
const line2MinY = Math.min(line2.y1, line2.y2)
const line2MaxY = Math.max(line2.y1, line2.y2)
// 교차점이 선분의 범위 내에 있는지 확인
if (
intersectionX >= line1MinX &&
intersectionX <= line1MaxX &&
intersectionX >= line2MinX &&
intersectionX <= line2MaxX &&
intersectionY >= line1MinY &&
intersectionY <= line1MaxY &&
intersectionY >= line2MinY &&
intersectionY <= line2MaxY
) {
return { x: Math.round(intersectionX), y: Math.round(intersectionY) }
}
}
return null // 교차점이 선분의 범위 내에 없음
}
export const findIntersection1 = (line1, line2) => {
const { x1, y1, x2, y2 } = line1 // 첫 번째 선의 두 점
@ -372,7 +322,7 @@ export const findIntersection1 = (line1, line2) => {
return { x, y }
}
export const calculateIntersection2 = (line1, line2) => {
export const calculateIntersection = (line1, line2) => {
const result = intersect([line1.x1, line1.y1], [line1.x2, line1.y2], [line2.x1, line2.y1], [line2.x2, line2.y2])
if (!result) {
@ -425,68 +375,32 @@ export function findOrthogonalPoint(line1, line2) {
*/
export const sortedPoints = (points) => {
const copyPoints = [...points]
//points를 x,y좌표를 기준으로 정렬합니다.
copyPoints.sort((a, b) => {
if (a.x === b.x) {
return a.y - b.y
}
return a.x - b.x
copyPoints.forEach((point) => {
point.x1 = point.x
point.y1 = point.y
const nextPoint = copyPoints[(copyPoints.indexOf(point) + 1) % copyPoints.length]
point.x2 = nextPoint.x
point.y2 = nextPoint.y
})
// 이때 copyPoints를 순회하며 최초엔 x값을 비교하여 같은 점을 찾는다. 이때 이 점이 2번째 점이 된다.
// 그 다음점은 2번째 점과 y값이 같은 점이 된다.
// 또 그다음 점은 3번째 점과 x값이 같은 점이 된다.
// 이를 반복하여 copyPoints를 재배열한다.
const resultPoints = [copyPoints[0]]
let index = 1
let currentPoint = { ...copyPoints[0] }
copyPoints.splice(0, 1)
while (index < points.length) {
if (index === points.length - 1) {
resultPoints.push(copyPoints[0])
index++
break
} else if (index % 2 === 0) {
// 짝수번째는 y값이 같은 점을 찾는다.
for (let i = 0; i < copyPoints.length; i++) {
// y값이 같은 point가 많은 경우 그 중 x값이 가장 큰걸 찾는다.
let temp = copyPoints.filter((point) => point.y === currentPoint.y)
if (temp.length === 0) {
// temp가 비어있을 경우 copyPoints에서 가장 가까운 점을 찾는다.
temp = Array.of(findClosestPointByY(currentPoint, copyPoints))
}
// temp중 x값이 가장 가까운 값
// copyPoint에서 x1, y1 값을 기준으로 정렬 후 첫번째 값
const startIndex = getStartIndex(copyPoints)
const min = temp.reduce((prev, current) => (Math.abs(current.x - currentPoint.x) <= Math.abs(prev.x - currentPoint.x) ? current : prev))
const resultPoints = [copyPoints[startIndex]]
resultPoints.push(min)
currentPoint = min
copyPoints.splice(copyPoints.indexOf(min), 1)
index++
break
}
} else {
// 홀수번째는 x값이 같은 점을 찾는다.
for (let i = 0; i < copyPoints.length; i++) {
// x값이 같은 point가 많은 경우 그 중 y값이 가장 큰걸 찾는다.
let temp = copyPoints.filter((point) => point.x === currentPoint.x)
if (temp.length === 0) {
// temp가 비어있을 경우 copyPoints에서 가장 가까운 점을 찾는다.
let currentPoint = copyPoints[startIndex]
temp = Array.of(findClosestPointByX(currentPoint, copyPoints))
}
// temp중 y값이 가장 가까운 값
const min = temp.reduce((prev, current) => (Math.abs(current.y - currentPoint.y) <= Math.abs(prev.y - currentPoint.y) ? current : prev))
copyPoints.forEach((point, index) => {
if (index === startIndex) return
resultPoints.push(min)
currentPoint = min
copyPoints.splice(copyPoints.indexOf(min), 1)
index++
break
}
}
}
return resultPoints
const nextPoint = copyPoints.find((p) => p.x1 === currentPoint.x2 && p.y1 === currentPoint.y2)
resultPoints.push(nextPoint)
currentPoint = nextPoint
})
return resultPoints.map((point) => {
return { x: point.x, y: point.y }
})
}
/**