벡터 크기와 정규화

Unity3D 2018. 9. 6. 19:33
반응형

https://ko.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-vectors/a/vector-magnitude-normalization




방금 봤듯이, 곱하기와 나누기는 벡터의 방향에 영향을 주지 않고 길이를 바꿀 수 있는 하나의 수단입니다. 아마 "그래, 그래서 벡터의 길이를 어떻게 알 수 있지? 벡터 성분 (x와 y)은 알지만 실제 화살표가 몇 픽셀이지?"하고 궁금해 할 수 있습니다. 벡터의 길이(혹은 크기)를 계산하는 방법을 이해하는 것은 굉장히 유용하고 중요합니다.
그림 1.10: 벡터의 길이 혹은 “크기”, v, with, vector, on top는 vertical bar, vertical bar, v, with, vector, on top, vertical bar, vertical bar로 쓸 수 있습니다.
여기서 화살표와 벡터의 성분 (x와 y) 들이 직각삼각형을 이루는 점을 유의하세요. 삼각형의 밑변과 높이는 벡터의 각 성분이고 빗변은 화살표 입니다. 다행이도 위 도형은 직각삼각형입니다. 직각삼각형은 고대 그리스의 수학자 피타고라스가 만든, 두 변과 빗변 사이의 관계를 설명하는 매력적인 공식인 피타고라스의 정리로 더욱 잘 알려진 도형입니다.
피타고라스의 정리는 a의 제곱 더하기 b의 제곱은 c의 제곱과 같다는 것을 정의합니다.
이 공식을 이용하면 다음과 같이 v, with, vector, on top의 크기를 계산할 수 있습니다.
vertical bar, vertical bar, v, with, vector, on top, vertical bar, vertical bar, equals, square root of, v, start subscript, x, end subscript, times, v, start subscript, x, end subscript, plus, v, start subscript, y, end subscript, times, v, start subscript, y, end subscript, end square root
이를 PVector 객체에서 구현하기 위한 코드는 다음과 같습니다:
PVector.prototype.mag = function() {
    return sqrt(this.x*this.x + this.y*this.y);
};
다음 예제는 화면에 생성된 벡터의 크기를 상단의 막대로 보여주고 있습니다.
벡터의 크기를 계산하는 것은 단지 시작에 불과합니다. 벡터의 크기 관련 함수는 매우 많은 가능성을 열어주는 일종의 열쇠와 같습니다. 첫 번째는 정규화 (Normalization) 입니다. 정규화란 무언가를 표준화 시키거나 다른 것과 비교하기 쉽도록 바꾸는 것을 의미합니다. 벡터의 경우를 살펴봅시다. 다른 것들과 비교하기 위해 표준화 시킨 벡터들의 크기를 1 이라고 생각합시다. 어떤 벡터를 이에 맞춰 정규화 시키려면 벡터의 방향은 그대로 두고 크기를 1로 바꾸어 주면 됩니다. 이렇게 만들어진 크기가 1인 벡터를 단위벡터 라고 합니다.
단위벡터는 크기와 상관없이 방향을 정의하므로 여러모로 유용하게 쓰입니다. 다음 단원에서 힘에 대해 배워보게 될 텐데 이 때 단위벡터가 매우 유용하게 쓰일 것입니다.
모든 벡터 u, with, vector, on top에 대해 그 단위벡터 \hat{u}는 다음과 같이 계산할 수 있습니다.
\hat{u} = \dfrac{\vec{u}}{||\vec{u}||}
다르게 말하면 벡터를 정규화하려면 단순하게 벡터의 크기를 그 성분으로 나누어 주면 됩니다. 잘 생각해보면 이해가 쉽습니다. 예를 들어 길이가 5인 어떤 벡터가 있습니다. 5 나누기 5는 1입니다. 위에서 본 직각삼각형의 경우, 빗면의 크기를 1로 맞추기 위해 5로 나누어주는 것입니다. 이 과정에서 나머지 두 개 변도 마찬가지로 5로 나누어져서 크기가 줄어듭니다.
그러므로 PVector 객체에서 정규화(normalization) 함수는 다음과 같이 적용할 수 있습니다.
PVector.prototype.normalize = function() {
  var m = this.mag();
  this.div(m);
};
물론 작은 문제가 하나 있습니다. 바로 벡터의 크기가 0 일때의 경우입니다. 알다시피 숫자 0으로 나누기는 불가능합니다! 이는 다음과 같은 간단한 오류검사로 해결할 수 있습니다:
PVector.prototype.normalize = function() {
  var m = this.mag();
  if (m > 0) {
    this.div(m);
  }
};
다음은 중심으로부터 마우스의 위치를 나타내는 벡터를 항상 정규화하도록 (1 픽셀은 매우 작기 때문에 눈으로 알아 볼 수 있도록 정규화한 후 증가시킵니다!) 짜여진 프로그램입니다.

본 "내추럴 시뮬레이션" 과정은 다니엘 쉬프만(Daniel Shiffman)이 저술한 "The Nature of Code"의 내용을 차용한 것이며, 본 내용물의 저작권은 Creative Commons Attribution-NonCommercial 3.0 Unported License를 적용합니다.


반응형

'Unity3D' 카테고리의 다른 글

피타고라스 정리  (0) 2018.09.06
벡터란?  (0) 2018.09.06
벡터의 이해와 두점의 거리 비교  (0) 2018.09.06
IAP (구글)  (0) 2018.08.11
유니티 에디터 확장 입문(번역글)  (0) 2018.05.15
: