Повернуть примитив по касательной к дуге

Автор Тема: Повернуть примитив по касательной к дуге  (Прочитано 7167 раз)

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

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

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

На картинке я нарисовал две касательных (благо в автокаде есть такая привязка) и примитив, повернутый по касательной.
Вопросы:
1. Как программно получить угол поворота?
Из математики: Угол между касательной и хордой, проведенной в точку касания, равен половине дуги, стягиваемой этой хордой. По идее - полный угол дуги, деленный на 2 - и есть нужный угол. На практике - не сработало
2. Как получить точку пересечения касательных?
Уверен, что есть достаточно несложные решения, но уровень моих знаний не достаточен...)))

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Добавлю еще вот что:
на сайте dwg.ru есть набор программок для работы с полилиниями. Они написаны на лиспе. Вот как работает одна из них:


Извините, вам запрещён просмотр содержимого спойлеров.

Вроде как раз то, что мне нужно (только в обратном порядке), но лисп я уже давно забыл

Отмечено как Решение Александр Пекшев aka Modis 23-11-2015, 17:36:48

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Мне нужно в вершины дуги (начальная и конечная точка дуги) расположить примитив и повернуть его по касательной к дуге
Код - C# [Выбрать]
  1. Curve.GetFirstDerivative
Это?
Ну а угол поворота получаешь при помощи:
Код - C# [Выбрать]
  1. Vector3d.GetAngleTo
« Последнее редактирование: 23-11-2015, 14:03:26 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Александр Ривилис, ну в целом - да. Вот только есть момент с которым я никак не могу разобраться. Сейчас попробую описать:
Возьмем полилинию из картинки в топике. Имеем 4 вершины. Первую и последнюю не учитываем. Делаем итерацию по вершинам (i = номер вершины, начиная с нуля).
Есть условие - я могу поворачивать примитив по сегменту перед вершиной и по сегменту после вершины.
Работаю с тремя точками:
Код - C# [Выбрать]
  1. var ptCurrent = pline.GetPoint3dAt(i);
  2. var ptBefore = pline.GetPoint3dAt(i - 1);
  3. var ptAfter = pline.GetPoint3dAt(i + 1);

1 Вариант: сегмент после вершины
- вершина в i=1. Сегмент после вершины - дуга. Получаю угол так:
Код - C# [Выбрать]
  1. var fd = pline.GetFirstDerivative(pline.GetPoint3dAt(i));
  2. var angle = fd.AngleOnPlane(pline.GetPlane());
- вершина в i=2. Сегмент после вершины - линейный. Получаю угол так:
Код - C# [Выбрать]
  1. angle = (ptAfter - ptCurrent).AngleOnPlane(pline.GetPlane());

2 Вариант: сегмент до вершины
- вершина в i=1. Сегмент до вершины - прямая. Получаю угол так:
Код - C# [Выбрать]
  1. angle = (ptCurrent - ptBefore).AngleOnPlane(pline.GetPlane());
- вершина в i=2. Сегмент до вершины - дуга. Не знаю как получить угол!

Поворот примитива в текущей точке
Код - C# [Выбрать]
  1. var matrix = Matrix3d.Rotation(angle.Value,
  2.     ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis, ptCurrent);
  3. ent?.TransformBy(matrix);

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть условие - я могу поворачивать примитив по сегменту перед вершиной и по сегменту после вершины.
Вычисляй не GetFirstDerivative(Point3d), а GetFirstDerivative(double param). И подбирай param рядом с конечными точками дуги, но внутри дуги, т.е. не 1.0 и 2.0, а (например) 1.0001 и 1.9999
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Все оказалось немного проще) При варианте Сегмент до вершины я пытался получить угол так:
Код - C# [Выбрать]
  1. var fd = pline.GetFirstDerivative(pline.GetPoint3dAt(i - 1));
  2. angle = fd.AngleOnPlane(pline.GetPlane());
В чем и была моя промашка - простая невнимательность. Производную-то нужно было получать не в предыдущей вершине, а именно в текущей, к которой у меня "подходит" дуговой сегмент. Т.е. нужно было так:
Код - C# [Выбрать]
  1. var fd = pline.GetFirstDerivative(pline.GetPoint3dAt(i));
  2. angle = fd.AngleOnPlane(pline.GetPlane());
Вот насчет точности - не уверен. Строил вручную - получил угол 336 градусов. Построил программно - 335 градусов. Думаю, это мелочи
Александр Ривилис, спасибо вам за активность. Иногда просто нужно о проблеме с кем-нибудь поговорить и сам находишь ответ :D

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

  • Administrator
  • *****
  • Сообщений: 13877
  • Карма: 1785
  • Рыцарь ObjectARX
  • Skype: rivilis
В случае примыкания дугового сегмента к линейному (если дуговой строили по трём точкам), в месте общей вершины касательная неопределена. Поэтому лучше делать так, как я сказал. Аналогично с двумя дуговыми и двумя линейными.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
В случае примыкания дугового сегмента к линейному (если дуговой строили по трём точкам), в месте общей вершины касательная неопределена. Поэтому лучше делать так, как я сказал
Обязательно учту)
Еще нужно разобраться в некоторых вещах - почему, например, в некоторых точках поворачивает неправильно? Пока даже зависимости найти не могу ((
Update:
Зависимость нашел - выпуклая или вогнутая кривая. Осталось разобраться что делать с углом
Update2:
Вопрос снят - опять моя невнимательность была =)
« Последнее редактирование: 23-11-2015, 15:20:16 от Александр Пекшев aka Modis »