2010-03-04 40 views
8

我正在製作一個遊戲,玩家只能在其中移動一定的空間。我想用某種多邊形表示這個空間。我要問的主要問題是它是否包含一個給定的觀點。 (Like rect.intersect()XNA是否有像矩形一樣的多邊形?

XNA有任何方法可以做到這一點嗎?

回答

8

號(不向上和含有至少3個版本)

XNA已包圍體作爲這樣平截頭體但它沒有多邊形的概念。

一個簡單,快速,有效的用XNA執行多邊形點的方法可以在here找到。我最近實現了這一點,它非常出色。

你知道你的對象的重點,你需要做的就是圍繞這個對象創建一個多邊形 - 使用向量將是最好和最簡單的方法。然後在多邊形檢查中執行該點。

這裏是我的實現代碼示例。使用XNA中的默認點類。多邊形是一個簡單的類,其中包含構成多邊形的矢量集合。

/// <summary> 
/// Point in polygon check. 
/// </summary> 
/// <param name="point">The point.</param> 
/// <param name="polygon">The polygon.</param> 
/// <returns>True if point is inside, false otherwise.</returns> 
/// <see cref="http://local.wasp.uwa.edu.au/~pbourke/geometry/insidepoly/"/> 
public bool PointInPolygon(Point point, Polygon polygon) { 

     bool inside = false; 

     foreach (var side in polygon.Lines) { 
      if (point.Y > Math.Min(side.Start.Y, side.End.Y)) 
       if (point.Y <= Math.Max(side.Start.Y, side.End.Y)) 
        if (point.X <= Math.Max(side.Start.X, side.End.X)) { 
         float xIntersection = side.Start.X + ((point.Y - side.Start.Y)/(side.End.Y - side.Start.Y)) * (side.End.X - side.Start.X); 
         if (point.X <= xIntersection) 
          inside = !inside; 

     } 

     return inside; 
} 

的Polgyon類是非常基本的,在半模擬性:

class Polygon 
{ 
    public List<Line> Lines { get; set; } 
} 

public class Line 
{ 
    public Vector2 Start; 
    public Vector2 End; 
} 

Polygon類可以很容易地只儲存向量的集合,但我推出了一系列類作爲線在其他地方需要。

+0

該代碼是基於製品,除了使用C#。另外它已經被大量修改。我應該補充一下,理解這段代碼。 Google *「點多邊形」*與光線投射。這將更多地解釋這個理論。維基百科也有一篇很好的文章。 – Finglas

+0

我可以看到您的多邊形類的代碼嗎? XNA似乎很難相信這一點。 –

+0

在過去的幾周裏,我花了很長時間在多邊形函數中寫下自己的觀點。測試最佳方法等等。光線投射法似乎不僅是最好的,而且是最好的實施。至於缺乏這種功能的XNA,是的,這似乎有點難以置信,但大多數框架在多邊形檢測中缺乏任何點。 – Finglas

1

改性foreach循環以下,以處理所有的多邊形形狀:

 foreach (var side in Lines) { 
      if (point.Y > Math.Min(side.Start.Y, side.End.Y)) 
       if (point.Y <= Math.Max(side.Start.Y, side.End.Y)) 
        if (point.X <= Math.Max(side.Start.X, side.End.X)) { 
         if (side.Start.Y != side.End.Y) { 
          float xIntersection = (point.Y - side.Start.Y) * (side.End.X - side.Start.X)/(side.End.Y - side.Start.Y) + side.Start.X; 
          if (side.Start.X == side.End.X || point.X <= xIntersection) 
           result = !result; 
         } 
        } 
     }