Проекция CurveLoop на плоскость

Автор Тема: Проекция CurveLoop на плоскость  (Прочитано 2089 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Ищу способы решения. Мне кажется, что решатся должно просто (нужно только нужные методы найти), но пока не нахожу решения.
Задача - подсчитать площадь проёма. Решение я придумал и вполне "красивое" и точное (даже с учётом стороны стены), но в процессе тестов сам себе придумал проблему. А именно - полукруглая стена!
Имеется вот такой пример:



Стена хоть и полукруглая, но окно в ней все-равно плоское. После некоторых манипуляций я получаю CurveLoop по внешней стороне проема:



Тут красные - это Curve проема. Фиолетовая - это прямая, добавленная в коде, чтобы замкнуть контур. А вот зеленые - это Curve, которые дуговые ввиду того, что стена полукруглая. Так вот если я посмотрю на все это "Спереди" (т.е. со стороны окна), то "увижу" плоский замкнутый контур. Скажем так - проекцию:



Вот задача теперь в том, чтобы получить этот "плоский" контур, но программно. По сути мне нужно спроецировать мой контур на плоскость окна.

Есть идеи?

Отмечено как Решение Александр Пекшев aka Modis 20-02-2018, 11:10:42

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Проекция CurveLoop на плоскость
« Ответ #1 : 20-02-2018, 10:09:07 »
Что ж... Сам спросил - сам отвечу =)
В RevitAPI каких-либо методов проекции нет. Однако есть нужная тема у Таммика. Правда у него там ошибка в методе ProjectOnto - смотрите в комментариях.
Из его поста беру нужные мне методы:
Извините, вам запрещён просмотр содержимого спойлеров.

Теперь в коде плагина, получив нужные мне кривые, я их проецирую на плоскость. Для построения плоскости использую свойство семейства (окна или двери) FacingOrientation:
Код - C# [Выбрать]
  1. Plane plane = new Plane(familyInstance.FacingOrientation, new XYZ(0,0,0));
Методы у меня проецируют на плоскость точки. И если для отрезков это не вызовет проблем - там всего две точки (начало и конец), то для дуговых сегментов не подходит. На выручку приходит метод Curve.Tessellate(), который дуговые сегменты апроксимирует. Остается только соединить полученные точки в новые отрезки (и только отрезки). Это делается тоже легко:
Код - C# [Выбрать]
  1. List<Curve> projectedCurves = new List<Curve>();
  2. foreach (Curve curve in curves)
  3. {
  4.     XYZ previosPoint = null;
  5.     for (var i = 0; i < curve.Tessellate().Count; i++)
  6.     {
  7.         XYZ xyzProjected = plane.ProjectOnto(curve.Tessellate()[i]);
  8.         if (i == 0)
  9.             previosPoint = plane.ProjectOnto(xyzProjected);
  10.         else
  11.         {
  12.             projectedCurves.Add(Line.CreateBound(previosPoint, xyzProjected));
  13.             previosPoint = xyzProjected;
  14.         }
  15.     }
  16. }

В итоге получаю нужный мне контур окна, спроецированный на плоскость:




Для тех, у кого вдруг возник вопрос "Зачем это нужно?" - дело в том, что дальше я кривые собираю в CurveLoop и используя метод ExporterIFCUtils.ComputeAreaOfCurveLoops() считаю площадь. Однако, в ходе тестов, выяснилось, что метод возвращает 0.0, если CurveLoop не лежит в одной плоскости. В справке этого не написано, к сожалению, хотя это логичное поведение

Оффлайн Алексей Кузин

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: Проекция CurveLoop на плоскость
« Ответ #2 : 20-02-2018, 12:32:00 »
Цитировать
И если для отрезков это не вызовет проблем - там всего две точки (начало и конец), то для дуговых сегментов не подходит

В вашем примере видно что в результате проецирования дуги получается прямая. То есть плоскость дуги перпендикулярна плоскости проецирования. То достаточно проецировать концевые точки. Для Задачи подсчета площади проема я полагаю это будет всегда.

Оффлайн Александр Пекшев aka ModisАвтор темы

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Re: Проекция CurveLoop на плоскость
« Ответ #3 : 20-02-2018, 12:36:12 »
То достаточно проецировать концевые точки. Для Задачи подсчета площади проема я полагаю это будет всегда
Вы сейчас мне моего коллегу напомнили, который мне подобное сказал =) Отвечу Вам также, как и ему:
А если у меня круглое окно? Что тогда?
Мой вариант решения универсален и позволяет проецировать геометрию любой формы. А то, что из одной дуги (которая чисто в этом примере получилась перпендикулярно плоскости) получится 5-6 отрезков - вообще ни на что не повлияет )

Оффлайн Алексей Кузин

  • ADN OPEN
  • ***
  • Сообщений: 116
  • Карма: 8
Re: Проекция CurveLoop на плоскость
« Ответ #4 : 20-02-2018, 12:38:46 »
Да! Про круглые не подумал)