【ユニティ】ベクトル内積と外積



Unity Vector Dot Product



【参考原文】 Unity3DでのVector3.DotとVector3.Crossの使用
【参考原文】 Unity3Dポイントと差の乗算
Unity3Dでは、Vector3.Dotは2つのベクトルの内積を見つけることを意味しますVector3.Crossは2つのベクトルの外積を見つけることを意味します。

内積計算の結果は数値であり、外積計算の結果はベクトルです。 2つの違いに注意してください。

簡単に言えば、角度を判断するためにポイント乗算を、方向を判断するためにクロス乗算を行います。

視覚的に言えば、敵があなたの後ろにいるとき、クロス乗算はあなたが左に曲がるか右に曲がるかを決定することができます。敵に目を向けたほうがいいです。ドット乗算は、現在の顔の方向と敵への方向の結果を取得します。角度のサイズ。



1.ドット積

a・b = | a |・| b | cos <a、b>

  • | a |および| b |ベクトルのモジュラスを表します
  • 2つのベクトル間の角度を表します。との間の角度は特定の順序ではありません。
  • 2つのベクトル間の角度は、内積で計算できます。

2つのベクトルaとbが単位ベクトルの場合、a.bはベクトルaの方向へのベクトルbの射影の長さに等しくなります。



応用

内積の計算により、現在のオブジェクトが別のオブジェクトに面しているかどうかを簡単かつ大まかに判断できます。現在のオブジェクトのtransform.forwardベクトルと(otherObj.transform.position – transform.position)の内積を計算するだけです。
-結果== 0の場合、2つのベクトルは互いに垂直です。
-結果が> 0の場合、2つのベクトル間の角度は90°未満であり、現在のオブジェクトは
-結果が<0, the angle between the two vectors is greater than 90°, and the current object faces away

2.外積

c = a x b

  • その中で、a、b、cはすべてベクトルです。つまり、2つのベクトルの外積はまだベクトルです!
  • プロパティ1:c⊥a、c⊥b、つまり、ベクトルcがベクトルa、bに垂直な平面。
  • プロパティ2:モジュラスの長さ| c | = | a || b | sin
  • 自然3:右手の法則を満たします。この時点から、axb≠bxa、およびaxb = –bxaになります。したがって、外積の正の値と負の値を使用して、ベクトルaとbの相対位置、つまり、ベクトルbがベクトルaの時計回りまたは反時計回りのどちらの方向にあるかを判断できます。

2つのベクトル間の角度を見つける

using UnityEngine using System.Collections public class MainScript : MonoBehaviour { //Vector a private Vector3 a //Vector b private Vector3 b void Start () { //Initialization of the vector a = new Vector3 (1, 2, 1) b = new Vector3 (5, 6, 0) } void OnGUI () { //Return value of dot product float c = Vector3.Dot (a, b) //The angle between vectors a and b, the obtained value is radians, we will convert it to an angle for easy viewing! float angle = Mathf.Acos (Vector3.Dot (a.normalized, b.normalized)) * Mathf.Rad2Deg GUILayout.Label ('The dot product of vectors a and b is:' + c) GUILayout.Label ('The angle between vectors a and b is:' + angle) //Return value of cross product Vector3 e = Vector3.Cross (a, b) Vector3 d = Vector3.Cross (b, a) //The angle between vectors a and b, the obtained value is radians, we will convert it to an angle for easy viewing! angle = Mathf.Asin (Vector3.Distance (Vector3.zero, Vector3.Cross (a.normalized, b.normalized))) * Mathf.Rad2Deg GUILayout.Label ('The vector axb is:' + e) GUILayout.Label ('The vector bxa is:' + d) GUILayout.Label ('The angle between vectors a and b is:' + angle) } }

上記の例では、2つのベクトルaとbを定義しました。内積と外積がそれぞれ得られ、それらの角度が内積と外積を介して順番に計算されます。
ここで説明します:
1. a.normalizedとb.normalizedは、2つのベクトルの単位ベクトルを表します。これは、式にベクトルと係数の除算があり、結果が単位ベクトル(単位ベクトル係数は1)であるためです。単位ベクトルを直接使用して、ここと後で計算するので、多くの手間を省くことができます。



2. Mathf.Rad2Degは、単位ラジアンの次数を表します。これは2π/ 360です

3.外積による次数の計算は、式| c | = | a || b | sinによる逆の評価です。 | c |は実際には外積のモジュラスです。つまり、Vector3.Distance(Vector3.zero、Vector3.Cross(a.normalized、b.normalized))の値も表します。
結果は次のとおりです。
画像

ドットおよびクロス乗算プロジェクトでのアプリケーション

プロジェクト要件:
1内積によってオブジェクトBがオブジェクトAの前にあるか後ろにあるかを計算します
2オブジェクトAがオブジェクトBに外積で回転するときの最小角度の回転方向を計算します

実装プロセス:
最初にオブジェクトAの順方向ベクトルを計算しますv_Bz = B.transform.forward、次にオブジェクトAに対するオブジェクトBの位置ベクトルを計算しますv_AB = A.position-B.position

ベクトルv_Bzとv_ABの内積の正と負の結果を計算することにより、オブジェクトBがオブジェクトAの前後にあると判断されます。
オブジェクトBがオブジェクトAの前にある場合、Vector3.Dot(v_Bz、v_AB)は0より大きくなります。
オブジェクトBがオブジェクトAの背後にある場合、Vector3.Dot(v_Bz、v_AB)は0未満です。

v_Bzベクトルとv_ABベクトルの外積の結果を計算して、回転方向を決定します。
反時計回りに回転する場合、v_C = Vector3.Cross(v_Bz、v_AB)はy軸に沿った負の方向です。
時計回りに回転すると、v_C = Vector3.Cross(v_Bz、v_AB)はy軸に沿った正の方向になります

using UnityEngine using System.Collections public class Vector3_Dot : MonoBehaviour { public Transform A, B Vector3 v_Bz, v_AB, v_A,v_B,v_C string str = '' // Use this for initialization void Start() { } // Update is called once per frame void Update() { //Dot multiplication v_Bz = B.transform.forward//B.transform.TransformDirection(Vector3.forward) v_AB = A.position - B.position float f = Vector3.Dot(v_Bz,v_AB) if (f>0) { str = 'A is in front of B's ​​own coordinate system' } else if (f<0) { str = 'A is behind B's own coordinate system' } else { str = 'A is in the front left or right of B's ​​own coordinate system' } //Difference multiplication v_A = A.position v_B = B.position v_C = Vector3.Cross(v_Bz, v_AB) // A.Rotate(0,0,0) } void OnGUI() { GUI.Label(new Rect(10,10,200,60),str) } void OnDrawGizmos() { //Difference and multiplication to draw related lines Gizmos.color = Color.blue Gizmos.DrawLine(-v_C,Vector3.zero) //Dot multiply draw related lines Gizmos.color = Color.yellow Gizmos.DrawLine(Vector3.zero,A.position) Gizmos.color = Color.yellow Gizmos.DrawLine(Vector3.zero,B.position) Gizmos.color = Color.red Gizmos.DrawLine(A.position, B.position) Gizmos.color = Color.red Gizmos.DrawLine(Vector3.zero,v_AB) Gizmos.color = Color.green // Gizmos.DrawLine(A.transform.position, Vector3.left) } }

画像

1.次の方法を使用して、前後のターゲットの位置を判断できます。

Vector3.Dot(transform.forward、target.position-transform.position)

戻り値が正の場合、ターゲットはあなたの前にあり、そうでない場合はあなたの後ろにあります。

2.次の方法を使用して、マシンの左右のターゲットの位置を決定できます。

Vector3.Cross(transform.forward、target.position-transform.position).y

戻り値が正の場合、ターゲットは右側にあり、それ以外の場合は左側にあります。