[게임 수학] 평면의 방정식

ounols·2021년 12월 25일
1

게임 수학

목록 보기
8/9
post-thumbnail

🧐 해당 파트는 게임 개발 환경을 구성하는 컴퓨터 그래픽스(Computer Graphics)를 이해하기 위한 기초 수학의 간단한 개념에 대해 설명하고 있습니다!

혹여나 이해가 잘 안되거나 잘못된 정보를 발견하시게 되었다면 관련해서 피드백 해주시면 정말 감사하겠습니다!

1. 평면의 방정식

학생 때 기억을 다시 되짚어보자면 직선의 방정식을 통해 특정 지점의 점과의 최단거리를 구하라 이런 식으로 몇가지 배웠습니다. (기억이 나지 않지만 분명 배우긴 했습니다..ㅎㅎ;;)

어쨌든 이번엔 직선이 아닌 한차원 업그레이드 된 평면의 방정식을 통해 그래픽스에 적용을 해보도록 합시다!

먼저 평면의 방정식은 아래와 같습니다.

ax+by+cz+d=0ax+by+cz+d=0

음... 일단 직선의 방정식에서 그냥 항이 하나 더 추가 된 모습의 단순한 수식인 건 알겠군요!
근데.. 평면의 방정식을 배워서 어디에 써먹을까요?

1-1. 배워야 하는 이유? 🤔

절두체위에서 바라본 절두체 컬링

혹시 이전에 원근 투영을 했던 그림이 기억나시나요? 저희는 이 그림에서 평면으로 표현되는 부분을 절두체(Frustum)라고 부릅니다.

절두체는 그래픽스에서 많은 도움을 줍니다. 대표적인 예시로는 위 그림처럼 절두체 컬링이라고 불리는 카메라 영역 밖에 있는 오브젝트는 드로우콜을 생략하는 정말 중요한 기법의 연산에 꼭 필요한 데이터를 가지고 있습니다.

절두체와 절두체 컬링에 대해 당장 다루고 싶지만 이는 다음 편으로 미루도록 하겠습니다ㅠ

어쨌든 이를 통해 평면을 구하는 공식의 필요성은 잘 알 수 있겠죠?
그런데 저희가 이전에 이미 평면의 방정식을 안쓰고 평면을 구한 적이 있습니다!

혹시 2편에서 다뤘던 외적을 통해 노멀벡터를 얻는 방법이 기억나시나요?
이 당시엔 점 3개를 통해 평면에 평행하는 벡터를 만들어 외적을 했었습니다.
여기서 얻은 노멀벡터를 통해 우리는 평면이란 개념을 만들고 앞 뒤를 구분할 수 있었습니다.

그런데 여기서 필요한 데이터를 더 줄이고도 평면을 얻을 수 있다면 더욱 좋겠죠?
따라서 저희는 평면 위의 점 3개가 아닌 평면 위의 점과 노멀 벡터를 통해 평면의 데이터를 얻어오는 방식을 채택하게 됩니다.

그럼 저 위 이미지처럼 평면 위의 한 점과 노멀벡터를 통해 평면의 방정식을 유도해보도록 하겠습니다.

1-2. 두 데이터를 평면의 방정식으로 유도

저희는 지금까지 2개 이상의 점을 이용하여 면을 이루며 매쉬 개념을 만들고, 노멀벡터를 만들고, 백페이스 컬링도 하고, 무게중심좌표도 구하는 등 정말 많은 곳에 응용을 했었습니다.

그런데 이번엔 평면 위의 한 점과 노멀벡터를 이용해 평면의 방정식을 유도하네요?
이렇게 유도를 하게되는 이유는 아래에서 알 수 있으니 일단 아래와 같은 조건으로 평면의 방정식을 유도해봅시다!

  • 노멀 벡터 : n=(a,b,c)\vec n = (a, b, c)
  • 평면 위의 한 점 : P0=(x0,y0,z0)P_0 = (x_0, y_0, z_0)
  • 평면 위의 임의의 점 : P=(x,y,z)P = (x, y, z)

먼저 노멀벡터를 살짝 변형시켜보겠습니다. 노멀 벡터는 항상 크기가 1이고, 벡터의 크기의 수학적 설명이 같은 벡터를 내적한 값의 루트값임을 응용해봅시다.

n=nn=a2+b2+c2=1a2+b2+c2=1||\vec n|| = \sqrt{\vec n \cdot \vec n} = \sqrt{a^2+b^2+c^2} = 1 \\ \therefore a^2+b^2+c^2 = 1

내적값이 1이 나온걸 루트를 씌우더라도 1이 나오기 때문에 루트를 생략할 수 있습니다.

노멀벡터와 직교하는 벡터

이제 평면 위에 있는 두 점인 P,P0P, P_0를 통해 노멀벡터에 직교하는 벡터를 구하고
노멀벡터와 직교하는 벡터를 내적하면 0이 나오는 성질을 이용해봅시다.

(a,b,c)(PP0)=0a(xx0)+b(yy0)+c(zz0)=0ax+by+cz(ax0+by0+cz0)=0(a, b, c)\cdot (P - P_0) = 0 \\ a(x-x_0) + b(y-y_0) + c(z-z_0) = 0 \\ ax + by + cz - (ax_0 + by_0 + cz_0) = 0

오 뭔가 식이 눈에 익지 않나요? 맞습니다!
ax+by+cz+d=0ax+by+cz+d=0 의 식이 위와 같이 유도가 되었습니다.

근데 dd의 값이 뭔가 이상하긴 합니다... (ax0+by0+cz0)- (ax_0 + by_0 + cz_0)라니...
정말 수상하게 생긴 식이지만 정말 많은 정보를 가지고 있다는 사실을 알고 계신가요?

1-3. 평면의 방정식의 dd

딱히 별 볼일 없어 보이는 dd를 왜 알아내려고 할까요? 한번 알아보도록 하겠습니다.

일단 알아보기 전 ax0+by0+cz0ax_0 + by_0 + cz_0 이라는 식 어디서 많이 본 것 같지 않나요?
바로 내적을 풀면 위 식처럼 나타나죠! 그럼 내적으로 만들어 봅시다.

(a,b,c)(x0,y0,z0)=nP?(a, b, c) \cdot (x_0, y_0, z_0) \\ = \vec n \cdot P?

음.. 안타깝게도 PP는 점이기 때문에 뭔가 내적을 계속 진행하기 이상합니다..
그렇기 때문에 그냥 원점 OO에서 PP로 가는 벡터로 만들어주고 이걸 p\vec p로 표현하겠습니다.

d=(nOP0)=(np)d = -(\vec n \cdot \vec{OP_0}) \\ = -(\vec n \cdot \vec p)

지금까지 구한 값을 시각화 한다면 위 사진처럼 보여질 겁니다.
이제 여기에서 np\vec n \cdot \vec p 처럼 서로 내적을 하는건 아래의 식처럼 표현이 가능합니다.

np=npcosθ=pcosθ\vec n \cdot \vec p = |\vec n| |\vec p| \cdot cos\theta \\ = |\vec p| \cdot cos\theta

위 식에서 n\vec n이 사라진건 크기가 1이기 때문에 생략이 가능하기 때문입니다.
위와 같은 수식을 시각화하면 아래의 사진처럼 표현할 수 있습니다.

위 그림처럼 내적의 성질로 직각 삼각형의 밑변에 해당되는 부분을 구한 스칼라 값이 됩니다.

이를 통해 우리는 원점에서부터 평면까지의 최단거리를 구했다고 봐도 무방합니다!
따라서 dd는 평면과 원점 간의 최단거리가 됩니다!

사실 중학생 때 배운 직선의 방정식에서도 스칼라 값이 yy기준 yy절편을 뜻하는 바를 보면 얼추 이런 결론을 예상하셨을거라 생각합니다.
그래도 우리는 이런 유도과정을 통해 P0P_0가 어디에 있든지 dd의 값은 항상 같을 수 밖에 없다는 것도 알 수 있습니다.

하지만 dd를 통해 알 수 있는 사실이 이것 뿐일까요? 만약 n\vec n방향이 반대라면 어떻게 될까요?

위 그림을 상세하게 표현하자면 θ\theta값이 90°90\degree가 넘었으므로 스칼라값이 음수가 나타납니다!

왜 내적값이 음수가 나타나는지 궁금하시다면
2편의 외적과 내적의 θθ각에 따른 음수 양수 영역을 확인해주세요!

따라서 dd의 양수와 음수의 차이가 n\vec n의 방향차이도 알 수 있습니다.

그럼 이제 dd에 담겨있는 정보들을 정리해봅시다!

  • dd의 값은 원점에서 평면까지의 최단거리다.
  • dd의 양수와 음수의 차이로 n\vec n의 방향을 알 수 있다.

이제 응용하러 가봅시다!

1-4. 응용 단계

지금까지 알아본 평면의 방정식의 성질을 응용하여 많은 문제들을 해결할 수 있습니다!
하지만 막상 응용해보려니 뭐부터 응용해야할지 잘 모르겠네요..!

따라서 저희는 아래와 같이 응용하는 예시들을 선정해보려고 합니다.

  • 평면의 앞뒤를 구분하는 그래픽스 실전 응용!
  • 고등학교 문제에서 나올 법한 응용..

한번 알아보도록 하겠습니다!

응용1) 그래픽스 실전 응용!

임의로 주어진 점이 평면 안에 있는지 밖에 있는지로 응용해보는 실전에서 쓰일만한 응용단계입니다.
어느정도 생각해보면 나름 답이 나올 것 같지 않나요? 먼저 간단하게 어떻게 정리할지 생각해봅시다.

말이 평면의 방정식의 dd이지 사실 노멀벡터임의의 점(벡터)를 가지고
최단거리양수 음수를 구분하는 거였죠?

그렇다면 평면의 방정식도 구하고 임의로 주어진 점을 dd값을 구하듯이
노멀벡터와 원점에서 임의의 점으로 가는 벡터를 내적해서 최단거리를 구해줍시다..

그리고 두 결과값을 비교하면 얼추 확인할 수 있을 것 같습니다...!
이제 본격적으로 정리해봅시다!

위 사진과 같이 원점이 평면 안에 있을 때를 가정해보겠습니다.
dd값은 이미 구했고, 임의의 점 PP도 내적을 통해 최단거리인 OPOP'의 거리를 구해줍니다.

distance(OP)=nOPdistance(OP') = \vec n \cdot \vec{OP}

이렇게 두 값을 구하면 여기서 음수와 양수를 구분하는 것이 정말 중요합니다.

먼저 dd는 수식이 (np)-(\vec n \cdot \vec p) 이므로 내적값의 부호가 반대로 바뀌고
OPOP'의 거리는 nOP\vec n \cdot \vec{OP} 이므로 내적값의 부호가 그대로 적용됩니다.

따라서 d+OPd + OP'을 했을 때 음수가 나온다면 OPOP'dd보다 짧으므로 점 PP가 평면 안에 있는 것이고
양수가 나온다면 OPOP'dd보다 길다는 뜻이므로 점 PP가 평면 밖에 있는 것이라 해석할 수 있습니다.

이번엔 원점이 평면 밖에 있을 때를 가정해보겠습니다.
위에 작성했던 d+OPd + OP'을 적용해보면 다음과 같이 결과가 나타납니다.

dd는 내적의 성질로 양수로 나타나게 됩니다.
그리고 OPOP'값도 내적으로 구하기 때문에 똑같이 반대로 음수가 나타납니다.

따라서 원점이 평면 안에 있을 때와 부호가 반대되는 결과값을 주게 되지만 평면 밖이기 때문에 부호가 반대되는 상황이 정상적인 판단이라고 해석할 수 있습니다.

이 모든 내용을 종합하면 아래와 같은 식으로 판별이 가능합니다!

d+OP<0         (평면 안쪽)d+OP>0     (평면 바깥쪽)d+OP=0     (평면에 포함)d + OP' < 0~~~~~~~~~(평면 \ 안쪽) \\ d + OP' > 0~~~~~(평면 \ 바깥쪽) \\ d + OP' = 0~~~~~(평면에 \ 포함)

응용2) 고등학교 문제에서 볼 법한 문제

[문제] 임의의 점 PP가 주어졌을 때 해당 점과 평면 ll과의 최단거리를 구하시오.

여기서는 아래와 같이 두가지 방법으로 접근해볼 수 있습니다.

  • 고등학교 과정을 통해 구하기
  • 내적을 통해 구하기

먼저 고등학교 과정을 통해 구해볼까요?

1. 고등학교 과정으로 구하기!

먼저 2차원의 직선과 점 사이의 최단거리를 내적, 외적없이 구해보고자 합니다.

먼저 수선의 발인 HH와 임의의 점 PP의 거리를 피타고라스의 정리를 통해 수식을 정리해줍니다.

PH=(x2x1)2+(y2y1)2PH2=(x2x1)2+(y2y1)2PH = \sqrt{(x_2-x_1)^2 + (y_2-y_1)^2} \\ PH^2 = (x_2-x_1)^2 + (y_2-y_1)^2

그리고 직선과 수직을 이루기 때문에 아래와 같은 식으로 표현이 됩니다.

y2y1x2x1×ab=1x2x1a=y2y1b\frac{y_2-y_1}{x_2-x_1} \times -\frac{a}{b} = -1 \\ \frac{x_2-x_1}{a} = \frac{y_2-y_1}{b}

이 최단거리를 tt로 표현할 수 있다 가정하고 x,yx, yPH2PH^2을 다음과 같이 대체가 가능합니다.

x=x1+at , y=y1+bt , PH2=(a2+b2)t2ax+by+c=0a(x1+at)+b(y1+bt)+c=0t=ax1+by1+ca2+b2PH2=(ax1+by1+c)2a2+b2PH=ax1+by1+ca2+b2x = x_1+at \ , \ y = y_1+bt \ , \ PH^2 = (a^2+b^2)t^2 \\ ax + by + c = 0 \\ a(x_1+at) + b(y_1+bt) + c = 0 \\ t = -\frac{ax_1+by_1+c}{a^2+b^2} \\ \therefore PH^2 = \frac{(ax_1+by_1+c)^2}{a^2+b^2} \\ PH = \frac{|ax_1+by_1+c|}{\sqrt{a^2+b^2}}

이렇게 최단거리를 구할 수 있다고 고등학교 시험 문제에서 설명하네요...
사실 증명부분을 보면 좀 이해가 안되게 뜬금없이 뭔가 나타나는 부분은 벡터의 개념으로 봐야 설명이 되는 부분들이 있었습니다.
예를 들어 tt가 나온다는건 정말 뜬금없어 보이지만 PH=tn{PH} = t \cdot \vec n을 만족하는 tt가 존재한다는 동차의 성질이 적용된 과정을 보니 이해가 되었습니다.

어쨌든 이러한 유도과정은 3차원에서도 똑같이 적용할 수 있기 때문에 3차원으로 적용한다면 아래와 같은 식으로 나타납니다.

ax1+by1+cz1+da2+b2+c2\frac{|ax_1+by_1+cz_1 + d|}{\sqrt{a^2+b^2+c^2}}

으악! 어찌됐든 위 과정은 증명도 좀 뜬금없고 복잡하네요!
이번엔 저희가 배웠던 내용을 토대로 구해봅시다.

2. 내적을 통해 구하기!

내적은 2차원은 생략하고 3차원으로 바로 적용해보도록 합시다!
저희는 이미 평면과 원점의 최단거리와 임의의 점과 원점의 최단거리를 구했습니다.
이제 이 둘을 빼주면 될 것 같은데...

어...? 끝났네요...?

저희는 임의의 점이 평면 안에 있는지 밖에 있는지를 판단하기 위해 부호를 비교했지만
사실 저 때 구한 값이 곧 평면과 점의 최단거리를 뜻하기도 합니다.

사실 위에서 이미 최단거리를 구했기 때문에 해당 문제가 너무 썰렁해질까봐 고등학교 과정을 통한 식 유도도 추가로 진행해본 것이였습니다!

어쨌든 수식으로 표현하자면 다음과 같습니다.

d+OP=d+nOP=d+(a,b,c)(x1,y1,z1)|d + OP'| \\ = |d + \vec n \cdot \vec{OP}| \\ = |d + (a, b, c) \cdot (x_1, y_1, z_1)|

좀 날로 먹는거 같으니 고등학교 과정에서 최종적으로 나온 식으로 한번 유도를 해볼까요?

ax1+by1+cz1+da2+b2+c2\frac{|ax_1+by_1+cz_1 + d|}{\sqrt{a^2+b^2+c^2}}

여기서 a2+b2+c2\sqrt{a^2+b^2+c^2}는 노멀벡터의 크기이므로 1이 되기 때문에 생략이 가능해집니다.

=ax1+by1+cz1+d=(a,b,c)(x1,y1,z1)+d= |ax_1+by_1+cz_1 + d| \\ = |(a, b, c)\cdot (x_1, y_1, z_1)+d|

ax1+by1+cz1ax_1+by_1+cz_1도 내적으로 표현이 가능하기 때문에 위와 같이 저희가 구한 식으로 유도가 된 모습입니다.

잠깐! 만약 n\vec{n}의 크기가 1이 아니면? 🙊

사실 코드 상으로는 혹시 모르니 노멀벡터를 한번 더 정규화 시키면 간단하게 해결 가능합니다!
근데 여기서 이렇게 다룬다면 수학적인 내용이 아니니 다른 방식으로 해결을 해봐야겠죠?

진행하기 전 저희는 응용2의 고등학교 과정으로 구하기의 수식을 그대로 다시 들고오도록 하겠습니다.

PH=ax1+by1+cz1+da2+b2+c2PH = \frac{|ax_1+by_1+cz_1 + d|}{\sqrt{a^2+b^2+c^2}}

해당 유도 과정은 동차를 적용했다는 과정을 추가하여 수식의 유도과정이 더욱 매끄럽게 진행하는 것에 의미를 두었습니다.

일단 n\vec n은 정규화되지 않았으므로 a2+b2+c2=1a^2+b^2+c^2 = 1은 성립되지 않습니다.
그리고 동차를 이용하여 ww개념을 도입하고, 기존 과정에서 다음과 같이 정리합니다.

x=x1+awy=y1+bwz=z1+cwPH2=(a2+b2+c2)w2w=ax1+by1+cz1+da2+b2+c2x = x_1+aw \\ y = y_1+bw \\ z = z_1+cw \\ PH^2 = (a^2+b^2+c^2)w^2 \\ \therefore w = \frac{ax_1+by_1+cz_1+d}{a^2+b^2+c^2}

이제 동차를 이용해 d=wnd = w \vec n을 만족하는 ww를 구했으니 dd에 대해 아래와 같이 표현할 수 있습니다.
아 맞다! 참고로 n\vec n은 정규화 되지 않았으니 꼭 정규화를 기억해주며 수식을 유도해야 합니다!

d=wnd=(ax1+by1+cz1+da2+b2+c2)a2+b2+c2d=ax1+by1+cz1+da2+b2+c2d = w\cdot||\vec n|| \\ d = (\frac{ax_1+by_1+cz_1+d}{a^2+b^2+c^2}) \cdot \sqrt{a^2+b^2+c^2} \\ d = \frac{ax_1+by_1+cz_1+d}{\sqrt{a^2+b^2+c^2}}

이렇게 평면의 방정식에 정규화를 진행해보았습니다!

다음 장에선 평면의 방정식을 절두체에 적용하여 절두체 컬링이 구현되는 원리에 대해 알아보도록 하겠습니다!

profile
(게임 엔진 프로그래머가 되고싶은) 게임 클라이언트 프로그래머

0개의 댓글