Спільнота програмістів autodesk в співдружність незалежних держав
Як визначити, чи знаходиться точка всередині зони
В Revit існують три типи просторових об'єктів:
В Revit API ці об'єкти представлені класами Room. Area і Space відповідно, які успадковуються від базового класу SpatialElement.
Класи Room і Space мають методи для визначення, чи знаходиться задана точка всередині приміщення або простору. IsPointInRoom і IsPointInSpace.
Мені ж знадобилося визначити, чи знаходиться задана точка всередині зони. А методу IsPointInArea, на жаль, не виявилося. Довелося реалізовувати самостійно.
Насамперед потрібно було знайти алгоритм, за яким можна визначити, чи знаходиться точка в заданому просторі. На щастя, завдання досить поширена, а значить готові алгоритми вже є.
Суть методу досить проста. Від заданої точки проводиться уявні промінь в будь-якому напрямку. Потім, підраховується кількість перетинів променя, з межами полігону. Якщо промінь перетинає полігон парна кількість разів, значить точка знаходиться за межами кордонів полігону. В іншому випадку, точка знаходиться всередині полігону.
Для реалізації даного алгоритму в Revit потрібно виконати наступні кроки
- Отримати список кордонів просторового елемента. SpatialElement .GetBoundarySegments (). Кордонів може бути кілька, наприклад, якщо посеред приміщення є колона або отвір.
- Побудувати промінь від заданої точки. Для простоти, побудуємо промінь паралельно осі X.
- Для кожної кордону отримати список сегментів, що визначають кордон.
- Перевірити, перетинається промінь з даним сегментом.
- Порахувати кількість перетинів
Насправді, даний алгоритм підходить для всіх просторових елементів Revit, тому не будемо обмежуватися лише зоною, а реалізуємо цей алгоритм для базового класу SpatialElement.
Я часто застосовую методи-розширення. Створимо його і в цей раз. Повний код методу для визначення знаходження точки всередині простору:
public static class SpatialElementExternsion
public static bool IsPointInsideSpatialElement # 40; this SpatialElement spatialElement, XYZ point # 41;
// визначимо місце розташування просторового елемента
var location = spatialElement. Location as LocationPoint;
if # 40; location == null # 41;
// Якщо точка лежить нижче рівня просторового елемента, то повертаємо False;
if # 40; point. Z // беремо межі об'єкта var boudnaries = spatialElement. GetBoundarySegments # 40; new SpatialElementBoundaryOptions # 40; # 41; # 41; ; Line line = Line. CreateBound # 40; point, new XYZ # 40; 10000. 0. 0 # 41; # 41; ; // змінна для підрахунку кількості перетинів int intersectionCount = 0;