본문 바로가기

Unity3D Tank/Vector

Vector in Unity

유니티에서 벡터를 사용하여 내적, 외적을 구하는 예



using UnityEngine;

using System.Collections;


public class VectorDemo : MonoBehaviour {

// Use this for initialization

void Start () {

}

// 내적(Dot Product, Inner Product, Scalar Product)을 이용하여 두 벡터 사이의 각도를 구하는 예

private void AngleBetweenVector2 ( Vector2 Va, Vector2 Vb){

/* Va dot Vb = |Va| |Vb| Cos theta

* Cos theta = (Va dot Vb) / (|Va| |Vb|)

* Angle = Acos ((Va dot Vb) / (|Va| |Vb|))

* Va, Vb 가 정규화된 벡터라면 (|Va| |Vb|))=1 이므로 

* Angle = Acos ((Va dot Vb))

*/

float dotValue = Vector2.Dot (Va, Vb);

print ("1. 두벡터 내적=" + dotValue); // 0

dotValue = Vector2.Dot (Vb, Va);

print ("2. 두벡터 내적=" + dotValue); // 0

// 벡터 정규화(Normalizing)

Va.Normalize ();

Vb.Normalize ();

float lengthA = Va.magnitude;

print ("3. 정규화된 벡터의 크기=" + lengthA);

// 정규화된 벡터 사이의 각도(Radian)

float radian = Mathf.Acos (Vector2.Dot (Va, Vb));

print ("4. 두 벡터 사이의 각도(Radians)=" + radian);

float degree = Mathf.Rad2Deg * radian;

print("5. Degrees="+degree);

}

// Va 가 Vb 에 수직으로 투영된 길이 구하는 예 (내적의 기하학적 의미)

private void ProjectionLength() {

// Va, Vb가 정규화된 상태라면, Va가 Vb에 수직 투영된 값이나, Vb가 Va에 투영된 값은 동일하다

// 그러나 두 벡터가 단위벡터가 아니라면 그 값은 달라지므로 내적을 구할 때 우선 정규화(Normalizing)해야 한다

// 정규화를 거쳐 내적을 구하고 내적값에 벡터 Va의 크기를 곱하면 Va가 Vb에 수직 투영된 값을 구할 수 있고

// 내적값에 벡터 Vb의 크기를 곱하면 Vb가 Va에 수직 투영된 값을 구할 수 있다

/**정규화하지 않고 내적값을 구하는 경우, 정확한 내적값을 구할 수 없다*/

Vector2 Va = new Vector2 (3f, 4f); // 정규화 안된 벡터

Vector2 Vb = new Vector2 (2f, 0f); // 정규화 안된 벡터

float dotValue = Vector2.Dot (Va, Vb);

print ("1. Va, Vb 내적=" + dotValue);// 6, 정확한 값이 아님

/** 정확한 내적을 구하기 위한 절차 */

float lengthA = Va.magnitude;

float lengthB = Vb.magnitude;

print ("2. Va의 크기=" + lengthA); // 5

Va.Normalize ();

Vb.Normalize ();

dotValue = Vector2.Dot (Va, Vb); 

// 단위벡터 내적값은 코사인비와 같으므로 벡터A의 크기를 곱하면 Vb에 투영된 길이를 알 수 있다

float projectionA2B = dotValue * lengthA;

print ("3. Va가 Vb에 수직으로 투영된 길이=" + projectionA2B);// 3

float projectionB2A = dotValue * lengthB;

print ("4. Vb가 Va에 수직으로 투영된 길이=" + projectionB2A);// 1.2

}

/** 벡터와 스칼라 값을 곱하여 방향은 유지하고 크기만 변경하는 예*/

private void Vector2Multiply(){

Vector2 Va = new Vector2 (1f, 0f);

Vector2 Vb = Va * 3f;

print ("벡터의 성분 변화 x=" + Vb.x + ", y=" + Vb.y); // x=3, y=0

}

/** 벡터의 외적(Cross Product, Outer Product)을 이용한 회전방향 구하기 */

private void Vector3Cross() {

Vector3 Va = new Vector3 (0f, 1f, 0f); //수직벡터

Vector3 Vb = new Vector3 (1f, 0f, 0f); //수평벡터

// 벡터의 외적은 연산에 참여하는 두벡터에 모두 수직인 벡터(음의 벡터, 양의벡터)를 구하는 계산이다

// 벡터의 회전시 시작벡터에서 끝벡터로 회전하는 방향이 시계방향일 경우 양의 방향으로 간주한다

// Va, Vb는 서로 직각을 이루고 있으므로 Va가 Vb까지 90회전하려면 +90도, -90도 방향 중 어떤 방향으로 회전해야 하나?

// Va, Vb를 외적하여 산출되는 결과 벡터의 z 값이 음수인지 양수인지 확인하면 된다

Vector3 Vc = Vector3.Cross (Va, Vb);

print ("Va to Vb = " + Vc.z); // -1

Vc = Vector3.Cross (Vb, Va);

print ("Vb to Va = " + Vc.z); // 1

}


// Update is called once per frame

void Update () {

}

}