Пересчитать координаты модели в координаты листа

Автор Тема: Пересчитать координаты модели в координаты листа  (Прочитано 7170 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Продолжение темы http://adn-cis.org/forum/index.php?topic=3237.0, но будет рассматриваться немного  другой вопрос, поэтому создал новую тему.
Надо:
Расставить текст в пространстве листа вдоль координатной сетки со значениями координат сетки (можно посмотреть чертеж с предыдущей темы, лист 1,2). Данный чертеж выполнен при помощи кода vba. Там алгоритм был сложный со многими вычислениями в модели и листе.
Вопрос:
Можно ли найти (вычислить) положение точки в пространстве листа имея координаты модели.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Здесь есть такой момент - точка в модели одна, а транслироваться она может на несколько листов, и даже на один и тот же лист несколько раз, если есть несколько видовых экранов, в которых видна эта точка. Так что, конкретизируйте: какие исходные данные и что вы хотите получить. Лучше с чертежом.

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 29-11-2015, 03:00:04

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Погуглив нашел несколько вариантов решения.
Самое простое решение с внешним dll (никогда не делал такое, надеюсь хоть правильно написал) и его методом acedTrans. В вышеприведенной ссылке от Александр Ривилис решение тоже основан на нем.
Надеюсь ссылки на внешние ресурсы не запрещены, если не так то я почищу ветку.
http://www.theswamp.org/index.php?topic=42503.msg476994#msg476994
Здесь даны несколько вариантов решения, и я решил пойти по созданию класса ViewportExtensionMethods (Reply#4). Перевел в vb.net, результаты:
Код - vb.net [Выбрать]
  1. ' ViewportExtensionMethods.cs  (c) 2007-2012  Tony Tanzillo
  2. ' Converted from C# to VB.NET
  3. Imports System
  4. Imports System.Collections.Generic
  5. Imports System.Linq
  6. Imports Autodesk.AutoCAD.Geometry
  7. Imports Autodesk.AutoCAD.DatabaseServices
  8.  
  9. Public Module ViewportExtensionMethods
  10.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  11.     Public Function GetModelToPaperTransform(vport As Viewport) As Matrix3d
  12.         If vport.PerspectiveOn Then
  13.             Throw New NotSupportedException("Perspective views not supported")
  14.         End If
  15.         Dim center As Point3d = New Point3d(vport.ViewCenter.X, vport.ViewCenter.Y, 0.0)
  16.         Return Matrix3d.Displacement(New Vector3d(vport.CenterPoint.X - center.X, vport.CenterPoint.Y - center.Y, 0.0)) *
  17.                Matrix3d.Scaling(vport.CustomScale, center) * Matrix3d.Rotation(vport.TwistAngle, Vector3d.ZAxis, Point3d.Origin) *
  18.                Matrix3d.WorldToPlane(New Plane(vport.ViewTarget, vport.ViewDirection))
  19.     End Function
  20.  
  21.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  22.     Public Function GetPaperToModelTransform(vport As Viewport) As Matrix3d
  23.         Return vport.GetModelToPaperTransform().Inverse()
  24.     End Function
  25.  
  26.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  27.     Public Function PaperToModel(point As Point3d, vport As Viewport) As Point3d
  28.         Return point.TransformBy(vport.GetModelToPaperTransform().Inverse())
  29.     End Function
  30.  
  31.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  32.     Public Function ModelToPaper(point As Point3d, viewport As Viewport) As Point3d
  33.         Return point.TransformBy(viewport.GetModelToPaperTransform())
  34.     End Function
  35.  
  36.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  37.     Public Sub PaperToModel(entity As Entity, vport As Viewport)
  38.         entity.TransformBy(vport.GetModelToPaperTransform().Inverse())
  39.     End Sub
  40.  
  41.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  42.     Public Sub ModelToPaper(entity As Entity, viewport As Viewport)
  43.         entity.TransformBy(viewport.GetModelToPaperTransform())
  44.     End Sub
  45.  
  46.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  47.     Public Function PaperToModel(source As IEnumerable(Of Point3d), viewport As Viewport) As IEnumerable(Of Point3d)
  48.         Dim xform As Matrix3d = viewport.GetModelToPaperTransform().Inverse()
  49.         Return source.[Select](Function(p As Point3d) p.TransformBy(xform))
  50.     End Function
  51.  
  52.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  53.     Public Function ModelToPaper(source As IEnumerable(Of Point3d), viewport As Viewport) As IEnumerable(Of Point3d)
  54.         Dim xform As Matrix3d = viewport.GetModelToPaperTransform()
  55.         Return source.[Select](Function(p As Point3d) p.TransformBy(xform))
  56.     End Function
  57.  
  58.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  59.     Public Sub PaperToModel(src As IEnumerable(Of Entity), viewport As Viewport)
  60.         Dim xform As Matrix3d = viewport.GetModelToPaperTransform().Inverse()
  61.         For Each ent As Entity In src
  62.             ent.TransformBy(xform)
  63.         Next
  64.     End Sub
  65.  
  66.     <System.Runtime.CompilerServices.ExtensionAttribute()>
  67.     Public Sub ModelToPaper(src As IEnumerable(Of Entity), viewport As Viewport)
  68.         Dim xform As Matrix3d = viewport.GetModelToPaperTransform()
  69.         For Each ent As Entity In src
  70.             ent.TransformBy(xform)
  71.         Next
  72.     End Sub
  73. End Module
Не стал переписывать которые IEnumerable, так как не знаю что это такое и для чего они. Проверил: и точки пересчитал и объекты перетрансформировал в PS правильно. В общем доволен.
PS. Так же, если есть замечания и предложения, с радостью выслушаю.
« Последнее редактирование: 29-11-2015, 02:01:20 от Александр Ривилис »

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
PS. Так же, если есть замечания и предложения, с радостью выслушаю.
А если спустя некоторое время тебе потребуется, к примеру, изменить масштаб видового экрана (предположим, что пользователь захотел изменить формат листа и под него оптимально изменить масштаб вида)? В этом случае ты получишь рассинхрон: изображение изменится, а весь текст, находящийся в пространстве листа, останется на прежнем месте. Если бы текст находился в модели, то такой проблемы бы не возникло.

Чем не устроил вариант размещения текста в модели на отдельном слое, который можно замораживать для тех видовых экранов, на которых этот текст видеть нет необходимости?

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
А если спустя некоторое время тебе потребуется, к примеру, изменить масштаб видового экрана (предположим, что пользователь захотел изменить формат листа и под него оптимально изменить масштаб вида)? В этом случае ты получишь рассинхрон: изображение изменится, а весь текст, находящийся в пространстве листа, останется на прежнем месте. Если бы текст находился в модели, то такой проблемы бы не возникло.

Чем не устроил вариант размещения текста в модели на отдельном слое, который можно замораживать для тех видовых экранов, на которых этот текст видеть нет необходимости?

Вся суть этих текстов с метками координат, чтобы они стояли по краям видового экрана и показывали значение координаты координатной сетки. Если пользователь решит изменить хоть как то видовой экран (масштаб, угол вращения, центр и т.д.), то метки расставленные в модели уже не будут по краям видового экрана. Поэтому рисовать в модели не выход, а эти тексты будут захламлять модель (они в модели вообще не нужны), что некрасиво при передаче заказчику ( некоторых объектах у нас бывает 50 и больше листов в зависимости от масштаба и размеров экстенда). В начале темы есть ссылка на предыдущую мою тему, там есть чертеж. Если посмотришь на листах 1 и 2 думаю поймешь о чем речь.
Ну а если пользователю все таки нужно изменить видовой экран, то ему всего то необходимо будет заново настроить блок в модели и запустить код.
Добавлено:
И еще, пока трансформация объектов с модели в лист и обратно в принципе не нужно, нужно было просто пересчитать точки, но в итоге получил универсальную вещь ::)

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Надеюсь ссылки на внешние ресурсы не запрещены, если не так то я почищу ветку.
Ссылки относящиеся непосредственно к теме (!!!) не запрещены и более того приветствуются.
Здесь даны несколько вариантов решения, и я решил пойти по созданию класса ViewportExtensionMethods (Reply#4). Перевел в vb.net, результаты:
Результаты я подправил по следующим причинам:
1) Нельзя убирать копирайт, когда он присутствует. Тем более, что Tony Tanzillo к этому плохо относится. А он очень уважаемая личность в среде программистов под AutoCAD.
2) Нельзя выкидывать куски кода даже если не понимаешь его назначения.
Не стал переписывать которые IEnumerable, так как не знаю что это такое и для чего они.
Они для того, чтобы в метод можно было передавать коллекцию точек и примитивов, что должно по идее улучшить производительность, т.к. матрица преобразования вычисляется однократно, а не для каждой точки/примитива. Вообще-то VB.NET действительно "недоязык". В очередной раз вылезла проблема с Extension Methods, разбираться с которой я не стал.

P.S.: Я тоже вспомнил с утра про этот алгоритм от Тони, но был занят и не было возможности оперативно дать ответ.
P.S.S.: Поставил тебе плюс за то, что ты самостоятельно нашёл лучшее из решений и поделился им. Так держать!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Нельзя убирать копирайт, когда он присутствует
Взято на заметку.
Нельзя выкидывать куски кода даже если не понимаешь его назначения
Тут две причины почему я выкинул. Первая, не знал как перевести в vb. Вторая, если бы как нибудь и перевел бы, то не знал бы как проверить на работу. Если бы код был в vb изначально, то скорее скопировал бы все (на всякий случай).
Они для того, чтобы в метод можно было передавать коллекцию точек и примитивов
Надо почитать и взять на вооружение, вещь полезная.
Спасибо за редактирование кода, он перекочует ко мне в проект. А для чего данная строка?
Код - vb.net [Выбрать]
  1. <System.Runtime.CompilerServices.ExtensionAttribute()>

Добавлено: После того как скопировал код, вроде понял почему, но все равно не откажусь услышать "научное" объяснение данной строке.

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

  • Administrator
  • *****
  • Сообщений: 13832
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Это так называемые методы расширения в .NET. Почитай: https://msdn.microsoft.com/en-us/library/bb384936.aspx
Преобразование точки из Модели в Лист будет выглядеть так
Код - vb.net [Выбрать]
  1. Dim ptModel As Point3d
  2. Dim ptPaper As Point3d
  3. Dim vp As Viewport
  4. ' где-то мы уже инициализировали ptModel и vp
  5. ptPaper = ptModel.ModelToPaper(vp)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 31
  • Карма: 1
Код - vb.net [Выбрать]
  1. ptPaper = ptModel.ModelToPaper(vp)
Круто. Я, до вашего поста добирался до метода через созданный класс. Проверил по вашему. Работает в обоих вариантах. Ваш вариант конечно намного удобнее.
ps. Теперь понял почему в коде C# стоял this, когда переводил в vb, гуглил про него, но ничего не понял.