miniRT 실습 - 04. Sphere

jkeum·2021년 2월 7일
0

miniRT

목록 보기
4/7
post-thumbnail

출처:
Ray Tracing in One Weekend - Adding a Sphere
Github - GaepoMorningEagles/mini_raytracing_in_c


Sphere


Description

레이트레이서에 단일 객체를 추가해 보겠다. 광선이 구와 만나는지를 계산하는 것은 비교적 간단하기 때문에 먼저 구를 나타내는 실습을 하겠다.


Ray-Sphere Intersection

반지름이 rr 이고 점 C(Cx,Cy,Cz)\bold{C}(C_x, C_y, C_z)를 중심으로 하는 구의 방정식은 (xCx)2+(yCy)2+(zCz)2=r2(x - C_x)^2 + (y - C_y)^2 + (z - C_z)^2 = r^2 이다.
구 위에 존재하는 어떤 점 P\bold P에 대해 구의 중심 C\bold C에서 점 P\bold P로 향하는 벡터를 만들어 위의 식을 다음과 같이 나타낼 수 있다.

(PC)(PC)=(xCx)2+(yCy)2+(zCz)2(\bold P - \bold C) \cdot (\bold P - \bold C) = (x - C_x)^2 + (y - C_y)^2 + (z - C_z)^2

이제 이 구의 방정식을 벡터를 이용한 구의 방정식으로 다시 쓸 수 있다.

(PC)(PC)=r2(\bold P - \bold C) \cdot (\bold P - \bold C) = r^2

우리는 "이 방정식을 만족하는 모든 점 P\bold P가 구 위에 존재한다."고 할 수 있다.
이제 어떤 광선의 방정식 P(t)=A+tb\bold{P}(t) = \bold{A} + t\bold{b}에서 어떤 점 P\bold P가 구 위에 존재한다는 것을 알고자 한다면, 이 광선의 방정식을 위의 식에 대입하여 다음과 같이 나타낼 수 있다.

(P(t)C)(P(t)C)=r2(\mathbf{P}(t) - \mathbf{C}) \cdot (\mathbf{P}(t) - \mathbf{C}) = r^2
(A+tbC)(A+tbC)=r2(\mathbf{A} + t \mathbf{b} - \mathbf{C}) \cdot (\mathbf{A} + t \mathbf{b} - \mathbf{C}) = r^2
t2bb+2tb(AC)+(AC)(AC)r2=0t^2 \mathbf{b} \cdot \mathbf{b} + 2t \mathbf{b} \cdot (\mathbf{A}-\mathbf{C}) + (\mathbf{A}-\mathbf{C}) \cdot (\mathbf{A}-\mathbf{C}) - r^2 = 0

위의 식은 미지수가 tt인 2차 방정식이므로 tt에 대해 풀 수 있다. 판별식을 구해서 판별식이 0보다 작으면 만나지 않는 것이고, 0이면 한 점에서 만나며(접함), 0보다 크면 두 점에서 만나는 것이다.

Sphere and Discriminant


Create Raytraced Image

구의 중심, 반지름을 담고 있는 구조체를 만들고 주어지는 값을 넣어서 초기화해준다. 그리고 광선과 구가 만나는지를 검사하는 함수를 만든다. 위에서 tt에 대해 정리한 2차 방정식을 이용하면 된다. ax2+bx+c=0ax^2 + bx + c = 0에서 각 aa, bb, cc에 대응되는 값을 구한다. double형 변수 a, b,c를 선언해서 대응되는 값을 계산해 넣어준다. 그리고 판별식을 구해서 그 값이 0보다 큰지 여부를 반환해준다.
코드에서 반환값이 0보다 크면 TRUE가 반환되어 그 때에 빨간색 원이 생기게 해주었다.
Ray Tracing in One Weekend에서는 빨간색 원이 나타나게 했는데 일본 같아서 색을 바꿨다. 갑자기 불타오르는 애국심🔥
(결과가 제대로 나오면, 위치나 색상을 바꿔보면서 어떻게 나오는지 확인해 보는 것도 재밌다.)

--

Result Image

profile
It's me, jkeum!

0개의 댓글