Трансформация точки по трансформации блока

Автор Тема: Трансформация точки по трансформации блока  (Прочитано 15190 раз)

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

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

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Всем привет. Конечно в меня полетят тухлые помидоры от Ривилиса, но придется потерпеть  ;D
Касаемо матриц трансформации у меня дикое непонимание темы ((
В этой теме я выкладывал тестовый проект. Вот с ним же и продолжим разбираться (я его приложил к этой теме). В этом проекте для блока задаются две ручки. Первая равна точке вставки блока, а вторая создает геометрию.
Для контроля положения второй точки я использовал расширенные данные, которые хранят вектор между второй точкой и первой. Т.е. при получении ручек берется точка вставки блока и к ней прибавляется этот вектор - получаем вторую точку. В той теме есть видео примеры в которых видно, что это работает. Но это работает до тех пор, пока я не трансформирую сам блок - поверну, масштабирую или отзеркалю (перемещение не играет роли в данном случае) - тогда вторая точка не соответствует требуемому положению.
При получении расширенных данных из блока работает следующий метод:
Код - C# [Выбрать]
  1. public void GetParametersFromResBuf(ResultBuffer resBuf)
  2. {
  3.     TypedValue[] resBufArr = resBuf.AsArray();
  4.     foreach (TypedValue typedValue in resBufArr)
  5.     {
  6.         switch ((DxfCode)typedValue.TypeCode)
  7.         {
  8.             case DxfCode.ExtendedDataAsciiString:
  9.                 {
  10.                     Vector3d vectorFromEndToStart = SimplyEntityHelper.ConvertStringToVector3d(typedValue.Value.ToString());
  11.                     var pt = StartPoint + vectorFromEndToStart;
  12.                     EndPoint = pt;
  13.                     break;
  14.                 }
  15.         }
  16.     }
  17. }
Это как раз получение второй точки по вектору. Как я предполагаю - эту точку нужно еще трансформировать в зависимости от трансформации блока. У меня получалось учесть масштаб и поворот, используя свойства ScaleX и Rotation из блока. Но я застрял с отзеркаливанием. Поэтому я предположил, что можно взять значение BlockTransform из вхождения блока и трансформировать точку:
Код - C# [Выбрать]
  1. EndPoint = pt.TransformBy(BlockTransform);
Но мои предположения оказались неверными.
Прошу помощи с идеями и подсказками  ::)


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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Возможно, имеет смысл хранить координаты точки во внутренней системе координат блока? Тогда BlockTransform поможет.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробуй:
Код - C# [Выбрать]
  1. EndPoint = pt.TransformBy(BlockTransform.Inverse());
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Насколько я понимаю, это переводит координаты точки из МСК в ОСК блока. Мне думается, что тут надо как-то грамотно использовать оба преобразования: из МСК в ОСК и обратно. Одно - до изменения точки, другое - после. Только что-то не сообразить каким способом. Надо тестировать.

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
А почему
Цитировать
DxfCode.ExtendedDataAsciiString
?

http://help.autodesk.com/view/ACD/2016/RUS/?guid=GUID-A2A628B0-3699-4740-A215-C560E7242F63

Чем код 1012 не устроил-то?

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Попробуй:
Код - C# [Выбрать]
  1. EndPoint = pt.TransformBy(BlockTransform.Inverse());
Нет, не помогает

Возможно, имеет смысл хранить координаты точки во внутренней системе координат блока?
А вот это идея. Только координаты точки я не храню вообще - я храню вектор от второй точки к первой. Значит перед тем как трансформировать точку с помощью BlockTransform, нужно произвести трансформацию координат. Или после... Запутался)) Да, нужно тестировать

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А почему
Цитировать
DxfCode.ExtendedDataAsciiString
?

http://help.autodesk.com/view/ACD/2016/RUS/?guid=GUID-A2A628B0-3699-4740-A215-C560E7242F63

Чем код 1012 не устроил-то?
Вот в этой теме написано чем ) Эти коды не меняются при изменении блока через палитру свойств

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Мне думается, что тут надо как-то грамотно использовать оба преобразования: из МСК в ОСК и обратно.
Думаю, что ты прав. Сначала МСК->ОСК, затем добавляем вектор, а затем ОСК->МСК.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
Цитировать
Вот в этой теме написано чем )

1011 и 1012 ... Разницу чувствуешь?
Цитировать
Для контроля положения второй точки я использовал расширенные данные, которые хранят вектор между второй точкой и первой.

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Цитировать
Вот в этой теме написано чем )

1011 и 1012 ... Разницу чувствуешь?
Можно попробовать. По коду 1012 я буду получать вектор, указывающий направление второй точки. Но вопрос в том-же - точка по коду 1012 будет меняться с объектом при изменении из палитры свойств? Если 1011 не меняется. то я на 80% уверен, что и 1012 не будет

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Не зря же значения динпараметров хранятся во внутренней системе измерений блока.
Тут получается так: если хранить точку (вектор) в МСК, то ее нужно пересчитывать перезаписывать и в случае редактирования "ручкой" и в случае изменения блока (поворот, масштаб, зеркало). А если хранить в ОСК - то только при изменении "ручкой".

Оффлайн bender

  • ADN Club
  • **
  • Сообщений: 62
  • Карма: 4
Цитировать
Но вопрос в том-же - точка по коду 1012 будет меняться с объектом при изменении из палитры свойств?

А зачем ей меняться?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Если 1011 не меняется. то я на 80% уверен, что и 1012 не будет
Я уверен в этом на 99%
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Не зря же значения динпараметров хранятся во внутренней системе измерений блока.
Тут получается так: если хранить точку (вектор) в МСК, то ее нужно пересчитывать перезаписывать и в случае редактирования "ручкой" и в случае изменения блока (поворот, масштаб, зеркало). А если хранить в ОСК - то только при изменении "ручкой".
Думаю, достаточно будет только трансформаций в методе GetParametersFromResBuf(), который я отобразил в вопросе темы. Как я понимаю, в BlockTransform хранится информация относительно координат блока, а не относительно WCS. Сейчас попробую идейку...
Цитировать
Но вопрос в том-же - точка по коду 1012 будет меняться с объектом при изменении из палитры свойств?

А зачем ей меняться?
А затем, что когда я через палитру свойств задам блоку масштаб, то точка с кодом 1012 останется в своем старом состоянии. Она не изменится, хотя должна будет

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Вроде вот так получается:
Код - C# [Выбрать]
  1. Vector3d vectorFromEndToStart = SimplyEntityHelper.ConvertStringToVector3d(typedValue.Value.ToString());
  2. var pt = StartPoint.TransformBy(BlockTransform.Inverse()) + vectorFromEndToStart;
  3. EndPoint = pt.TransformBy(BlockTransform);
Но еще тестировать нужно
Правда возникают новые проблемы (касаемо самой графики в блоке после отзеркаливания), но это уже вопрос другой темы