XNA中向量的定義

來源:互聯網
上載者:User

從上篇向量的文章中,我們主要分析出了向量需要包含的資訊和主要的操作。我們總結如下:

  1. 對分量值x,y,z的存取。
  2. 向量間的賦值操作。
  3. 比較兩個向量是否相同。
  4. 得到零向量。
  5. 向量求負。
  6. 向量求模。
  7. 向量與標量的乘除法。
  8. 向量標準化。
  9. 向量加減法。
  10. 兩點(點用向量表示)的距離。
  11. 向量點乘。
  12. 向量叉乘。

以上的這些功能能夠完成我們99%的日常工作,但XNA中也定義了一些其他比較方面的操作,例如直接可以得到向上的單位向量等。那下面我們就看一下XNA中的Vector3是怎麼提供這些功能的。

對分量x,y,z的存取

Vector3類提供了x,y,z的公用欄位,可以直接存取。而且整個類中只有這三個欄位儲存資料,也就是說系統中存在一個Vector3對象時,整個對象只佔用了3個float資料佔用的空間。而且Vector2被定義成了結構,在進行運算時,結構會儲存在棧中,這也會對向量運算等效能的提升帶來協助。而三個分量定義也是沒有用到微軟推崇的屬性,而是直接定義成公用欄位。我想這也有可能是針對效能上的考慮吧。看來,在定義Vertor3在定義時已經把能提高效能的地方都考慮到了,儘管有些執行改善很有限的效能。下面為三個分量在類中的定義:

// 摘要:

        //     Gets or sets the x-component of the vector.

        public float X;

        //

        // 摘要:

        //     Gets or sets the y-component of the vector.

        public float Y;

        //

        // 摘要:

        //     Gets or sets the z-component of the vector.

        public float Z;

向量間的賦值操作

向量間的賦值操作就相當於把這個向量的值賦值給另外一個向量。我們知道,在C#中,參考型別賦值,只是賦值控制代碼,也就是我們平常說的引用。但Vector的要求是把另外一個向量的值都取出來。還好,我們定義的Vector3是結構,也就是實值型別,在使用=操作符賦值時,會產生一個拷貝,能夠滿足我們賦值的要求。所以我們不用再取複寫=操作符了。

比較兩個向量是否相等

在比較兩個向量是否相等部分,Vector3繼承了IEquatable<Vector3>介面,所以在判斷是否相等方面,大家應該知道怎麼用了吧。而且Vector3也複寫了==操作符。在判斷是否相等的演算法上,XNA認為只要向量的三個分量值都分別都相等的話,兩個向量就相等。相關的代碼定義如下:

public struct Vector3 : IEquatable<Vector3>

//

        // 摘要:

        //     Tests vectors for inequality.

        //

        // 參數:

        //   value1:

        //     Vector to compare.

        //

        //   value2:

        //     Vector to compare.

        public static bool operator !=(Vector3 value1, Vector3 value2);

//

        // 摘要:

        //     Tests vectors for equality.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        public static bool operator ==(Vector3 value1, Vector3 value2);

//

        // 摘要:

        //     Returns a value that indicates whether the current instance is equal to a

        //     specified object.

        //

        // 參數:

        //   obj:

        //     Object to make the comparison with.

        public override bool Equals(object obj);

        //

        // 摘要:

        //     Determines whether the specified Object is equal to the Vector3.

        //

        //參數:

        //   other:

        //     The Vector3 to compare with the current Vector3.

        public bool Equals(Vector3 other);

        //

        // 摘要:

        //     Gets the hash code of the vector object.

        public override int GetHashCode();

得到零向量

得到零向量按照邏輯講,應該是一個靜態函數。該方法和已經存在記憶體裡面的Vector3對象應該是沒有什麼關係的。如果程式需要先定義一個向量,然後再調用這個向量的歸零函數,豈不是很麻煩。所以得到零向量的函數定義如下:

//

        // 摘要:

        //     Returns a Vector3 with all of its components set to zero.

        public static Vector3 Zero { get; }

向量求負

向量求負在XNA中用-號操作符定義,例如有一向量A,對向量A求負的話就可以進行下面操作。B=-A;B就是A求負後的向量。

// 摘要:

        //     Returns a vector pointing in the opposite direction.

        //

        // 參數:

        //   value:

        //     Source vector.

        public static Vector3 operator -(Vector3 value);

向量求模

向量求模就是求一個向量的長度,得到標量。這個應該是定義成Vector3對象的函數,而不是靜態。計算模時,會和Object Storage Service的資料有關。XNA中代碼定義如下:

//

        // 摘要:

        //     Calculates the length of the vector.

        public float Length();

向量與標量的乘除法

在XNA中,向量與標量的乘除法都是以複寫*和/操作符實現的。代碼定義如下:

//

        // 摘要:

        //     Multiplies a vector by a scalar value.

        //

        // 參數:

        //   scaleFactor:

        //     Scalar value.

        //

        //   value:

        //     Source vector.

        public static Vector3 operator *(float scaleFactor, Vector3 value);

        //

        // 摘要:

        //     Multiplies a vector by a scalar value.

        //

        // 參數:

        //   value:

        //     Source vector.

        //

        //   scaleFactor:

        //     Scalar value.

        public static Vector3 operator *(Vector3 value, float scaleFactor);

//

        // 摘要:

        //     Divides a vector by a scalar value.

        //

        // 參數:

        //   value:

        //     Source vector.

        //

        //   divider:

        //     The divisor.

        public static Vector3 operator /(Vector3 value, float divider);

而且在Vector3中還定義了乘除的靜態函數,但我感覺用處不是太大,既然已經定義了重載操作符,就沒有必要再定義那些靜態函數了。也有可能我現在還沒有用到,所以覺得那些函數沒用。但那些函數實現的功能和重載操作符是一樣的,就不在列舉了。

向量標準化

向量標準化就是在已有向量對象的基礎上,得到該向量方向的單位向量。因此該函數也應該是一個附屬在類上的普通函數。定義如下:

//

        // 摘要:

        //     Turns the current vector into a unit vector. The result is a vector one unit

        //     in length pointing in the same direction as the original vector.

public void Normalize();

        //

        // 摘要:

        //     Creates a unit vector from the specified vector. The result is a vector one

        //     unit in length pointing in the same direction as the original vector.

        //

        // 參數:

        //   value:

        //     The source Vector3.

        public static Vector3 Normalize(Vector3 value);

        //

        // 摘要:

        //     Creates a unit vector from the specified vector, writing the result to a

        //     user-specified variable. The result is a vector one unit in length pointing

        //     in the same direction as the original vector.

        //

        // 參數:

        //   value:

        //     Source vector.

        //

        //   result:

        //     [OutAttribute] The normalized vector.

        public static void Normalize(ref Vector3 value, out Vector3 result);

在標準化的功能上,XNA提供了三個函數,一個函數是把向量自己標準化。第二個函數是靜態函數,標準化傳入的參數向量。第三個也是靜態函數,傳入一個向量,返回一個新的向量,不在傳入參數的基礎上操作。

感覺XNA在定義標準化功能上搞的太複雜了,我覺得只要留一個就可以了,留第一個或者是第二個靜態函數,就能解決所有的問題。

向量加減法

向量加減法和向量乘除法的實現方式很類似,主要是通過重載運算子,和實現一些靜態函數。當然,我還是覺得那些靜態函數用處不大。定義如下:

//

        // 摘要:

        //     Adds two vectors.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        public static Vector3 operator +(Vector3 value1, Vector3 value2);

//

        // 摘要:

        //     Subtracts a vector from a vector.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        public static Vector3 operator -(Vector3 value1, Vector3 value2);

兩點(點用向量表示)的距離

XNA中不存在Point3的定義,所以在表示某個點時,也是用Vector3來表示。即使有Point3的定義,其內容也只是Vector3的子集。所以一般的三維繫統中都會以Vector3來定義三維點。定義如下:

//

        // 摘要:

        //     Calculates the distance between two vectors.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        public static float Distance(Vector3 value1, Vector3 value2);

        //

        // 摘要:

        //     Calculates the distance between two vectors.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        //

        //   result:

        //     [OutAttribute] The distance between the vectors.

        public static void Distance(ref Vector3 value1, ref Vector3 value2, out float result);

我認為第二個函數也沒有必要。

向量點乘

向量點乘也是採用了複寫*號操作符的方法。定義如下:

//

        // 摘要:

        //     Multiplies the components of two vectors by each other.

        //

        // 參數:

        //   value1:

        //     Source vector.

        //

        //   value2:

        //     Source vector.

        public static Vector3 operator *(Vector3 value1, Vector3 value2);

兩個向量的運算有兩種乘法,點乘和內積。但作為表示乘的操作符只有一個*號,所以我們只能選擇一個,捨棄一個。但似乎*號更像點,而不像叉。所以XNA和大部分的三維繫統都會以*號表示點乘。

向量叉乘

向量叉乘,也就是我們說的向量叉積了。其實我們也可以複寫其他動作符來完成叉乘操作。但誰能想到用這個操作符呢?這回造成晦澀難懂的代碼,不如用函數定義。在這個方面,很多三維平台的想法都是一致的。

//

        // 摘要:

        //     Calculates the cross product of two vectors.

        //

        // 參數:

        //   vector1:

        //     Source vector.

        //

        //   vector2:

        //     Source vector.

        public static Vector3 Cross(Vector3 vector1, Vector3 vector2);

        //

        // 摘要:

        //     Calculates the cross product of two vectors.

        //

        // 參數:

        //   vector1:

        //     Source vector.

        //

        //   vector2:

        //     Source vector.

        //

        //   result:

        //     [OutAttribute] The cross product of the vectors.

        public static void Cross(ref Vector3 vector1, ref Vector3 vector2, out Vector3 result);

其他的功能

除了以上的這些功能,XNA中的Vector3類也提供了一些其他比較方便的功能。例如:

  1. 得到各個方向的單位向量

// 摘要:

        //     Returns a unit Vector3 designating backward in a right-handed coordinate

        //     system (0, 0, 1).

        public static Vector3 Backward { get; }

        //

        //摘要:

        //     Returns a unit Vector3 designating down (0, −1, 0).

        public static Vector3 Down { get; }

        //

        //摘要:

        //     Returns a unit Vector3 designating forward in a right-handed coordinate system(0,

        //     0, −1).

        public static Vector3 Forward { get; }

        //

        //摘要:

        //     Returns a unit Vector3 designating left (−1, 0, 0).

        public static Vector3 Left { get; }

        //

        //摘要:

        //     Returns a Vector3 with ones in all of its components.

        public static Vector3 One { get; }

        //

        //摘要:

        //     Returns a unit Vector3 pointing to the right (1, 0, 0).

        public static Vector3 Right { get; }

        //

        //摘要:

        //     Returns the x unit Vector3 (1, 0, 0).

        public static Vector3 UnitX { get; }

        //

        //摘要:

        //     Returns the y unit Vector3 (0, 1, 0).

        public static Vector3 UnitY { get; }

        //

        //摘要:

        //     Returns the z unit Vector3 (0, 0, 1).

        public static Vector3 UnitZ { get; }

        //

        //摘要:

        //     Returns a unit vector designating up (0, 1, 0).

        public static Vector3 Up { get; }

  1. 得到三個點組成的三角面的中心點,當然點還是用向量表示。

//

        // 摘要:

        //     Returns a Vector3 containing the 3D Cartesian coordinates of a point specified

        //     in Barycentric coordinates relative to a 3D triangle.

        //

        // 參數:

        //   value1:

        //     A Vector3 containing the 3D Cartesian coordinates of vertex 1 of the triangle.

        //

        //   value2:

        //     A Vector3 containing the 3D Cartesian coordinates of vertex 2 of the triangle.

        //

        //   value3:

        //     A Vector3 containing the 3D Cartesian coordinates of vertex 3 of the triangle.

        //

        //   amount1:

        //     Barycentric coordinate b2, which expresses the weighting factor toward vertex

        //     2 (specified in value2).

        //

        //   amount2:

        //     Barycentric coordinate b3, which expresses the weighting factor toward vertex

        //     3 (specified in value3).

        public static Vector3 Barycentric(Vector3 value1, Vector3 value2, Vector3 value3, float amount1, float amount2);

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.