[Unity] 벡터의 외적과 내적

남생이야·2024년 4월 29일

벡터란?
 크기와 방향을 가지는 물리적 양을 말한다. 사실 실제로는 방향만 가지고 있다.

  • 벡터 + 벡터 = 그 만큼 이동한 위치를 나타낸다.
  • 벡터1 - 벡터2 = 벡터2가 벡터1을 바라 보는 방향을 나타낸다.

                      파란선으로 나타낸 초록색 큐브(벡터) - 흰 큐브(벡터)의 결과

방향 벡터의 길이는 거리다. 그러나 방향 벡터는 정규화하여 사용한다.

위 코드에서 정규화(normalized)를 하여 계산에 추가

정규화를 통해 거리값을 곱하는 것만으로 쉽게 결과를 얻을 수 있다.

벡터의 내적 (Dot Product)

  • 벡터의 내적은 벡터를 수처럼 곱하는 개념이다.
  • 두 방향 벡터의 내각을 구할 수 있다. 게임에선 각도의 개념은 우리가 일상에서 사용하는 60분법을 사용하지 않는다. 특정 대상을 기준으로 왼쪽인지 오른쪽인지를 구하기 쉽게 하기 위해 사용한다. (호도법 = 라디안)

특정 대상 물체 뒤(180도)에 갈수록 -1에 가까워 진다.

벡터의 외적 (Cross Product)

  • 벡터의 내적은 좌우를 구분 지을 수 없다는 문제가 있다. 이를 해결하기 위해 벡터의 외적이라는 개념을 사용한다.
  • 벡터의 외적의 결과는 방향이 나타난다.
  • Unity 기준 평면된 방향으로 Z축 이동해도 Y축의 길이는 항상 일치한다.

녹색 큐브를 흰색 큐브 왼쪽으로 이동하면 녹색 기즈모선은 흰색 큐브 아래로 나타난다.

etc.

벡터의 내적과 외적을 동시에 쓰는면 60분법각을 구할 때 사용할 수 있다.

using UnityEngine;

public class Test_Vector : MonoBehaviour
{
    [SerializeField]
    private GameObject cube2;

    private Vector3 result; 


    private void Start ()
    {
        //transform.position = transform.position + new Vector3(2, 0, 3);
    }

    private void Update()
    {
        Vector3 position = transform.position;
        Vector3 position2 = cube2.transform.position;

        result = position2 - position;
    }

    [SerializeField]
    private float distance = 5.0f;

    private float dot;
    private Vector3 cross; 

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawLine(transform.position, transform.position + transform.forward * distance);


        Vector3 from = transform.position;
        Vector3 to = result;

        Gizmos.color = Color.blue;
        //Gizmos.DrawLine(from, from + to);

        Vector3 normal = result.normalized;
        Gizmos.DrawLine(from, from + normal * 5.0f);

        dot = Vector3.Dot(transform.forward, result.normalized);

        Gizmos.color = Color.green;
        cross = Vector3.Cross(transform.forward, result);
        Gizmos.DrawLine(transform.position, transform.position + cross);
    }

    private void OnGUI()
    {
        GUI.color = Color.red;
        GUILayout.Label(dot.ToString());
        GUILayout.Label(cross.ToString());

        float y = Vector3.Dot(cross, Vector3.up);   // y값만 가져올 수 있다. 모든항을 곱하고 더하니 특정 값만 가져올 수 있음
        GUILayout.Label(y.ToString());

        float sign = Mathf.Sign(y); // 0보다 작으면 -1 
        GUILayout.Label(sign.ToString());
    }
}

0개의 댓글