
const fs = require('fs');
const path = process.platform === 'linux' ? '/dev/stdin' : 'input.txt';
const inputs = fs
.readFileSync(path)
.toString()
.trim()
.split('\n')
.map((it) => it.split(' ').map(Number));
const [x1, y1, x2, y2] = inputs[0];
const [x3, y3, x4, y4] = inputs[1];
const CCW = (x1, y1, x2, y2, x3, y3) => {
return (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
};
const a = CCW(x1, y1, x2, y2, x3, y3);
const b = CCW(x1, y1, x2, y2, x4, y4);
const c = CCW(x3, y3, x4, y4, x1, y1);
const d = CCW(x3, y3, x4, y4, x2, y2);
if (a * b <= 0 && c * d <= 0) console.log(1);
else console.log(0);
⏰ 소요한 시간 : -
선분 교차를 판별하는 문제다.
선분 교차는 CCW라는 알고리즘으로 알아낼 수 있다.
CCW는 세 점이 이루는 방향을 계산하는 알고리즘이다.
위와 같이 1번점과 2번점이 있을 때 그 두 점을 이은 상태에서, 나머지 하나의 점이 반시계 구역인지, 시계구역인지를 판단하는 방식이 CCW이다.
이 때 벡터의 외적을 통해서 세 점이 이루는 방향을 알 수 있다.
즉, 각 선분에 대해 다른 선분의 두 끝점이 서로 다른 방향에 위치해, 하나는 시계방향, 하나는 반시계 방향이 나와 두 결과값의 곱이 음수가 뒤어야 선분이 교차하는 것이다.
const a = CCW(x1, y1, x2, y2, x3, y3);
const b = CCW(x1, y1, x2, y2, x4, y4);
const c = CCW(x3, y3, x4, y4, x1, y1);
const d = CCW(x3, y3, x4, y4, x2, y2);
위의 경우, (x1,y1) - (x2,y2) 선분과 점 (x3,y3)의 CCW 결과, (x1,y1) - (x2,y2) 선분과 점 (x4,y4)의 CCW 결과를 각각 a, b에 넣었다.
a와 b의 결과가 반대로 나와하고, 두 결과의 곱이 음수가 된다.
이 과정을 반대로 했을 때도 음수를 만족한다면 선분교차임을 알 수 있다.
ㅜㅜ 너무 어려워서 유튜브를 몇번이나 봤는지 모른다
학생 때 기하벡터를 열심히 할걸 ~
보통 복습할 때 내가 풀이했던 블로그를 보면서 복습하는데 이 문제는 아래 링크된 유튜브를 보는게 더 도움될 것 같다.... 흑 ㅠ