Листая блог Джереми Таммика наткнулся на статью FilterRule Use and Retrieving Exterior Walls одной из тем которой была тема поиска наружных стен. Там приводится несколько вариантов решения. При этом есть важное условие – наружные стены обязательно должны образовывать замкнутый контур. И даже при этом предложенные варианты могут не дать нужного варианта.
В нескольких моих плагинах решалась похожая задача и был придуман алгоритм поиска наружных стен. Скорее всего и мой алгоритм не идеален, но при тестировании показал высокие результаты. В самой статье я не буду выкладывать частей кода – в конце статьи вы найдете ссылку на репозиторий GitHub.
Итак, мой алгоритм состоит из двух частей:
1. Основная часть.
Весь смысл основной части алгоритма заключается в поиске пересечений со стенами перпендикуляров, опущенных с середины стены в обе стороны – если с одной стороны есть пересечения со стенами, а с другой нет, то это наружная стена. Все просто. Несколько замечаний и условий:
- Если стена имеет дуговой контур, то направление стены нужно высчитать самому, так как значение свойства Orientation может указать совсем в ненужное нам место. Поэтому нужный вектор посчитаем, отняв от средней точки дуги среднюю точку между концами дуги. Или наоборот – это не важно
- Можно опускать только два перпендикуляра из одной стены – в большинстве случаев этого достаточно. Но в моем примере я делю направляющую линию стены на три части и из каждой части опускаю по два перпендикуляра. Это замедляет, но и улучшает точность. При работе плагина разница по времени даже не заметна.
- При поиске пересечений возможно следует учитывать и некоторые другие условия. Например, в своём коде я привожу проверяемые на пересечение кривые к одной координате Z. Подобные условия Вы должны предусматривать в своём коде исходя из своих потребностей
2. Дополнительная часть.
Дополнительная часть существует потому, что основная часть даст нам не все стены. Самый банальный и простой пример – это когда у нас в контуре наружных стен есть «вогнутость»:
В этом случае основная часть алгоритма будет считать боковые стены этой «вогнутости» внутренними, хотя для нас это неверное решение. Поэтому вторая часть заключается в поиске таких стен и добавлении их в результирующий список. А условие совпадения тут также достаточно просто – нужную нам стену будут с двух концов касаться две разных стены из списка наружных стен. Возможно в коде моего примера не самое лучшее решение, поэтому вы всегда можете предложить свои варианты.
Что-же – расписывать особо больше ничего не буду. Берите код, пробуйте, изучайте и тогда сами поймете все нюансы.
И напоследок несколько скриншотов:
1. Тестовый план этажа, приложенный в теме Таммика:
2. Результат работы моего алгоритма
3. Результат работы моего алгоритма над немного усложненным вариантом плана. Как видите – он не замкнут
Ну и конечно-же самое главное – проект на GitHub’е