8.2.8 關(guān)于向量結(jié)構(gòu)的最后一點(diǎn)內(nèi)容
現(xiàn)在已經(jīng)完成了一個很不錯的、功能完善的向量結(jié)構(gòu),但是稍加一些處理,還可以使這個結(jié)構(gòu)更加容易使用。首先,可以重寫ToString方法,使其輸出一些有用的內(nèi)容。在Visual Studio中使用調(diào)試器時,將自動調(diào)用ToString方法。重寫這個方法后,可以立刻了解向量,而不需要仔細(xì)分析向量的定義并查看它可以取的各個值。
public override string ToString()
{
return string.Format("X:{0}, Y:{1}, Z:{2}", X, Y, Z);
}
0向量是一個特殊的向量,它沒有單位向量。0向量不代表方向,也沒有大小。它有些類似于向量中的null。因此,把它定義為一個常量是很有幫助的。
[StructLayout(LayoutKind.Sequential)]
public struct Vector
{
public static Vector Zero = new Vector(0, 0, 0);
這是所需的全部向量操作。通過這個簡單的結(jié)構(gòu),可以構(gòu)建并操作一個完整的3D世界。如果現(xiàn)在還不能完全理解向量的所有特性,也不用擔(dān)心,這是一個熟能生巧的過程。
8.3 二維相交
相交用于判斷兩個形狀何時重疊或相交。在所有的圖形編程(包括游戲)中這都很重要。檢測鼠標(biāo)指針是否在一個按鈕上就是一種相交測試。在游戲中,檢測一個導(dǎo)彈是否擊中飛船也是一種相交性測試。2D相交十分簡單,可以作為一個不錯的起點(diǎn)。
8.3.1 圓
圓通過位置和弧度定義。相交以圖形化方式顯示最容易理解。接下來就創(chuàng)建一個游戲狀態(tài)CircleIntersectionState,使其成為默認(rèn)加載的狀態(tài)。
class CircleIntersectionState : IGameObject
{
public CircleIntersectionState()
{
Gl.glLineWidth(3);
Gl.glDisable(Gl.GL_TEXTURE_2D);
}
#region IGameObject Members
public void Update(double elapsedTime)
{
}
public void Render()
{
}
#endregion
}
現(xiàn)在狀態(tài)只是準(zhǔn)備好OpenGL,使其可以畫線。接下來需要創(chuàng)建Circle類。
public class Circle
{
Vector Position { get; set; }
double Radius { get; set; }
public Circle()
{
Position = Vector.Zero;
Radius = 1;
}
public Circle(Vector position, double radius)
{
Position = position;
Radius = radius;
}
public void Draw()
{
// Determines how round the circle will appear.
int vertexAmount = 10;
double twoPI = 2.0 * Math.PI;
// A line loop connects all the vertices with lines
// The last vertex is connected to the first vertex
// to make a loop.
Gl.glBegin(Gl.GL_LINE_LOOP);
{
for (int i = 0; i <= vertexAmount; i++)
{
double xPos = Position.X + Radius * Math.Cos(i * twoPI /
vertexAmount);
double yPos = Position.Y + Radius * Math.Sin(i * twoPI /
vertexAmount);
Gl.glVertex2d(xPos, yPos);
}
}
Gl.glEnd();
}
}
默認(rèn)情況下,在原點(diǎn)位置定義一個圓,其半徑為1個單位?,F(xiàn)在還沒有編寫繪制圓的代碼。繪制圓時,將使用OpenGL的立即模式,即只繪制圓的輪廓。正弦和余弦函數(shù)用于確定在什么位置繪制組成圓周的各個頂點(diǎn)。
為了在CircleIntersectionState內(nèi)測試?yán)L圖函數(shù),應(yīng)在類中添加一個成員_circle。
Circle _circle = new Circle(Vector.Zero, 200);
現(xiàn)在以原點(diǎn)為圓心、創(chuàng)建一個半徑為200的圓。為了看到圓,需要修改渲染方法。
public void Render()
{
_circle.Draw();
}