Есть ли в XNA полигон, например, прямоугольник? - PullRequest
8 голосов
/ 04 марта 2010

Я делаю игру, в которой есть только определенное пространство, в котором игрок может передвигаться. Я хочу представить это пространство каким-то многоугольником. Главный вопрос, который я хотел бы задать, состоит в том, содержит ли он данный момент. (Вроде rect.intersect())

Есть ли у XNA способ сделать это?

Ответы [ 2 ]

8 голосов
/ 04 марта 2010

Нет. (Не до и включая версию 3 как минимум)

XNA имеет ограничивающие объемы, такие как усеченные или блоки , но не имеет понятия о многоугольниках.

Простой, быстрый и эффективный способ выполнения точки в многоугольнике с помощью 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;
}

Класс многоугольника может очень просто хранить коллекцию векторов, но я ввел класс линий, так как линии требовались в другом месте.

1 голос
/ 18 сентября 2012

Изменен цикл 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;
                        }
                    }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...