'Degree'에 해당되는 글 1건

  1. 2011.04.05 Vector 추가 설명
2011.04.05 02:34

우선 벡터의 내적과 외적, 법선벡터를 알아 보겠습니다.
먼저 벡터의 내적과 외적을 알기전에 벡터에 대해 조금만 얘기하겠습니다.
당연히 수학적인 부분이지만 쉽게 설명해 보겠습니다.

 

 

1. 벡터

 

3차원 좌표상에 점을 표시할때 일반적으로 x, y, z 3개의 좌표를 가지고
화면의 점을 그림니다. 이때 수학적으로 점이란 눈에 안보이는 것이지만
점을 구성하는 좌표 성분으로 P(x, y, z)라고 지정합니다.

 

벡터란 원점을 기준으로한 점이라고 생각하면 쉽게 설명할 수 있을 것
입니다. V(x, y, z)를 표시할때 결국 (0, 0, 0)에서 (x, y, z)의 방향을 가르키는
말이며 V(1, 1, 1)와 U(3,3)은 결국 크기만 다르지 같은 방향을 가르키고 있습니다.

 


2. 단위 벡터의 특성

 

단위 벡터란 크기(길이)가 1인 벡터를 얘기 합니다.

(길이가 1인 벡터를 norm(노름) nomalize 벡터라고 합니다.)

 

0 에서 1까지의 실수는 아무리 곱해서 절대로 1을 넘지 않죠?
이 특성이 단위 벡터에서도 나타납니다.


단위 벡터끼리 곱하는 연산은 1000만번을 한다하더라도 단위 벡터 이겠죠.

사실 위의 예기는 아주 중요한 얘기이며 이 간단한 사실만으로
연산을 아주 간소화 할수 있습니다.

 

그럼, 단위 벡터는 어떻게 만드는가?
U(1, 1, 1)와 V(2, 2, 2)는 크기가 다르지만 방향을 같다고 했습니다.
두 벡터를 크기는 무시하고 오직 방향만 계산하고 싶다고 할때
단위 벡터를 만듭니다.

 

결국 크기는 1이니까..

같은수에다 같은수를 나누어 봅니다.


예를 들어 8 / 8 = 1, 7676 / 7676 = 1 (역시 1이네요)

단위 벡터도 이렇게 구합니다.

 

벡터 V(x, y, z)가 있을때 벡터의 크기는

sqrt( (Vx * Vx) + (Vy * Vy) + (Vz * Vz) )가 됩니다. 
그럼, 이걸로 나누면 되겠죠?

그리고 임의위 벡터 V의 크기를 표시할때는 |V|라고 표시 합니다.

 

|V| = sqrt( (Vx * Vx) + (Vy * Vy) + (Vz * Vz) );

(norm) V = (Vx /|V|) + (Vy /|V|) + (Vz /|V|) ); 가 됩니다.

 

마지막으로 계산된 벡터가 1의 길이인지 확인하고자 한다면 다음과 같이 합니다.

 

크기 = sqrt( (Vx * Vx) + (Vy * Vy) + (Vz * Vz) )는 1이 나와야 한다.

이것은 영어로 Normalize라고 한다.

 

 

3. 벡터의 내적 과 두 벡터를 이용한 각도 구하기

 

이제 좀 어려운 부분을 얘기 하겠습니다.
벡터의 내적은 수학정석에 나와 있습니다.


영어로 DotProduct 혹은 inner-Product, Scalar-Product라고 하더군요...
벡터의 내적 공식은 두 벡터가 있을때 두 벡터 사이의 각도를
구하는데 사용됩니다.

 

두 벡터 U와 V가 있을때 의 두 벡터간의 내적은 U●V라고 표시 합니다.

그럼 U●V를 계산하는 공식을 알아 보겠습니다.

 

[1] U●V = ( (Ux * Vx) + (Uy * Vy) + (Uz * Vz)으로 나옵니다.

그리고 또 다른 공식은

[2] U●V = |U| * |B| * cos(#세타)으로도 나옵니다.

 

여기서 잠깐 내적의 특징에 대해 알아보겠습니다.

위 [1]번의 공식에 의해 나온 값은 두 벡터간의 각도에 있어서 중요한

정보를 담고 있습니다.

 

[1]의 공식에 의해 나온 값이 0이면 두벡터간의 각도가 90도 입니다.

[1]의 공식에 의해 나온 값이 0보다 작다면( 0 > U●V ) 두벡터간의 각도는 90도보다 큽니다.

[1]의 공식에 의해 나온 값이 0보다 크다면( 0 < U●V ) 두벡터간의 각도는 90도보다 작습니다.

 

결과를 표면 내적은 특정한 정보를 찾는데 유용하게 쓰이겠죠??

그럼 우리가 알고 싶은 것은 위의 공식들을 이용해 실재 두벡터간의 각도를 구하는 것 입니다.

위의 공식들을 다시 풀어보면 다음과 같이 나옵니다.

 

[1]과 [2]의 공식을 조합해 봅시다.

[1] U●V = ( (Ux * Vx) + (Uy * Vy) + (Uz * Vz);

[2] U●V = |U| * |B| * cos(#세타);

 

우리가 알고 싶은 정보는 cos(#세타)에 들어 있기 때문에 두공식을 이용해 좌우로 이동시켜 보면

 

                                     U●V

[3] cos(#세타) =         -----------      가 나오고

                                  |U| * |V|

 

 

이 공식에서 실재 알고자 하는 라디안 값을 추려내게 되면 다음과 같은 공식이 됩니다.

 

                                                       (  ( (Ux * Vx) + (Uy * Vy) + (Uz * Vz)   )

(라디안(각도)) #세타 = (아코사인)acos{   ---------------------------------   } 이 나옵니다.

                                                       (                    |U| * |V|                    )

 

 

우선 위 공식의 두 대치된 오른쪽에서 큰 괄호 안을 살펴보겠습니다.

(U●V) / (|U| * |V|)에서 우리가 알고자 하는 최종 정보(각도)를 얻는데는 벡터의 크기(길이)

가 몇이든 상관이 없기 때문에 이 두 벡터를 단위 벡터로 만들면 좀더 계산하기 쉬운 공식으로

바뀌게 됩니다.

 

(|U| * |V|)값이 모두 1길이의 단위 벡터가 되면 위 공식에서 나눗셈 부분이

(U●V) / 1 이 되기 때문에 남는 공식은 다음과 같이 되겠죠.

 

#세타 = acos( U●V =  ( (Ux * Vx) + (Uy * Vy) + (Uz * Vz) );

 

정말 단순화 되었죠 ^^?

 

acos(x)함수의 인자로 들어가는 값은 다음과 같습니다.

-1 >=  x <= 1

 

acos(-1) ~ acos(1)이라는 범위는 최종 라디안 값의 0 ~ 파이 값을 가집니다.

 

acos(-1) = 파이 ; [두벡터의 각이 180도를 의미]

acos(0) = 파이 / 2 ; [두벡터의 각이 90도를 의미]

acos(1) = 0 ; [두벡터의 각이 0도를 의미]

 

위에서 본 것처럼 acos( U●V )값을 통해 나온 값이 라디안 값으로 표시되는 최종 각도가 됩니다.

 

***** acos(x)를 계산 하는 공식을 나름데로 만들어 봤습니다 정확히 맞을지는 잘.. ^^; *****

 

acos(x) = 파이 * ( |(x - 1.0)| / 2.0 )

=> |(x - 1.0)|  부분은 절대값입니다

 

x는 -1 부터 1의 범위이고 만약 x가 1이라면

두 벡터의 각도는 [180도 = (radian값)파이가 나요죠 => 3.141592~]

 

그럼 위의 공식에 대입해 보면 구하고자 했던 각도값(radian)은

acos(-1) = 3.141592 * ( |(-1 - 1.0)| / 2.0 ) = 3.141592 가 나옴니다.

 

***********************************************************************************

 

 

 

마지막으로 삼각 함수에 대해 아는것만 정리해 보겠습니다.

 

acos() : double acos(double x)

함수 acos()는 전달된 인수의 아크코사인 값을 돌려준다. 인수 x는 -1 <= x <= 1의 범위에 포함되

어야 하고, 보귀값은 0 <= acos <= π의 범위를 가집니다.

 

asin() : double asin(double x)

함수 asin()은 전달된 인수의 아크 사인값을 돌려준다. 인수 x는 -1 <= x <= 1의 범위에 포함되어야

하고, 복귀값은 -π/2 <= asin <= π/2의 범위를 가집니다.

 

atan() : double atan(double x)

함수 atan()은 전달된 인수의 아크 탄젠트값을 돌려준다. 보귀값은 -π/2 <= atan <= π/2의 범위를

가집니다.

 

atan2() : double atan2(double x, double y)

함수 atan2()는 x/y의 아크 탄젠트값을 돌려준다. 복귀값은 -π <= atan2 <= π의 범위를 가집니다.

 

cos() : double cos(double x)

함수 cos()는 전달된 인수의 코사인값을 돌려줍니다.

 

sin() : double sin(double x)

함수 sin()은 전달된 인수의 사인값을 돌려줍니다.

 

tan() : double tan(double x)

함수 tan()은 전달된 인수의 탄젠트값을 돌려줍니다.

 

지수 함수와 로그 함수

exp() : double exp(double x)

함수 exp()는 전달된 인수의 지수값ex를 돌려줍니다. e는 2.7182818284590452354 입니다.

 

log() : double log(double x)

함수 log()는 전달된 인수의 자연 로그값을 돌려줍니다. 인수는 0보다 커야합니다.

 

log10() : double log10(double x)

함수 log10()은 전달된 인수에 대해서 밑수를 10으로 가지는 로그값을 돌려줍니다.

인수는 0보다 커야 합니다.

 

frexp() : double frexp(double x, int *y)

함수 frexp()는 x라는 값을 생성하는 수식을 구한다. 함수의 복귀값 r은 0.5 <= r <= 1.0의 범위를 가

진다. 함수는 y에 x = r*2y의 정수형 지수를 할당한다. 함수에 전달되는 값이 0이라면, r과 y는 0이

됩니다.

 

ldexp() : double ldexp(double x, int y)

함수 ldexp()는 x*2y의 값을 돌려줍니다.

출처를... 까...깜빡했다... 주소가 기억이 안나... 죄송...
보시면 댓글을 ;ㅁ; 

신고
Posted by 우엉 여왕님!! ghostkyow

티스토리 툴바