Как можно найти расстояние между 2 объектами?

Автор Тема: Как можно найти расстояние между 2 объектами?  (Прочитано 11694 раз)

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Как можно найти расстояние между 2 объектами?

У меня есть 2 объекта рандомной формы, как между ними можно найти кратчайшее расстояние??

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Как можно найти расстояние между 2 объектами?

У меня есть 2 объекта рандомной формы, как между ними можно найти кратчайшее расстояние??
Приветствую на форуме!
Общего решения для этой задачи нет. Нужна конкретика по поводу того что это за объекты, 2D или 3D они и т.д.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
2d объекты, могут быть любой формы.

Я думал в начале сделать, создать круг. Увеличивать его диаметр и проверять на пересечение объектов. Но это довольно таки ресурсо затратно. И я не знаю как проверять на пересечение объекты

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
2d объекты, могут быть любой формы.
Формы-то они могут быть любой. Но что это за объекты? Отрезки, полилинии, тексты, блоки...?
Я думал в начале сделать, создать круг. Увеличивать его диаметр и проверять на пересечение объектов.
Для начала, можно попробовать находить расстояния между габаритными контейнерами объектов - см. свойство GeometricExtents.

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Отрезки, полилинии, блоки.
Гляну свойство.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Всё-таки, как выше уже написал Александр Ривилис, нужно больше конкретики. Потому что для разных случаев варианты могут быть совершенно разными.

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Есть полилиния нужно найти кратчайшее расстояние до точки.

Вот так например.
А нельзя получить у каждого объекта массив точек, где проходит этот объект??

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Есть полилиния нужно найти кратчайшее расстояние до точки.

Вот так например.
Полилиния, как и любой другой наследник от Curve имеет метод GetClosesPointTo
А нельзя получить у каждого объекта массив точек, где проходит этот объект??
У линейного - можно. А у блока, например, что это за массив точек?

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
При создании линии мы задаем 3 координаты, а можно получить список координат где находится линия

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
А у блока, например, что это за массив точек?
Точки объектов внутри блока, преобразованные в единую систему координат, и для каждого объекта внутри блока, можно же так же найти GetClosesPointTо, перенеся эту точку внутрь блока..

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
При создании линии мы задаем 3 координаты, а можно получить список координат где находится линия
Это вопрос или утверждение? Если вопрос, то где знак вопроса? Если утверждение, то оно неверное.
3 координаты - это одна из вершин полилинии или начало-конец отрезка. Но этих точек очевидно недостаточно для определения минимального расстояния. Вероятно следует выполнить аппроксимацию с заданной точностью.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
При создании линии мы задаем 3 координаты
Как это? Высшая математика в ВУЗе была? :)

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
и для каждого объекта внутри блока, можно же так же найти GetClosesPointTо
Если это наследник от Curve. В общем случае - необязательно ;)

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А нельзя получить у каждого объекта массив точек, где проходит этот объект??
Это называется аппроксимация. Для линий/полилиний/отрезков и т.д. наследников Curve это возможно. Преобразуешь его в Curve3d и используешь метод Curve3d.GetNewSamplePoints
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Спасибо

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Подскажите, как из Enemy сделать Curve3d и  BlockReference, то каждый раз когда пытаюсь применить у Polyline пишет ошибку

Код - C# [Выбрать]
  1.                         // получаем текущую БД
  2.                         Database db = HostApplicationServices.WorkingDatabase;
  3.  
  4.                         // начинаем транзакцию
  5.                         using (Transaction tr = db.TransactionManager.StartTransaction())
  6.                         {
  7.                                 // получаем ссылку на пространство модели (ModelSpace)
  8.                                 BlockTableRecord ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForRead);
  9.  
  10.                                 string text = "";
  11.  
  12.                                 // "пробегаем" по всем объектам в пространстве модели
  13.                                 foreach (ObjectId id in ms)
  14.                                 {
  15.                                         // приводим каждый из них к типу Entity
  16.                                         Entity entity = (Entity)tr.GetObject(id, OpenMode.ForRead);
  17.                                         if ( entity.Layer.Equals("стены"))
  18.                                         {
  19.                                                 //BlockReference br = tr.GetObject(entity.ObjectId, OpenMode.ForRead) as BlockReference;
  20.                                                 //text += "br.Position.X=" + br.Position.X + " ;br.Position.Y=" + br.Position.Y + " 1\n\r";
  21.  
  22.                                                 acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage(string.Format("\nLayer:{0}; Type:{1}; Color: {2},{3},{4},x={5}y={6}\n",//br.Position.X, br.Position.Y
  23.                                                         entity.Layer, entity.GetType().ToString(), entity.Color.Red.ToString(), entity.Color.Green.ToString(), entity.Color.Blue.ToString(), "dsf", "453"));
  24.                                         }
  25.                                 }
  26.                                 text += "\n\r";
  27.  
  28.                                 MessageBox.Show(text);
  29.                                 tr.Commit();
« Последнее редактирование: 12-03-2019, 23:11:47 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
merta
1. Enemy - это враг. Думаю, что речь идёт об Entity.
2. Entity нельзя преобразовать в Curve3d. Можно преобразовать Curve в Curve3d при помощи метода Curve.GetGeCurve
3. Форматируйте нормально код, как написано у меня в подписи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Извините за ошибки, быстро писал не заметил этого.
Спасибо. А еще подскажите. У меня есть BlockReference и polyline. Между ними нужно найти расстояние. Polyline я могу привести к curve3d, с BlockReference  что делать?
Создать на его позиции объект и его привести к polyline?
или есть еще метод

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
У меня есть BlockReference и polyline. Между ними нужно найти расстояние.
Что подразумеваете под понятием "расстояние между блоком и полилинией"? Тут могут быть варианты - от точки вставки блока до линии, от крайнего ближайшего объекта блока до линии и пр.
Насколько точное должно быть расстояние?

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Расстояние между блоком и полилинией - от ближайшей точки блока к полилинии до этой точки на полилинии

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Как вариант - просто взорвать его.

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Взорвать конечно интересное предложение. Но после того как сделаю!

Когда у новой линии пытаюсь получить Curve3d Автокад вылетает:
Приложение не поддерживает оперативную (JIT)
отладку. Подробная информацию приводится в конце данного сообщения.

************** Текст исключения **************
Autodesk.AutoCAD.Runtime.Exception: eInvalidInput
   в Autodesk.AutoCAD.DatabaseServices.Curve.GetGeCurve(Tolerance tolerance)
   в Autodesk.AutoCAD.DatabaseServices.Curve.GetGeCurve()
   в ClassLibraryExample2.Class1.AddPoint(Double x1, Double y1, Double x2, Double y2) в C:\Users\User\source\repos\ClassLibraryExample2\ClassLibraryExample2\Class1.cs:строка 137
   в ClassLibraryExample2.Class1.test123() в C:\Users\User\source\repos\ClassLibraryExample2\ClassLibraryExample2\Class1.cs:строка 73
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

Код создания линии:
Ошибка в строке где "Тут"
Код - C# [Выбрать]
  1. private static void AddPoint(double x1, double y1, double x2, double y2)
  2.                 {
  3.                         // Get the current document and database
  4.                         Document acDoc = acad.DocumentManager.MdiActiveDocument;
  5.                         Database acCurDb = acDoc.Database;
  6.  
  7.                         // Start a transaction
  8.                         using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  9.                         {
  10.                                 // Open the Block table for read
  11.                                 BlockTable acBlkTbl;
  12.                                 acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId,
  13.                                                                                                 OpenMode.ForRead) as BlockTable;
  14.  
  15.                                 // Open the Block table record Model space for write
  16.                                 BlockTableRecord acBlkTblRec;
  17.                                 acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
  18.                                                                                                 OpenMode.ForWrite) as BlockTableRecord;
  19.                                 Line acLine;
  20.  
  21.                                 using (acLine = new Line(new Point3d(x1, y1, 0),
  22.                                                                                           new Point3d(x2, y2, 0)))
  23.                                 {
  24.  
  25.                                         acBlkTblRec.AppendEntity(acLine);
  26.                                         acLine.GetGeCurve();//Тут
  27.                                         acTrans.AddNewlyCreatedDBObject(acLine, true);
  28.                                 }
  29.                                 acTrans.Commit();
  30.                                
  31.                         }
  32.                 }
« Последнее редактирование: 14-03-2019, 00:00:04 от Александр Ривилис »

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

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

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
merta,
В коде у тебя полный бред, который даже непонятно как комментировать. Зачем ты создаёшь отрезок? Зачем пытаешься преобразовать его в Curve3d если для отрезка можно сразу создать LineSegment3d?

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Александр Ривилис, Извините за тэги. Тэг просто называется "Код", вот я и ошибся.

Я вызываю у полилинии GetClosesPointTо и передавал туда линию (выходила ошибка чуть ниже), а теперь попытался передать GetClosesPointTо, все равно вылетает ошибка(.

Как можно передать в метод GetClosesPointTо передать только созданную GetClosesPointTо?

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

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Чет устал.
Как можно в объекте polyline в метод getgeclosespointto, передать только что созданный lineSegment3d?

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
getgeclosespointto
Нет такого метода. Внимательнее!  Есть метод GetClosestPointTo.
Как можно в объекте polyline в метод getgeclosespointto, передать только что созданный lineSegment3d?
Никак. Polyline - это класс унаследованный от Curve (т.е. Autodesk.AutoCAD.DatabaseServices.Curve). Его метод GetClosestPointTo  принимает только точку (Point3d) - смотри документацию.
Метод Curve3d.GetClosestPointTo  позволяет передать другую кривую (Curve3d) в качестве параметра.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Красные линии показывают кратчайшее расстояние между кривыми (попарно):


Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. #pragma warning disable 0618
  9.  
  10. // This line is not mandatory, but improves loading performances
  11. [assembly: CommandClass(typeof(Rivilis.GetNearest))]
  12.  
  13. namespace Rivilis
  14. {
  15.   public class GetNearest
  16.   {
  17.  
  18.     [CommandMethod("GetNearest")]
  19.     public void GetNearestHandler() // This method can have any name
  20.     {
  21.       Document doc = Application.DocumentManager.MdiActiveDocument;
  22.       if (doc == null) return;
  23.       Editor ed = doc.Editor;
  24.       PromptEntityOptions prOpt = new PromptEntityOptions("");
  25.       prOpt.Message = "\nВыберите первую кривую: ";
  26.       prOpt.SetRejectMessage("\nЭто не кривая!");
  27.       prOpt.AddAllowedClass(typeof(Curve), false);
  28.       PromptEntityResult prRes1 = ed.GetEntity(prOpt);
  29.       if (prRes1.Status != PromptStatus.OK)
  30.         return;
  31.       prOpt.Message = "\nВыберите вторую кривую: ";
  32.       PromptEntityResult prRes2 = ed.GetEntity(prOpt);
  33.       if (prRes2.Status != PromptStatus.OK)
  34.         return;
  35.       using (Curve curve1 = prRes1.ObjectId.Open(OpenMode.ForRead) as Curve)
  36.       using (Curve curve2 = prRes2.ObjectId.Open(OpenMode.ForRead) as Curve)
  37.       {
  38.         using (Curve3d c3d1 = curve1.GetGeCurve())
  39.         using (Curve3d c3d2 = curve2.GetGeCurve())
  40.         {
  41.           PointOnCurve3d[] ptsOnc3d = c3d1.GetClosestPointTo(c3d2);
  42.           if (ptsOnc3d != null && ptsOnc3d.Length == 2)
  43.           {
  44.             using (BlockTableRecord btrSpace =
  45.               doc.Database.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord)
  46.             {
  47.               using (Line line = new Line(ptsOnc3d[0].Point, ptsOnc3d[1].Point))
  48.               {
  49.                 line.SetDatabaseDefaults();
  50.                 line.ColorIndex = 1; // Отметим красным цветом
  51.                 btrSpace.AppendEntity(line);
  52.               }
  53.             }
  54.           }
  55.         }
  56.       }
  57.     }
  58.   }
  59. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Спасибо

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
При нахождение короткого пути между 2 списками polyline  пишет ошибку: "System.NullReferenceException".
Как это исправляется

При первом прохождении 1 цикла все нормально работает. После второго прохождения первого цикла пишет ошибку выше.
Код - C# [Выбрать]
  1. foreach (Entity curvPoint in listPoint)//1-цикл
  2.                                 {
  3.                                         using (Curve curve1 = curvPoint.ObjectId.GetObject(OpenMode.ForRead) as Curve)
  4.                                         using (Curve3d c3d1 = curve1.GetGeCurve())
  5.                                         {
  6.                                                 foreach (Entity block in listPolyline)//2-цикл
  7.                                                 {
  8.                                                         try
  9.                                                         {
  10.                                                                 using (Curve curve2 = block as Curve)
  11.                                                                 using (Curve3d c3d2 = curve2.GetGeCurve())
  12.                                                                 {
  13.                                                                         PointOnCurve3d[] ptsOnc3d = c3d1.GetClosestPointTo(c3d2);
  14.                                                                                 AddLineBetweenDist(ptsOnc3d[0].Point, ptsOnc3d[1].Point);
  15.                                                                         acad.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\n\r curve2 " + ptsOnc3d.Length + " x1=" + ptsOnc3d[0].Point.X + " y1=" +
  16.                                                                                 ptsOnc3d[0].Point.Y + " x2=" + ptsOnc3d[0].Point.X + " y2=" + ptsOnc3d[0].Point.Y);
  17.                                                                 }
  18.                                                         }
  19.                                                         catch { }
  20.                                                 }
  21.                                         }
  22.                                 }

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
При первом прохождении 1 цикла все нормально работает. После второго прохождения первого цикла пишет ошибку выше.
Запусти под отладчиком и найди место, где возникает исключение.
P.S.: В настройках VS измени величину табуляции (сравни мой код и свой) - читать такой сдвинутый на половину экрана код невозможно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Ошибка возникает в Curve3d c3d2 = curve2.GetGeCurve(). Но при прохождении цикла в первый раз все нормально работает

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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ошибка возникает в Curve3d c3d2 = curve2.GetGeCurve(). Но при прохождении цикла в первый раз все нормально работает
Я так понимаю, что в этом случае curve2 == null, т.е. block as Curve возвращает null и соответственно block не наследник Curve. Проверяй что туда попадает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Off-Topic: показать
В настройках VS измени величину табуляции (сравни мой код и свой) - читать такой сдвинутый на половину экрана код невозможно.
Дополню. В стандартных настройках VS, автоматическое выравнивание кода - Ctrl+K+D


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

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
merta,
Стоп!!! А зачем вообще using в
Код - C# [Выбрать]
  1. using (Curve curve2 = block as Curve)
???
Ты понимаешь что происходит в этом случае или это просто копипастинг чужого кода?
Тогда объясню, что после завешения блока using curve2 будет закрыт (выполнен метод Close) и соответственно повторно к нему до его открытия обратиться нельзя. Так что этот using просто выкини из кода. Он в нём не нужен.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Александр Ривилис, Спасибо. Ещё раз прочитал, делает using все стало на свои места. Спасибо.