배열의 배열(2차원 배열)을 입력으로 받아, 그 좌표들이 모두 한 직선 위에 있는지 판별하는 JavaScript 함수를 작성해 보겠습니다. 각 하위 배열은 정확히 두 개의 요소를 가지며, 각각 x 좌표와 y 좌표를 나타냅니다.
예를 들어 다음과 같습니다.
[[4, 5], [5, 6]] → true 반환
입력 배열에는 최소 두 개의 하위 배열이 포함되어 있다고 가정합니다.
기본 아이디어
여러 점이 한 직선 위에 있다면, 첫 번째 점을 기준으로 계산한 나머지 점들까지의 기울기(slope)가 모두 동일해야 합니다. 따라서 첫 점과 각 점 사이의 기울기를 구해 서로 비교하면 됩니다. 기울기가 하나라도 다르면 해당 점들은 같은 직선 위에 있지 않습니다.
예제 코드
const coordinates = [
[4, 5],
[5, 6]
];
const checkStraightLine = (coordinates = []) => {
if(coordinates.length === 0) return false;
let x1 = coordinates[0][0];
let y1 = coordinates[0][1];
let slope1 = null;
for(let i = 1; i < coordinates.length; i++){
let x2 = coordinates[i][0];
let y2 = coordinates[i][1];
if(x2 - x1 === 0){
return false;
}
if(slope1 === null){
slope1 = (y2 - y1) / (x2 - x1);
continue;
}
let slope2 = (y2 - y1) / (x2 - x1);
if(slope2 !== slope1){
return false;
}
}
return true;
};
console.log(checkStraightLine(coordinates));코드 설명
첫 번째 점 (x1, y1)을 기준점으로 삼고, 반복문을 돌며 나머지 각 점까지의 기울기를 계산합니다. 처음 계산한 기울기를 slope1에 저장한 뒤, 이후 점들의 기울기(slope2)와 비교하여 값이 다르면 즉시 false를 반환합니다. 모든 점의 기울기가 동일하다면 마지막에 true를 반환하여 세 점 이상이 한 직선 위에 있음을 알려줍니다.
출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
true
참고: 수직선까지 올바르게 처리하려면
위 코드는 x 좌표의 차이가 0일 때(수직선인 경우) 무조건 false를 반환하기 때문에, 실제로 수직선 위에 있는 점들을 판별하지 못한다는 한계가 있습니다. 나눗셈 대신 교차 곱(cross multiplication)을 사용하면 0으로 나누는 문제 없이 안전하게 검사할 수 있습니다.
const checkStraightLine = (coordinates = []) => {
const [[x1, y1], [x2, y2]] = coordinates;
const dx = x2 - x1;
const dy = y2 - y1;
// (y - y1) / (x - x1) === dy / dx 를 곱셈 형태로 변형
return coordinates.every(([x, y]) => dy * (x - x1) === dx * (y - y1));
};
console.log(checkStraightLine([[1, 1], [1, 5], [1, 9]])); // true (수직선)이 방식은 부동소수점 오차도 줄여 주므로, 실무에서는 교차 곱 기반의 구현을 사용하는 것이 더 안전합니다.