원 그리기
원 그리기는 개쉬움 그냥 밥임
구의 방정식이라고 있음
구의 방정식
임의의 점 (x,y,z)가 있다고 가정 ㄱㄱ
x 2 + y 2 + z 2 = r 2 x^2 + y^2 + z^2 = r^2 x 2 + y 2 + z 2 = r 2
이걸 사용하면 구 내부를 색칠놀이 할 수 있음
x 2 + y 2 + z 2 < r 2 x^2 + y^2 + z^2 < r^2 x 2 + y 2 + z 2 < r 2 이면 x,y,z에 해당되는 점이 구 내부에 존재하는거임
x 2 + y 2 + z 2 = r 2 x^2 + y^2 + z^2 = r^2 x 2 + y 2 + z 2 = r 2 이면 x,y,z에 해당되는 점이 구 표면에 존재하는거임
x 2 + y 2 + z 2 > r 2 x^2 + y^2 + z^2 > r^2 x 2 + y 2 + z 2 > r 2 이면 x,y,z,에 해당되는 점이 구 외부에 존재하는거임
그러니까 구 표면 || 내부에 존재하는 점(픽셀, 좌표)만 원하는 색으로 색칠놀이 하면 되는거임
이때 구의 방정식은 구의 중앙이 원점 (0,0,0)에 있다고 가정할때의 방정식임.
즉, 임의의 점 C C C 에서 구의 방정식을 구하면 다음과 같음
( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2 = r 2 (Cx−x)^2+(Cy−y)^2+(Cz−z)^2=r^2 ( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2 = r 2
C C C 의 각 좌표에서 x , y , z x,y,z x , y , z 를 빼면 해당 방향으로의 길이 벡터가 나옴
각 길이들을 제곱했을때
= r 2 = r^2 = r 2 이면 구 표면,
< r 2 < r^2 < r 2 이면 구 내부,
> r 2 > r^2 > r 2 이면 구 외부의 점
이 되는거지 ㅇㅇ
이때 ( x , y , z ) (x,y,z) ( x , y , z ) 를 점 P P P 라고 하면,
( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2 = ( C − P ) ⋅ ( C − P ) (Cx−x)^2+(Cy−y)^2+(Cz−z)^2 = (C-P) \cdot (C-P) ( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2 = ( C − P ) ⋅ ( C − P ) 와 같음
이유는 내적 공식임
내적은 두 벡터의 각 요소를 서로 곱해서 더한 값임
두 벡터를 X X X , Y Y Y 라고 해보자
그럼 내적은
X x ∗ Y x + X y ∗ Y y + X z ∗ Y z X_x * Y_x + X_y * Y_y + X_z * Y_z X x ∗ Y x + X y ∗ Y y + X z ∗ Y z 가 됨
( C − P ) ⋅ ( C − P ) = (C-P) \cdot (C-P) = ( C − P ) ⋅ ( C − P ) =
( C x − P x ) ∗ ( C x − P x ) . . . = (C_x - P_x) * (C_x - P_x)... = ( C x − P x ) ∗ ( C x − P x ) . . . =
( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2 (Cx−x)^2+(Cy−y)^2+(Cz−z)^2 ( C x − x ) 2 + ( C y − y ) 2 + ( C z − z ) 2
임
이때, ( C − P ) ⋅ ( C − P ) (C-P) \cdot (C-P) ( C − P ) ⋅ ( C − P ) 는 다시 아래 식처럼 표현할 수 있음
핵심 아이디어는 다음과 같음
점 P P P 는 이제부터 없고, 점 P P P 대신 Ray P ( t ) P(t) P ( t ) 가 존재함
이유는 Ray가 지나간 자리에서 원과 충돌이 생기는 지점만 색을 칠하면 되기 때문임
즉, P ( t ) P(t) P ( t ) 는 광선의 시작점(Q Q Q )에서부터 스칼라 값 t t t 만큼 d d d 방향으로 이동한 좌표임
P ( t ) = Q + t d P(t) = Q + td P ( t ) = Q + t d
따라서
( C − P ) ⋅ ( C − P ) = ( C − ( Q + t d ) ) ⋅ ( C − Q + t d ) ) (C-P) \cdot (C-P) = (C - (Q + td)) \cdot (C - Q + td)) ( C − P ) ⋅ ( C − P ) = ( C − ( Q + t d ) ) ⋅ ( C − Q + t d ) )
처럼 표현가능
이항정리를 해보자
( C − ( Q + t d ) ) ⋅ ( C − Q + t d ) ) = (C - (Q + td)) \cdot (C - Q + td)) = ( C − ( Q + t d ) ) ⋅ ( C − Q + t d ) ) =
( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) ) (-td + (C - Q)) \cdot (-td + (C - Q)) ( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) )
처럼 표현가능함
( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) ) (-td + (C - Q)) \cdot (-td + (C - Q)) ( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) )
이 식을 거시적으로 봐보센
뭐가보임?
− t d = A -td = A − t d = A
C − Q = B C - Q = B C − Q = B
라고 보면
( A + B ) ⋅ ( A + B ) (A + B) \cdot (A + B) ( A + B ) ⋅ ( A + B ) 가됨
위 식을 풀어보면
( A + B ) ⋅ ( A + B ) = A ⋅ A + A ⋅ B + B ⋅ A + B ⋅ B (A + B) \cdot (A + B) = A \cdot A + A \cdot B + B \cdot A + B \cdot B ( A + B ) ⋅ ( A + B ) = A ⋅ A + A ⋅ B + B ⋅ A + B ⋅ B 가 됨.
이때 A = − t d A = -td A = − t d 이고, B = C − Q B = C - Q B = C − Q 임
내적은 교환법칙이 성립하므로 A ⋅ B = B ⋅ A A \cdot B = B \cdot A A ⋅ B = B ⋅ A 임
즉, A ⋅ A + 2 ( A ⋅ B ) + B ⋅ B A \cdot A + 2 (A \cdot B)+ B \cdot B A ⋅ A + 2 ( A ⋅ B ) + B ⋅ B 임!
항을 풀어서 정리를 해보자
( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) ) = (-td + (C - Q)) \cdot (-td + (C - Q)) = ( − t d + ( C − Q ) ) ⋅ ( − t d + ( C − Q ) ) =
( A + B ) ⋅ ( A + B ) = (A + B) \cdot (A + B) = ( A + B ) ⋅ ( A + B ) =
( − t d ) ⋅ ( − t d ) + 2 ( − t d ⋅ ( C − Q ) ) + ( C − Q ) ⋅ ( C − Q ) (-td) \cdot (-td) + 2(-td \cdot (C - Q)) + (C - Q) \cdot (C - Q) ( − t d ) ⋅ ( − t d ) + 2 ( − t d ⋅ ( C − Q ) ) + ( C − Q ) ⋅ ( C − Q )
가 됨
t t t 는 스칼라 값으로,
스칼라 값들의 내적은 스칼라 값을 그냥 곱한것과 같음
즉, 위의 식을 한번 더 풀어서 원 표면과 함께 식 정리를 하면
t 2 ( d ⋅ d ) − 2 t d ⋅ ( C − Q ) + ( C − Q ) ⋅ ( C − Q ) = r 2 t^2(d \cdot d) -2td \cdot(C - Q) + (C - Q ) \cdot (C - Q) = r^2 t 2 ( d ⋅ d ) − 2 t d ⋅ ( C − Q ) + ( C − Q ) ⋅ ( C − Q ) = r 2
이 됨
뭔가 익숙하지않음?
이차방정식이 막 근질근질 하지 않음?
r 2 r^2 r 2 을 좌항으로 넘기면 a x 2 + b x + c = 0 ax^2 + bx + c = 0 a x 2 + b x + c = 0 꼴의 이차방정식이 됨
t 2 ( d ⋅ d ) − 2 t d ⋅ ( C − Q ) + ( C − Q ) ⋅ ( C − Q ) − r 2 = 0 t^2(d \cdot d) -2td \cdot(C - Q) + (C - Q ) \cdot (C - Q) - r^2 = 0 t 2 ( d ⋅ d ) − 2 t d ⋅ ( C − Q ) + ( C − Q ) ⋅ ( C − Q ) − r 2 = 0 이 되는거고,
이걸 다시 정리하면
[ d ⋅ d ] t 2 + [ − 2 d ⋅ ( C − Q ) ] t + [ ( C − Q ) ⋅ ( C − Q ) − r 2 ] = 0 [d \cdot d] t^2 + [-2d \cdot(C - Q)]t + [(C - Q ) \cdot (C - Q) - r^2] = 0 [ d ⋅ d ] t 2 + [ − 2 d ⋅ ( C − Q ) ] t + [ ( C − Q ) ⋅ ( C − Q ) − r 2 ] = 0
형태인 이차방정식이 됨!! ㅁㅊㅁㅊ!!
a x 2 ax^2 a x 2 에서 a = [ d ⋅ d ] a = [d \cdot d] a = [ d ⋅ d ] 가 되고
b x bx b x 에서 b = [ − 2 d ⋅ ( C − Q ) ] b = [-2d \cdot(C - Q)] b = [ − 2 d ⋅ ( C − Q ) ] 가 되고
c c c 에서 c = [ ( C − Q ) ⋅ ( C − Q ) − r 2 ] c = [(C - Q ) \cdot (C - Q) - r^2] c = [ ( C − Q ) ⋅ ( C − Q ) − r 2 ] 가 되는거임
근의 공식
− b ± b 2 − 4 a c 2 a \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} 2 a − b ± b 2 − 4 a c
이라는 공식 알고있지?
여기서 판별식이 존재함
b 2 − 4 a c b^2 - 4ac b 2 − 4 a c 가 판별식임
이 판별식에 따라서
판별식 값이 음수 = 근이 없음 = 구 외부를 지남
판별식 값이 같음 = 근은 1개 = 구 표면(접점)을 지남
판별식 값이 양수 = 근이 2개 = 구 내부를 지남
이렇게 ray에 대하여 구의 어느부분을 지나는지 판별하게 되는거임
코드 구현
a = [ d ⋅ d ] a = [d \cdot d] a = [ d ⋅ d ]
b = [ − 2 d ⋅ ( C − Q ) ] b = [-2d \cdot(C - Q)] b = [ − 2 d ⋅ ( C − Q ) ]
c = [ ( C − Q ) ⋅ ( C − Q ) − r 2 ] c = [(C - Q ) \cdot (C - Q) - r^2] c = [ ( C − Q ) ⋅ ( C − Q ) − r 2 ]
를 기억하자
bool hit_sphere ( const Point3& center, double radius, const Ray& r)
{
Vector3 oc = center - r. origin ( ) ;
double a = dot ( r. direction ( ) , r. direction ( ) ) ;
double b = - 2.0 * dot ( r. direction ( ) , oc) ;
double c = dot ( oc, oc) - radius * radius;
double discriminant = b * b - 4 * a * c;
return discriminant >= 0 ;
}
Color ray_color ( const Ray& r)
{
if ( hit_sphere ( Point3 ( 0.2 , 0.2 , - 1 ) , 0.5 , r) )
{
return Color ( 1 , 1 , 0 ) ;
}
. . .
}
여기서 Point3(0.2, 0.2, -1)는 원 중심의 좌표임
판별식에 따라 0보다 크거나 같으면 원 표면 혹은 원 내부를 지난다는 의미이므로, 해당 점을 다른색으로 칠해준다.
이때 z축이 -1인 이유는 다음과 같음
오른손 좌표계를 우리는 사용중임
y는 화면 위, x는 화면 오른쪽, z는 화면에서 내 눈 방향임
즉, 우리 눈이 z축으로 양수값에 위치하게 되는거임
근데 원의 z축이 양수가 되면?
우리가 반대로 구를 보게 된다는거임!
따라서 좌표값에 반대 값으로 반전이 생긴것처럼 보이게 된다는거임
z = 1일때
z = -1일때
구가 약간 삐뚫어진 이유는
카메라에서 바라본 각도이기 때문에, 시야각에 따라 삐뚫어진거임