Спільнота програмістів autodesk в співдружність незалежних держав

Як визначити, чи знаходиться точка всередині зони

В Revit існують три типи просторових об'єктів:

В Revit API ці об'єкти представлені класами Room. Area і Space відповідно, які успадковуються від базового класу SpatialElement.

Класи Room і Space мають методи для визначення, чи знаходиться задана точка всередині приміщення або простору. IsPointInRoom і IsPointInSpace.

Мені ж знадобилося визначити, чи знаходиться задана точка всередині зони. А методу IsPointInArea, на жаль, не виявилося. Довелося реалізовувати самостійно.

Насамперед потрібно було знайти алгоритм, за яким можна визначити, чи знаходиться точка в заданому просторі. На щастя, завдання досить поширена, а значить готові алгоритми вже є.

Суть методу досить проста. Від заданої точки проводиться уявні промінь в будь-якому напрямку. Потім, підраховується кількість перетинів променя, з межами полігону. Якщо промінь перетинає полігон парна кількість разів, значить точка знаходиться за межами кордонів полігону. В іншому випадку, точка знаходиться всередині полігону.

Спільнота програмістів autodesk в співдружність незалежних держав

Для реалізації даного алгоритму в Revit потрібно виконати наступні кроки

  1. Отримати список кордонів просторового елемента. SpatialElement .GetBoundarySegments (). Кордонів може бути кілька, наприклад, якщо посеред приміщення є колона або отвір.
  2. Побудувати промінь від заданої точки. Для простоти, побудуємо промінь паралельно осі X.
  3. Для кожної кордону отримати список сегментів, що визначають кордон.
  4. Перевірити, перетинається промінь з даним сегментом.
  5. Порахувати кількість перетинів

Насправді, даний алгоритм підходить для всіх просторових елементів 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;