Quantcast
Channel: Форум программистов и сисадминов Киберфорум
Viewing all articles
Browse latest Browse all 514750

Поиск частей внешнего контура по четырём сторонам с "захватом" - Алгоритмы

$
0
0
Вот так вот чудно я назвал тему =)
Всем привет. В рамках проекта нужно придумать алгоритм поиска внешних стен с заходом на соседнюю сторону. Да, звучит совсем непонятно, поэтому давайте с картинками:
Имею первоначальный набор отрезков, которые получаю из стен чертежного плана:
Вложение 863135
На цифры пока не обращайте внимания - ниже опишу.
Вот из этого набора отрезков мне нужно получить четыре "крайних" варианта:
Низ и Верх:
Вложение 863136
Лево и Право
Вложение 863137
Как видите - это все крайние отрезки по стороне + по одному отрезку с соседней стороны. "Заходящему" так сказать.
Условие:
1. Нельзя оперировать точками. Дело в том, что реально эти отрезки не соединяются в концах (это я так начертил). Но соединение я могу получить (см.ниже)
2. Внешний контур не обязательно замкнут
3. Все отрезки уже проверены на горизонтальность и вертикальность
3. У каждого отрезка есть уникальный id

Как я начал решать:
1. Создаю 4 списка, в которые буду помещать нужные отрезки (в реале - стены)
2. Делаю 4 цикла для поиска самых крайних отрезков. Соответственно, самый левый, самый правый, самый верхний и самый нижний. Добавляю их в результирующие списки, НЕ удаляя из исходного
3. Делаю еще 4 цикла и теперь уже ищу в исходном списке те отрезки, которые лежат на той-же ординате (x или y), что и уже добавленные в результирующие списки. Т.е. для приведенного примера эта будут два нижних горизонтальных отрезка в варианте Bottom (см.картинку)
4. И вот последний цикл, который у меня отрабатывает не совсем верно:
4.1. Создаю вспомогательный список идентификаторов "заходящих отрезков" (у меня у всех отрезков есть уникальный id). Начинаю цикл по исходному списку
4.2. Беру i-ый отрезок.
4.3. Проверяю, что этот отрезок принадлежит "стороне". Не обязательно одной - он может принадлежать сразу двум сторонам. Вот тут используется то, о чем я говорил в "условиях": я могу для отрезка (стены) получить элементы с которыми он соприкасается своими концами. Получив этот набор элементов, я проверяю, что среди них есть те, которые принадлежат моим результирующим спискам. Например, для текущего проверяемого отрезка в списке соприкасающихся элементов есть отрезки, которые у меня УЖЕ ДОБАВИЛИСЬ (это вот важно!) в "левую сторону". При этом в цикле я пропускаю отрезок, если его id находится в списке "заходящих отрезков" (это позволяет мне прекратить добавление отрезков в направлении после "захода на соседнюю сторону")
После четырех таких проверок я имею 4 булевы переменные, соответственно: hasInleft, hasInRight, hasInTop, hasInBottom (т.е. в какую сторону попал отрезок)
4.4. Проверяю, что отрезок относится к соседней стороне. Например, если он hasInleft, то я проверяю, лежит ли он на одной прямой с самым крайним отрезком из "верха" или "низа" (их я получил в п.2). Если да, то помещаю его id в список "заходящих отрезков".
Ну и, соответственно, добавляю этот отрезок в эту группу "сторону"

Теперь о проблемах, связанных с моей реализацией:
1. На картинке есть отрезок №1. Так вот он попадает тоже в "нижнюю группу", т.к. проходит условие из п.4.3 - т.е. он своими концами соприкасается и с другими отрезками из "нижней группы". А он мне там совсем даже не нужен
2. После того, как проходит мой цикл из п.4 некоторые отрезки не попадают куда нужно. Например, в примере на картинке, номера 2,3,4 не попадут в верхнюю группу, а номера 5,6,7 не попадут в правую. И это логично, так как при работе цикла из п.4 я могу взять отрезок (например, №5), который ЕЩЕ не соприкасается с отрезками из правой группы, но УЖЕ соприкасается с отрезками из верхней. Пока что этот вопрос у меня решен ужасным костылём - я цикл из п.4 произвожу 4 раза. Но это бредовая идея.

Прошу помощи опытных форумчан - может подскажете нормальное решение, а то я что-то в тупике

Изображения
Тип файла: png Screenshot_1.png (4.3 Кб)
Тип файла: png Screenshot_2.png (9.5 Кб)
Тип файла: png Screenshot_3.png (9.0 Кб)

Viewing all articles
Browse latest Browse all 514750

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>