Вычислить точку пересечения перпендикуляра и трассы

Автор Тема: Вычислить точку пересечения перпендикуляра и трассы  (Прочитано 2049 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Павел55Автор темы

  • ADN OPEN
  • **
  • Сообщений: 75
  • Карма: 3
Допустим есть произвольная точка P на небольшом удалении от трассы, необходимо получить точку пересечения перпендикуляра проведенного из точки P к трассе. Стандартных методов не нашел, есть у кого идеи как это сделать? Трасса большая(автодороги до 10 км), состоит не только из дуг и отрезков, но есть еще и эллиптические дуги(переходные кривые).

Онлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 11762
  • Карма: 1540
  • Рыцарь ObjectARX
  • Skype: rivilis
Не проверял, но возможно такое решение сработает:
1. Используя Alignment.GetPolyline получаем полилинию, образующую трассу.
2. Используя метод Curve.GetClosestPointTo находим ближайшую точку на полилинии - это и будет нормаль. Если конечно точка не за пределами начала и конца трассы - в  этом случае это будет одна из конечных точек.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Павел55Автор темы

  • ADN OPEN
  • **
  • Сообщений: 75
  • Карма: 3
Спасибо, буду пробовать! Я уж было чуть не взялся вычислительную геометрию и алгоритмы штудировать.

Отмечено как Решение Павел55 31-07-2019, 20:40:25

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2311
  • Карма: 641
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Используя Alignment.GetPolyline получаем полилинию, образующую трассу.
При этой операции создаётся новый объект, так что, не забудьте потом его уничтожить.
Используя метод Curve.GetClosestPointTo находим ближайшую точку на полилинии
Насколько я помню, этот метод можно применять сразу к трассе, не извлекая полилинию.

Если же решать задачу чисто средствами Civil 3D API, то следует использовать методы: Alignment.StationOffset для получения пикетажа ближайшей точки на трассе и Alignment.PointLocation для получения координат этой точки.



Онлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 11762
  • Карма: 1540
  • Рыцарь ObjectARX
  • Skype: rivilis
Насколько я помню, этот метод можно применять сразу к трассе, не извлекая полилинию.

Точно. Я зевнул, что Alignment - наследник Curve:


Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2311
  • Карма: 641
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Вы знаете, с Сивилом такая интересная ситуация - у него почти все графические объекты являются наследниками Curve. Но очень часто базовые методы Curve для них либо не реализованы, либо результат их работы совершенно не тот, который ожидается.
В случае с трассой есть все основания полагать, что они сработают как надо, т.к. трасса по своей геометрии как раз и является Curve. По крайней мере, IntersectWith я часто использую и с ним нет проблем.  Я не использую методы из AutoCAD API если есть возможность то же самое сделать с помощью Civil 3D API. Поэтому, GetClosestPointTo к трассе не применяю. И не уверен на 100% что он будет работать с трассой корректно, надо проверять.

Онлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 11762
  • Карма: 1540
  • Рыцарь ObjectARX
  • Skype: rivilis
Поэтому, GetClosestPointTo к трассе не применяю. И не уверен на 100% что он будет работать с трассой корректно, надо проверять.
Если не сработает, то нужно попробовать мой начальный вариант.
Павел55, хочу уточнить, что предложенный мной вариант не всегда возвращает точку на перпендикуляре - он возвращает ближайшую точку к трассе. В зависимости от того какая это трасса и как расположена точка, это может быть перпендикуляр, одна из конечных точек или просто ближайшая. Например в такой ситуации:



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2311
  • Карма: 641
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
Если исходить из условий:
Трасса большая(автодороги до 10 км)
То такой ситуации не будет. Дорога так никогда не повернёт. Там будут дуги и плавные переходные спирали. Кстати, интересно взглянуть - какая получится полилиния из трассы со спиралями? У полилинии спиралей-то нет... Наверное, там будет аппроксимация из кучи мелких отрезков.

Оффлайн Павел55Автор темы

  • ADN OPEN
  • **
  • Сообщений: 75
  • Карма: 3
Сработал метод Curve.GetClosestPointTo, пока что на дорогах не тестировал, но на пробном примере работает как надо.

Онлайн alsh

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Если же решать задачу чисто средствами Civil 3D API, то следует использовать методы: Alignment.StationOffset для получения пикетажа ближайшей точки на трассе и Alignment.PointLocation для получения координат этой точки.
А как получить отметку(elevation) этой точки на трассе? PointLocation дает только координаты без Z.
Спасибо

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2311
  • Карма: 641
  • LISP/C#, AutoCAD/Civil 3D
  • Skype: zagor_dmtr
У трассы нет отметки. Это линия, которая всегда находится на отметке 0. Отметки есть у профилей, которые могут быть построены по трассе. Поэтому, алгоритм такой:
1. Получаем профили трассы: http://docs.autodesk.com/CIV3D/2019/ENU/API_Reference_Guide/html/13710c82-f2b8-44f6-3574-f73f918fc39e.htm
2. Находим в этой коллекции нужный профиль.
3. Определяем отметку по пикету: http://docs.autodesk.com/CIV3D/2019/ENU/API_Reference_Guide/html/55d4560c-0867-5e73-4d88-04fbac2d2b35.htm

Онлайн alsh

  • ADN OPEN
  • Сообщений: 32
  • Карма: 0
Дмитрий, большое спасибо !