bansh123   3년 전

일단 코드가 너무 스파게티고 길어 못볼지경이라서 말로 설명드리자면..

벽의 위치를 광원으로부터 가까운 순으로 정렬해서 저장합니다.

가까운벽부터 순서대로 각 벽에 대해서 광원에 의해 만들어지는 그림자의 모양에서 윗부분의 선분(그림자가 시작하는부분)과 아랫부분의 선분을 구합니다. 

이때 광원의 위치와 벽에 위치에따라서 그림자의 모양이 상이하기때문에 벽의 위치가 광원 기준으로 1,2,3,4분면, x축 y축중에 어디에 속하는지에 따라 나눠서 생각했고, 그 이외에도 여러가지 있지만 일단 제생각에는 다 고려된것같습니다.)

각 차례마다 만들어진 그림자선분에 포함되는 벽들은 다 제거합니다.

그 후에, 모든 만들어진 선분들을 대상으로, 선분의 시작점, 끝점의 y좌표 , 그리고 선분간 교차점들의 y좌표를 전부 구한 다음에 정렬합니다. (중복값 제거) (혼동될수 있는데 여기서 말하는 y좌표는 0~M값으로 가로축입니다)

그다음 구한 y좌표들에 대해서 아주작은 수 a(ex. 10^(-14))를 더하고 빼서 수직 세로줄 (0,y+a)--(n,y+a), (0,y-a)--(n,y-a)  두 개 만들어서 아까 구했던 모든 그림자 선분들을 대상으로 교차점을 구합니다. (이때 그림자가 시작하는 선분과의 교차점인지 끝나는 선분과의 교차점인지도 마킹해놓습니다.)

다음 마지막으로 이제 각 y좌표들에 대해 그림자인 부분의 길이를 구합니다. 방법은 스위핑기법 활용해서 구했습니다.

그 후에 이를 바탕으로 그림자의 총 넓이를 구했습니다.

제 생각에는 오차범위가 10^(-9)까지 허용되니까 이런 식으로 해도 맞을 것 같아서 짜봤는데 뭘 빠뜨린건지 1%에서 틀렸습니다가 뜨네요..

조언 부탁드립니다!.. 반례라도 주시면 정말 감사하겠습니다!

bansh123   3년 전

자답합니다.

일단 small을 너무 작게했던게 문제가 됐었고,

그 다음으론 (0,y)--(n,y)와 선분들의 교차점의 x좌표들이 같은경우에 제가짠 스위핑 기법을 활용하는데 문제가 발생했었습니다.

이 두가지 수정햇더니 드디어 패스했네요! 

댓글을 작성하려면 로그인해야 합니다.