'수학'에 해당되는 글 2건

  1. 2009.02.03 벡터는 벡터일 뿐
  2. 2005.11.22 머리 위의 가마
dev.log2009. 2. 3. 22:19
벡터는 벡터일 뿐, 3차원 벡터는 좌표 3개가 아니다.
3D게임 프로그래밍을 시작하는, 특히 2D게임을 만들다가 3D로 전향하려는 사람들에게서 잘 드러나는 것 같은데, 벡터를 벡터로 보지 않고 계산해야 할 좌표 3개로 보는 경향이 있는 것 같다. 사실, 벡터를 조작하여 얻고자 하는 무언가는 대부분의 경우 주어진 벡터로부터 특정한 방향을 가진 벡터, 혹은 주어진 벡터의 길이와 관계된 것일 경우가 많다. 이런 것을 구하기 위해서는 벡터를 좌표 3개로 분할할 필요가 없는데도, 습관처럼 좌표를 쪼개서 계산한다면, 벡터 연산에 익숙하지 않기 때문일 것 같다.

3차원 공간상의 벡터에 정의된 연산은 대략 반전, 덧셈, 뺄셈, 실수 곱셈, 실수 나눗셈, 그리고 내적과 외적이 거의 전부다. 이를 적절히 이용하면 간략한 표현으로 원하는 결과를 얻을 수 있는데, 좌표로 쪼개서 계산하면 고려해야할 예외적 상황이 증가하여 오히려 코드가 복잡해지는 결과가 초래되곤 한다.

오늘 본 문제는 '어떤 점에서 선분에 내린 수선의 발이 그 선분을 분할하는 비율'이다. 조금 더 상세히 정의하자면 선분의 시작점 s, 끝점 t가 주어졌을때, 임의의 점 p에서 내린 수선의 발 f에 대해서 |sf|/|st|의 값을 구하라는 것이다. 이런 문제는, 고등학교 수학시간에도 나오는 문제이지만, 이를 좌표로 쪼개서 풀려고 다음과 같이 하는 것을 보았다. (정확히 기억하고 있진 않을 수도 있지만)
  1. 각 벡터 p, s, t를 한 평면, 이를테면 xy평면에 투영하여 p', s', t'으로 한다.
  2. xy평면에서 선분s't'의 방향은 ( tx-sx, ty-sy )이다.
  3. xy평면에서 선분s't'과 직교하는 선분의 방향 d는 ( -ty+sy, tx-sx )이다.
  4. p'의 s'에 대한 변위 o를 구한다. 이때 o( p'x-s'x, p'y-s'y )이다.
  5. 점 o를 지나고 d와 평행한 직선과 선분 s't'의 교점 q를 연립방정식으로 구하면 그 점이 수선의 발.
  6. qx/(tx-sx)가 구하고자 하는 값이다.

대충 돌아가기는 하겠지만, 몇가지 예외사항이 존재한다. 우선 과정1에서 선분st가 xy평면에 수직일 경우 다른 평면을 골라 투영해야 한다. 또한 6단계에서 선분s't'이 y축에 평행하면 0/0의 꼴이 되어 부정이 되므로 역시 다른 좌표축을 골라야 한다. 여러가지 복잡한 예외를 고려해야 하기 때문에 결과적으로는 코드 길이가 원래보다 2배 정도 길어지게 마련이다. 하지만, 이는 내적의 성질을 이용해서 다음과 같은 간략한 방법으로 구할 수 있다.

이렇게 하면 선분의 방향이 어떠하든 일반적인 해를 구할 수 있다. 내적은 두 벡터의 길이의 곱에 사잇각의 코사인을 곱한 것과 같다는 성질을 이용한 것인데, 벡터의 길이에 코사인을 곱하면 다른 쪽 벡터에 투영된 길이가 나온다는 점을 생각하면 되겠다.

물론, 이런 방법으로는 길이의 비만 구할 수 있기 때문에 수선의 발 자체가 필요한 경우에는 따로 계산을 해야 하겠지만, 그때에도 위 결과로부터 직접 구할 수 있다. 선분 ts와 선분 fs의 길이의 비를 이미 구했으므로, 선분 ts를 이 비율대로 곱하기만 하면 수선의 발이 직접 구해진다. 따라서 수선의 발 f는 다음과 같이 구할 수 있다.

벡터에 정의된 연산이 몇개가 안되므로, 성급하게 벡터를 좌표로 쪼개려고 하는 것보다는, 벡터 연산으로 요리조리 조작해 보는 편이 더 일반적으로 유효한 결과를 가져온다. 3D프로그래밍의 시작은 벡터를 좌표의 집합이 아닌, 벡터 그 자체로 보는 것이라고나.


Posted by uhm
geek.log2005. 11. 22. 15:37

"사람의 머리에는 가마가 있다"를 수학적으로 표현하면?




Posted by uhm