【问题标题】:Does XNA have a Polygon, like Rectangle?XNA 是否有多边形,例如矩形?
【发布时间】:2011-01-23 16:51:20
【问题描述】:

我正在制作一款游戏,玩家只能在一定的空间内移动。我想用某种多边形来表示这个空间。我要问的主要问题是它是否包含给定的点。 (喜欢rect.intersect()

XNA 有没有办法做到这一点?

【问题讨论】:

    标签: c# xna polygon


    【解决方案1】:

    没有。 (未升级,至少包括第 3 版)

    XNA 有诸如 frustumsboxes 之类的边界体,但它没有多边形的概念。

    可以在here 找到使用 XNA 在多边形中执行点的简单、快速和有效的方法。我最近实现了这一点,效果非常好。

    您知道对象的点,您需要做的就是围绕该对象创建一个多边形 - 使用矢量将是最好和最简单的方法。然后执行多边形检查中的点。

    这是我实现的示例代码。使用 XNA 中的默认点类。 Polygon 是一个简单的类,其中包含构成多边形的向量集合。

    /// <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;
    }
    

    多边形类可以很容易地只存储向量的集合,但我引入了一个线类,因为其他地方需要线。

    【讨论】:

    • 此代码基于那篇文章,但它使用 C#。加上它已经被大量修改。我应该补充一点,以理解这段代码。带有光线投射的 Google “多边形中的点”。这将更多地解释该理论。维基百科对此也有一篇不错的文章。
    • 我可以看看你的多边形类的代码吗?似乎很难相信 XNA 缺少这一点。
    • 过去几周我花了很长时间在多边形函数中写下我自己的观点。测试最好的方法等等。光线投射方法似乎不仅是最好的,而且是最好实现的。至于 XNA 缺少这个功能,是的,这似乎有点难以置信,但大多数框架在多边形检测方面都没有任何类型的点。
    • 上述方法不适用于所有形状 - 查看源链接,我已将其修改为以下内容,这似乎在我的测试中有效。必须在答案中发布代码,因为在评论中不会那么多。
    • @AskeB。是的 - 这是前一阵子出现的。由于某种原因,内容不可访问或已被移动。如果有人知道在哪里/为什么请更新。
    【解决方案2】:

    将 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;
                            }
                        }
            }
    

    【讨论】:

      猜你喜欢
      • 2011-05-03
      • 2011-06-17
      • 2013-02-24
      • 2014-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 1970-01-01
      相关资源
      最近更新 更多