為了回答這些問(wèn)題,需要擴(kuò)展向量類(lèi),在其中添加基本的向量方法。本章中的示例將以前面章節(jié)中的代碼為基礎(chǔ)。其中的大多數(shù)示例都要求創(chuàng)建一個(gè)新的游戲狀態(tài),并使其成為活動(dòng)的狀態(tài)以測(cè)試代碼。本章所有的示例代碼都可以從本書(shū)配套光盤(pán)中的Code\Chapter 8目錄中找到。下面的小節(jié)將解釋各種向量操作,并列出完成向量類(lèi)所需添加的代碼。游戲引擎中有時(shí)候會(huì)有Vector2d、Vector3d和Vector4d,但是在這里只創(chuàng)建一個(gè)向量結(jié)構(gòu)會(huì)更加簡(jiǎn)單一些,這個(gè)向量仍然可以用于任意的2D操作。本書(shū)中的內(nèi)容不會(huì)涉及4D向量。
[StructLayout(LayoutKind.Sequential)]
public struct Vector
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public Vector(double x, double y, double z) : this()
{
X = x;
Y = y;
Z = z;
}
}
8.2.2 長(zhǎng)度操作
長(zhǎng)度操作以一個(gè)向量作為參數(shù),返回該向量的大小。對(duì)于簡(jiǎn)單的向量,如[0,1,0],很容易看出長(zhǎng)度為1。但是對(duì)于復(fù)雜一些的向量,如[1.6,-0.99,8],很難一眼看出其長(zhǎng)度。如下所示的公式可以計(jì)算向量的長(zhǎng)度。
v旁邊的兩條豎線是數(shù)學(xué)上表示向量長(zhǎng)度的一種方法。該公式對(duì)于任意維度的向量都是相同的:計(jì)算成員的平方值,將這些值相加,然后取其平方根。
用代碼表示這個(gè)公式很簡(jiǎn)單。這里使用了兩個(gè)函數(shù):一個(gè)用于計(jì)算成員的平方值,然后對(duì)這些平方值求和;另一個(gè)函數(shù)執(zhí)行求平方根的運(yùn)算。
public double Length()
{
return Math.Sqrt(LengthSquared());
}
public double LengthSquared()
{
return (X * X + Y * Y + Z * Z);
}
如果想要比較兩個(gè)向量的長(zhǎng)度,可以采用LengthSquared操作,而不是采用Length操作,這樣可以省去球平方根的操作,從而使代碼更高效一些。
8.2.3 向量的相等性
如果所有的成員值(X、Y和Z)都相等,則認(rèn)為向量是相等的。向量沒(méi)有位置,它們只是從某個(gè)原點(diǎn)開(kāi)始的一個(gè)方向。圖8-3顯示了一組向量,可以看到,即使一些向量放到了不同的位置,它們?nèi)匀皇窍嗟鹊模驗(yàn)樗鼈兊某蓡T是相等的。不管是從你的房子向北3英里,還是從吉薩金字塔向北3英里,它都一樣是向北3英里。
為向量創(chuàng)建一個(gè)Equals函數(shù)是很簡(jiǎn)單的。
public bool Equals(Vector v)
{
return (X == v.X) && (Y == v.Y) && (Z == v.Z);
}
在代碼中,如果重載了==操作符的話,就更方便了?,F(xiàn)在,還不能編寫(xiě)下面的代碼。
// Cannot write this
if (vector1 == vector2)
{
System.Console.WriteLine("They're the same")
}
// Instead must write
if (vector1.Equals(vector2))
{
System.Console.WriteLine("They're the same")
}
要使用==操作符,需要重載該操作符,還需要重寫(xiě)其他一些函數(shù)或操作符,如GetHashCode、!=和Equals(Object obj)。