유니티에서 벡터를 사용하여 내적, 외적을 구하는 예
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 () {
}
}