Анализ пересечения объектов

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

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

Оффлайн Николай КоломоецАвтор темы

  • ADN Club
  • Сообщений: 16
  • Карма: 0
  • Skype: myckola_kolomoets
Доброго всем времени суток.

Есть задача - проанализировать, находится ли точка на блоке (на каком-либо из его примитивов, за исключением текста или атрибута, штриховки).
Написал такой текст:

Код - C# [Выбрать]
  1. private int Compare(Point3d point, BlockReference br, double radius)
  2.         {
  3.             Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
  4.             Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
  5.             bool intersect = false;
  6.             using (Transaction trans = db.TransactionManager.StartTransaction())
  7.             {
  8.                 BlockTableRecord btr = trans.GetObject(br.BlockTableRecord,OpenMode.ForRead) as BlockTableRecord;
  9.                 //BlockTableRecord modelBTR = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
  10.                 Matrix3d brTransformedCoord = br.BlockTransform;
  11.  
  12.                 foreach (ObjectId objId in btr)
  13.                 {
  14.                     DBObject obj = trans.GetObject(objId, OpenMode.ForWrite);
  15.                     if ((obj is Entity) && (!(obj is DBText)) && (!(obj is MText)) && (!(obj is Hatch)) && (!(obj is Spline)))
  16.                     {
  17.                         Entity ent = (Entity)obj;
  18.                         Entity tempEnt = ent;
  19.                         tempEnt.TransformBy(brTransformedCoord);
  20.                         Point3dCollection pts = new Point3dCollection();
  21.                         //Plane pl = new Plane();
  22.                         Circle pointCircle = new Circle(point, new Vector3d(0, 0, 1), radius);
  23.                         //modelBTR.AppendEntity(pointCircle);
  24.                         //trans.AddNewlyCreatedDBObject(pointCircle, true);
  25.                         try
  26.                         {
  27.                             tempEnt.IntersectWith(pointCircle, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
  28.                         }
  29.                         catch (Autodesk.AutoCAD.Runtime.Exception ex)
  30.                         {
  31.                         //    MessageBox.Show(ex.Message + ex.Source + "\n");
  32.                         }
  33.                         if (pts.Count > 0)
  34.                             intersect = true;
  35.                         //pointCircle.Erase();
  36.                     }
  37.                 }
  38.                 trans.Commit();
  39.             }
  40.             if (intersect == true)
  41.                 return 0;
  42.                         return -1;
  43.         }

Тут point - точка; br - вставка блока: функция должна вернуть 0, если точка находится на блоке; radius - "допуск", тут используется для прорисовки малого круга: считаю, что точка находится на блоке, если круг радиуса radius с центром в точке point пересекает какой-либо из примитивов блока.

В общем, данная функция никогда не возвращает 0 в реальной жизни. Как мне кажется, я неправильно понимаю работу метода IntersectWith.

Анализировать отдельно каждый тип примитива (линию, дугу и т.п.) тоже наверное неправильно. Как правильнее всего поступить в данной ситуации?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Re: Анализ пересечения объектов
« Ответ #1 : 21-07-2013, 20:37:11 »
В порядке предположения: а система координат вхождения блока мировая? Угол поворота 0? Масштабы по разным осям тоже равны 1?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Николай КоломоецАвтор темы

  • ADN Club
  • Сообщений: 16
  • Карма: 0
  • Skype: myckola_kolomoets
Re: Анализ пересечения объектов
« Ответ #2 : 21-07-2013, 21:01:35 »
Система координат мировая. Масштабы все по 1, хотя тут хотелось бы узнать, что делать, если будет не так - программа все-таки должна работать при любых блоках. А вот насчет поворота - тут интереснее: блоки в большинстве своем динамические. Угол вставки самого блока почти всегда 0, но динамический параметр - угол поворота! Вообще, блоки могут быть любые, в т.ч. динамические, параметрические.
Выходит, что Entity.TransformBy(BlockReference.BlockTransform) не учитывает все эти параметры?

P.S. Пока, чтобы работало, сделал анализ пересечения с конкретным типом данных примитива из br.BlockTableRecord - Circle, Arc, Curve и Polyline. Работает "почти" нормально, но это явно неверный способ решения проблемы.

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1096
  • Карма: 172
Re: Анализ пересечения объектов
« Ответ #3 : 22-07-2013, 09:32:14 »
Могу попытаться помочь только с общим алгоритмом, но никак не с реализацией :(
Что бы сделал я:
  • Перевести координаты точки / примитива "в блок" - т.е. сложить координаты (предварительно умножив на коэффициенты масштабов по соответствующим осям), высчитать полярное смещение и т.п.
  • Пройтись по всем подпримитивам описания блока и проверить для каждого IntersectWith
Как-то так, наверное...
P.S. На caduser.ru, кажется, были варианты лисповых решений поиска пересечения примитивов и блоков, но я особо за ними не следил, поскольку не требовалось решать подобные задачи.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Анализ пересечения объектов
« Ответ #4 : 31-07-2013, 22:55:47 »
Для примитивов унаследованных от Curve я вообще не вижу смысла так усложнять код. Достаточно проверять расстояние от точки до примитива при помощи метода GetClosestPointTo. С остальными типами примитивов придётся разбираться отдельно. Для Region и Solid3d потребуется использовать BREP .NET API.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Николай КоломоецАвтор темы

  • ADN Club
  • Сообщений: 16
  • Карма: 0
  • Skype: myckola_kolomoets
Re: Анализ пересечения объектов
« Ответ #5 : 01-08-2013, 12:31:18 »
Это "исторически" сложилось так - я думал, что метод IntersectWith работает для всех типов Entity, и что одной командой можно решить все вопросы. Потом начал применять его по-разному к разным типам примитивов, но саму команду оставил.

Переделаю, спасибо за совет :)