2010-03-04 26 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; 
         } 
        } 
     }