법선 벡터 계산하기: 외적

2023. 7. 22. 18:28Public/Math

법선 벡터(normal vector)는 표면에 수직인 벡터다. 표면(삼각형 등)의 법선 벡터를 계산하면 3D 게임에서 매우 도움이 된다. 예를들어 6장 '3D 그래픽스'에서 설명하는 광원 모델은 법선 벡터의 계산이 필요하다.

평행하지 않은 2개의 3D 벡터가 주어지면 두 벡터를 포함하는 평면은 반드시 존재한다. 외적은 그림 3.9에서 보여주듯이 그 평면에 수직한 벡터를 구한다. (즉 벡터의 두 벡터의 외적을 계산하면 법선 벡터가 나온다.)

그림 3.9

 

외적은 2D 벡터에서는 동작하지 않는다. 그러나 2D 벡터를 3D 벡터로 변환하면 사용할 수 있다. 2D 벡터를 3D 벡터로 변환하려면 z 요소값 0을 2D 벡터에 추가하면 된다.

기술적으로는 그림 3.9에서 평면에 수직인 두 번째 벡터 -c가 존재할 수 있다. 평면에 수직한 벡터가 2개가 있다는 것은 외적의 중요한 특성을 나타낸다. 즉 외적에서는 교환 법칙이 성립되지 않지만, 교환 후에 그 값을 반전시키면 그결과는 원래의 외적과 동일하다.

 

왼손법칙(left-hand rule)을 사용하면 외적으로 구한 벡터가 향하는 방향을 빠르게 알 수 있다. 왼손의 집게 손가락을 a방향으로 향하고, 중지를 b방향으로 향한다. 필요하다면 손목을 회전시켜도 된다. 엄지 손가락은 자연히 c 방향을 가리키게 된다. 여기서는 왼손을 사용했으며 이 책의 좌표 체계는 왼손 기준이다.(5장 'OpenGL'에서는 더 다양한 좌표계도 알아볼 것이다). 오른손 좌표계에서는 오른손 법칙을 사용한다. 

외적의 수치 계산은 다음과 같다.

외적 계산을 기억하는 인기 있는 니모직(mnemonic)은 'xyzzy'다. 이 니모닉은 x값(x요소) 외적 결과의 첨자 순서를 기억하는 데 도움을 준다.

xyzzy이다.

y와 z값은 x->y->z->x 순서로 회전된 첨자를 가지며, 두 요소의 외적 결과는 다음과 같다.

내적처럼 외적에서도 특별히 고려해야 되는 경우가 있다. 외적이 벡터 (0,0,0)을 반환하면 a와b가 평행하다는 것을 뜻한다. 두 평행한 벡터는 평면을 형성할 수 없다. 그래서 외적은 반환할 법선 벡터를 가지지 못한다.

 

삼각형은 단일 표면상에 놓여 있으므로 외적을 구하는 것이 가능하다. 그림 3.10은 삼각형 ABC를 보여준다. 법선 벡터를 계산하기 위해 먼저 삼각형 변에 해당하는 두 벡터를 만들자.

그러고 나서 두 벡터의 외적을 구하고 그 결과를 정규화한다. 그 결과는 이 삼각형의 법선벡터다.

Math.h 라이브러리는 정적 함수 Cross를 제공한다. 예를 들어 다음 코드는 두 벡터 a,b 사이의 외적을 계산한다.

Vector3 c = Vector3::Cross(a,b);