임의의 점 \(Q\) 가 주어진 다각형 안에 있는지 판단하는 방법은 모든 선분에 대해서 선분과 점 \(Q\) 가 이루는 삼각형이 시계반대방향인지 체크하는 것이다. 만약 밖에 있다면 어떤 선분은 시계방향으로 삼각형을 이룰 것이다. 또한 볼록껍질의 특성 상 이러한 특징을 갖는 선분은 서로 인접한다. 다시말해 다각형은 삼각형을 시계방향으로/반대방향으로 이루는 두 부분으로 나뉘어 질 것이다.
우리는 \(Q\) 와 시계방향으로 삼각형을 이루는 어떤 선분이 존재하는지, 존재한다면 어떤 선분인지, 이분탐색으로 빠르게 구할 수 있다.
볼록껍질의 특성 때문에 주어진 다각형의 임의의 점 \(P_O\) 에 대해서 다른 정점들은 반드시 시계반대방향 순서로 정렬되어 있다. 다른 정점들의 양 끝을 넘어서지 않는다면 \(Q\) 가 변 \(\overline{P_S P_E}\) 에 대해서 \(P_S \leq Q \leq P_E\) 가 시계반대방향 순서로 성립하는지는 이분탐색으로 빠르게 구할 수 있다.
만약 이 변에 대해서 외적이 양수라면 \(Q\) 는 다각형 안에 있게 된다. 그렇지 않다면 이 변의 양쪽으로 나아가다 보면 접점이 나올 것이다.
다른 정점들의 양 끝을 넘는 범위에 대해서는 적절한 예외처리를 통해 확인할 수 있다.
나머지는 코드의 주석을 참고하자.
점수 구하기
두 접점이 주어져 있다면 누적합을 통해 빠르게 넓이를 구할 수 있다.
임의의 두 꼭짓점 \(P_A, P_B\) 에 대해 다각형을 쪼개야한다고 하자.
우선 다각형을 그것을 이루는 꼭짓점 중 임의의 점 \(P_O\) 을 공통으로 지나는 삼각형으로 쪼갠다.
그러면 다각형은 삼각형 \(\{P_O, P_A, P_B\}\) 와 양쪽의 두 다각형 \(\{P_O, P_{O+1}, ..., P_{A-1}, P_A, P_O\}\), \(\{P_O, P_B, P_{B+1}, ..., P_{O-1}, P_O\}\), 으로 나눌 수 있다.
앞의 삼각형은 외적으로 뒤의 두 다각형은 누적합으로 구하면 상수시간에 점수를 구할 수 있다.
댓글남기기