Member 11841791 Ответов: 2

C# - объединить уже соседние прямоугольники в список точек многоугольника по часовой стрелке?


Привет, Codeproject!

Я сделал рекурсивную функцию flood fill, чтобы найти все плитки в массиве, которые находятся рядом друг с другом. Я хотел бы использовать этот список плиток, чтобы сделать многоугольник, используя их прямоугольную информацию - многоугольник должен быть в конечном итоге в порядке по часовой стрелке, однако каждый раз, когда я пытаюсь это сделать, я сталкиваюсь с ошибкой, которую, кажется, не понимаю.

Все мои попытки были безуспешны, и это действительно беспокоит меня. Никаких исключений не возникает, однако все полигоны оказываются недействительными из-за того, что точки находятся либо в неправильном порядке, либо в совершенно неправильном положении.

Плитки не сортируются по X или Y. Я что-то упустил?

Что я уже пробовал:

То, что я пытался сделать, это пробежаться по списку вот так:

for (int i =0; i<TileList.Count; i++) {


    PointList.AddRange(new Vector2[] {
            new Vector2(TileList[i].BoundingBox.X, TileList[i].BoundingBox.Y),
            new Vector2(TileList[i].BoundingBox.X + TileList[i].BoundingBox.Width, TileList[i].BoundingBox.Y),
            new Vector2(TileList[i].BoundingBox.X + TileList[i].BoundingBox.Width, TileList[i].BoundingBox.Y + TileList[i].BoundingBox.Height),
            new Vector2(TileList[i].BoundingBox.X, TileList[i].BoundingBox.Y + TileList[i].BoundingBox.Height),
    });


}


for(int i =0; i<PointList.Count; i++)
{
    for (int j = 0; j < PointList.Count; j++)
    {
        if(PointList[i] != PointList[j])
        {
            if (Vector2.Distance(PointList[i], PointList[j]) < 2)
            {
                PointList.Remove(PointList[i]);
                PointList.Remove(PointList[j]);
            }
        }
    }

}

PointList = PointList.OrderBy(p => Math.Atan2(p.X, p.Y)).ToList();

2 Ответов

Рейтинг:
1

#realJSOP

Что вам нужно сделать, так это получить список точек рассматриваемых прямоугольников и определить их угол от центральной опорной точки. Как только вы это сделаете, вы можете отсортировать углы от самого низкого до самого высокого значения и обработать каждый из них в этом порядке (по существу, по часовой стрелке).

Я оставлю это вашим значительным навыкам google, чтобы узнать, как рассчитать углы.


Member 11841791

А, теперь я понимаю, что ты имеешь в виду. Я этим занимаюсь.

Member 11841791

Это дает мне точно такую же проблему, как просто сортировка точек с помощью Math.Atan.

Рейтинг:
1

Patrice T

Вам нужно провести анализ вашей проблемы.
Около примыкающий, Я понимаю, что 2 прямоугольника имеют общую сторону.
Надо брать очки:

r
A  B  C
D  E  F

это дает прямоугольники ABED и BCFE.

Чтобы проверить, являются ли 2 прямоугольника смежными или нет, вам нужно найти общие 2 точки между обоими прямоугольниками.
Затем, как только вы узнаете, что они разделяют точки, вы должны объединить их и получить ACFD.
Вам нужно разработать метод, гарантирующий, что после слияния все точки останутся по часовой стрелке.

PointList.Remove(PointList[i]);
PointList.Remove(PointList[j]);

remove есть побочный эффект перемещения следующих элементов вниз. Чтобы понять, как код идет не так, используйте отладчик и обратите внимание на изменения в списке.

Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволяет вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения, это невероятный инструмент обучения.

Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.