Unity 中的向量的 相關使用1
Unity 中的 Vector向量的 相關使用1
孫廣東 2015.10.28
以下頁面提供有關在您的程式碼中有效地使用向量的一些建議。
理解向量演算法
向量算術是 3D 圖形、 物理和動畫的基礎,深度的理解它是有用的。下面是主要的操作和一些建議,它們可以用於許多的事的說明。
當兩個向量相加時,結果是相當於以原始向量為”步驟”,一個接一個。請注意這兩個引數的順序並不重要,因為結果是相同的無論哪種方式。
如果第一個向量作為空間中的點然後第二個可以被解釋為一個偏移量,或者從這一個位置”跳”到另一個位置。例如,找到地面以上 5 個單位 上的某個位置,可以使用以下的計算方法:-
var pointInAir = pointOnGround + new Vector3(0, 5, 0);
如果向量代表力量,那麼它是更加直觀,他們代表了方向和大小 (大小表示力的大小)。新增兩個力在一個新的向量的向量結果等於力量的結合。這一概念經常是有用的當施加力與幾個單獨的元件,立刻採取行動 (如,被推著向前走火箭可能也受側風)。
向量減法是最常用的去的方向和距離從一個物件到另一個。注意這兩個引數的順序無關緊要用減法:-
// The vector d has the same magnitude as c but points in the opposite direction.
var c = b - a;
var d = a - b;
作為數字,新增負的一個向量是 這兩個向量 反著減。
// These both give the same result.
var c = a - b;
var c = a + -b;
負的一個向量具有相同的原始大小和點沿同一行,但在相反的方向。
標量乘法和除法
一個向量乘以一個標量結果指出在原方向相同的向量。然而,新向量大小等於乘以標量值的原始大小。
當向量表示運動的一個偏移量或一種力量,這些操作很有用。他們允許您更改該向量的大小而不影響它的方向。
當任何向量除以其自身magnitude時,結果是一個向量,其大小是 1,被稱為歸一化的向量。如果一個歸一化的向量乘以一個標量結果大小將等於該標量值。 這是有用的當力的方向不變,但強度是可控 (例如,從一輛車的車輪力總是向前推但功率控制由驅動程式)。
點積
點積採用兩個向量,並返回一個標量。這個標量等於兩個向量相乘的結果乘以向量之間的角度的餘弦值的大小。當這兩個向量的歸一化時,餘弦值基本上是第一個向量在第二方向上投影 (或反之亦然-引數的順序並不重要)。
它從的角度來考慮很容易,然後使用計算器找到相應的餘弦。但是,它很有用要直觀地瞭解一些主要的餘弦值,如下圖所示:-
點積是一個非常簡單的操作,可以使用 Mathf.Cos 函式代替或向量幅度操作在某些情況下 (它不會做同樣的事情,但有時效果是等效)。然而,計算點積功能需要更少的 CPU 時間,所以它可以是一種有價值的優化。
差積
結果向量是垂直於兩個輸入向量。”左手規則”可以用來記住輸出向量的方向從排序的輸入向量。如果第一個引數匹配到拇指的手和食指的第二個引數,然後結果會指向方向的中指。如果顛倒的引數順序然後結果向量會指向相反的方向,但會有同一數量級。
結果大小等於輸入的向量相乘,然後該值乘以他們之間角度的正弦值的大小。一些有用的正弦函式值如下所示:-
從一個物件到另一個物件的方向和距離
相減 就是 方向了
// Gets a vector that points from the player's position to the target's.
var heading = target.position - player.position;
指向目標物件的方向,這個向量的大小等於兩個位置之間的距離。物件之間的距離等於方向向量的大小和 此向量可以除以其大小 得到歸一化的方向處理:-
var distance = heading.magnitude;
var direction = heading / distance; // This is now the normalized direction.
這種方法最好是使用大小(magnitude )和歸一化(normalized )屬性兩個分開,因為它們是兩個相當消耗CPU(他們都涉及計算平方根)。
如果你只需要使用距離進行比較 (接近檢查等) 然後你可以完全避免計算magnitude 等。SqrMagnitude 屬性是大小的 平方值,像大小但無需耗時開平方根操作。而比比較針對距離的大小,您可以比較距離平方的量:-
if (heading.sqrMagnitude < maxRange * maxRange) {
// Target is within range.
}
這是比在比較真實大小的更高效。
有時,一個目標的地上的heading 是必需的。例如,想象站在地上的Player需要接近一個漂浮在空中的目標。如果你減去的目標從球員的位置然後結果向量將指向向上的目標。這是不適合面向玩家的變換,因為他也會指向上方 ; 真正需要的是從 Player 的位置到地上直接低於目標位置向量。這很容易獲得該減法運算的結果,將 Y 座標設定為零:-
計算一個法線/垂直向量
一個法線向量 (即垂直於平面的向量) 在網格生成過程中經常需要,也可能用於路徑跟蹤和其他情況。鑑於三個點在平面上,說網格三角形的角點,很容易找到法線。拿任何三個點,然後其中任意兩點相減得出兩個向量:-
var a: Vector3;
var b: Vector3;
var c: Vector3;
var side1: Vector3 = b - a;
var side2: Vector3 = c - a;
這兩個向量叉積cross 會得出第三個向量也就是垂直於表面的向量。 “左手規則” 可以用來決定法線的法線。
var perp: Vector3 = Vector3.Cross(side1, side2);
如果輸入向量的順序相反的結果將完全相反的方向。
對於網格,法向量必須是規範化的。這可以通過歸一化normalized 的屬性,但還有另一個技巧是偶爾有用的。你也可以除以其大小得到啊:-
var perpLength = perp.magnitude;
perp /= perpLength;
原來三角形的面積等於 perpLength / 2。這是有用的如果你需要找到整個網格的表面面積 或想要基於其相對領域的概率隨機選擇三角形。
方向和距離從一個物件到另一個
一個向量在另一個向量上的投影大小
一輛車的車速表工作通常通過輪子的轉速測量。這輛車可能不會直接向前移動(它可能會側身打滑) 這個案例部分的議案不會方向測速儀可以測量。物件 rigidbody.velocity 向量是在其整體運動的方向的,如果要求得 向前的速度:-
var fwdSpeed = Vector3.Dot(rigidbody.velocity, transform.forward);
自然,方向可以是任何你喜歡但方向向量總是必須這種計算 歸一化。不只是結果比速度的大小更正確,也避免了慢平方根運算參與尋找大小。