Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: ДмитрийПетров от 10-03-2020, 12:08:14

Название: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 12:08:14
Всем привет! Вопрос, как получить отдельные участки длин от пересечения линий в .net на примере рисунка. Спасибо!
(https://i.postimg.cc/ZWpSbQF7/one-moment.png) (https://postimg.cc/ZWpSbQF7)
находить точки пересечения предполагается примерно так:
Код - C# [Выбрать]
  1. [CommandMethod("findIntersect")]
  2. public static void CmdFindIntersect()
  3. {
  4.   Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  5.   ObjectId lineId = ed.GetEntity("Select line: ").ObjectId; // not safe, test only
  6.   ObjectId circleId = ed.GetEntity("Select circle: ").ObjectId; // not safe, test only
  7.  
  8.   Database db = Application.DocumentManager.MdiActiveDocument.Database;
  9.   using (Transaction trans = db.TransactionManager.StartTransaction())
  10.   {
  11.     Line l = trans.GetObject(lineId, OpenMode.ForRead) as Line;
  12.     Circle c = trans.GetObject(circleId, OpenMode.ForRead) as Circle;
  13.  
  14.     Point3dCollection intersectionPoints = new Point3dCollection();
  15.     l.IntersectWith(c, Intersect.OnBothOperands, intersectionPoints, IntPtr.Zero, IntPtr.Zero);
  16.  
  17.     trans.Commit();
  18.  
  19.     ed.WriteMessage("{0} intersection(s) found", intersectionPoints.Count);
  20.   }
  21. }
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 12:12:00
Для начала нужно нормально сформулировать задачу. Из рисунка я только понял, что нужно находить разность координат X точек.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 13:00:32
Для начала нужно нормально сформулировать задачу. Из рисунка я только понял, что нужно находить разность координат X точек.

Задача вообще комплексная, а это небольшая подзадача. Да у меня есть массив из линий и мне необходимо рассчитать длины тех линий, которые попадают в пересечение с "голубой" линией, причем одни длины, которые до пересечения с вертикальной линией положить в один массив другие длины, после пересечения, в другой массив. По видимому, в местах пересечений, создается точка и нужно измерить расстояние от начала линии до точки и от точки до конца линии. Хотелось бы увидеть как это делается на любом примере .net.

1. Предполагаю, вначале нужно создать точки на горизонтальных линиях в начале и в конце, запомнить их.
2. Создать точки пересечения линий, запомнить их.
3. Вычислить расстояния между этими точками, расстояния занести в массив (должно быть два разных массива - один до пересечения, другой после пересечения, как я писал выше).

Спасибо!
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 13:56:38
1. Предполагаю, вначале нужно создать точки на горизонтальных линиях в начале и в конце, запомнить их.
2. Создать точки пересечения линий, запомнить их.
3. Вычислить расстояния между этими точками, расстояния занести в массив (должно быть два разных массива - один до пересечения, другой после пересечения, как я писал выше).
Как-то уж очень всё запутано. Мне видится эта задача значительно проще. Нужно найти все точки пересечении ипоместить их в "массив". Массив отсортитровать по координате X. И этого судя по тому, что я вижу должно быть достаточно.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 14:39:15
Нужно найти все точки пересечении ипоместить их в "массив". Массив отсортитровать по координате X. И этого судя по тому, что я вижу должно быть достаточно.

хм..да, точки пересечений нужно обязательно найти и поместить в "массив", но и координаты начала и конца секущейся линии тоже нужно найти и поместить в "массив"? иначе как я буду искать длину участка до пересечения и после пересечения?
p.s. может быть и достаточно.
Пример бы хоть какой-нибудь.. Спасибо.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 14:42:24
но и координаты начала и конца секущейся линии тоже нужно найти и поместить в "массив"?
Да.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 15:02:39
Да.

Понятно. Тогда следующий вопрос, как мне, имея в массиве линии создать на их концах точки и затем по созданным точкам найти длину между точками . Желательно пример. Спасибо.

p.s. возможно даже точки не нужно создавать, а может быть просто создать новые линии на уже существующих до пересечения с секущей линией и после нее. возможно это будет на мой взгляд проще.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 15:38:37
p.s. возможно даже точки не нужно создавать, а может быть просто создать новые линии на уже существующих до пересечения с секущей линией и после нее. возможно это будет на мой взгляд проще.
И даже это не нужно. Имея координаты (X и Y) начала и конца и используя основы аналитической геометрии (на уровне школьного курса) вычисляется длина отрезка. Только судя по картинке нужна не длина отрезка, а длина проекции отрезка, т.е. разница координат X точек, о чем я уже в третий раз намекаю...
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 16:21:42
И даже это не нужно. Имея координаты (X и Y) начала и конца и используя основы аналитической геометрии (на уровне школьного курса) вычисляется длина отрезка. Только судя по картинке нужна не длина отрезка, а длина проекции отрезка, т.е. разница координат X точек, о чем я уже в третий раз намекаю...

Совершенно верно, длина проекции отрезка на x y.
школьную геометрию никто не отменял..
Код - C# [Выбрать]
  1. sqrt((x2*x2)+(y2*y2))-sqrt((x1*x1)+(y1*y1));

А где бы почитать как в c#.net реализовано с линией пересечения и нахождение необходимых расстояний? Спасибо.

p.s. (с) Суха теория друг мой, а древо жизни пышно зеленеет.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 16:23:51
А где бы почитать как в c#.net реализовано с линией пересечения
Не линия пересечения, а точка (или точки) пересечения. И в предложенном вами коде эти точки вычисляются в строке:
Код - C# [Выбрать]
  1. l.IntersectWith(c, Intersect.OnBothOperands, intersectionPoints, IntPtr.Zero, IntPtr.Zero);
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 16:25:42
школьную геометрию никто не отменял..
Как и правило форматирования кода на нашем форуме. Это правило у меня в подписи.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 16:33:48
Не линия пересечения, а точка (или точки) пересечения. И в предложенном вами коде эти точки вычисляются в строке:

Хотел увидеть именно с линиями пересечения, ну если нет подобных примеров, то буду пробовать с точками.
код не мой поэтому я не сильно вникал, но уже понял, куда смотреть.
я на форуме не так давно, поэтому глубоко не "рыл", думал, если кто уже решал подобные задачи смог бы поделиться..
Спасибо.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 10-03-2020, 18:22:40
Вот пример, который дальше будешь "допиливать" для себя:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Geometry;
  5. using Autodesk.AutoCAD.Runtime;
  6. using System;
  7. using System.Collections.Generic;
  8.  
  9. // This line is not mandatory, but improves loading performances
  10. [assembly: CommandClass(typeof(Rivilis.TestIntersect))]
  11.  
  12. namespace Rivilis
  13. {
  14.   public class TestIntersect
  15.   {
  16.     [CommandMethod("GetIntSegs")]
  17.     public void GetIntSegsHandler()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null)   return;
  21.       Editor ed = doc.Editor;
  22.       PromptEntityOptions prEntOpt =
  23.         new PromptEntityOptions("\nВыберите основную линию, пересечение с которой мы ищем: ");
  24.       prEntOpt.SetRejectMessage("Это не линия");
  25.       prEntOpt.AddAllowedClass(typeof(Curve), false);
  26.       PromptEntityResult prEntRes = ed.GetEntity(prEntOpt);
  27.       ObjectIdCollection ids = new ObjectIdCollection();
  28.       if (prEntRes.Status != PromptStatus.OK)
  29.         return;
  30.       ids.Add(prEntRes.ObjectId);
  31.       prEntOpt.Message =
  32.          "Выберите очередную линию для пересечения (ENTER - завершение)";
  33.       while (true)
  34.       {
  35.         prEntRes = ed.GetEntity(prEntOpt);
  36.         if (prEntRes.Status != PromptStatus.OK)
  37.           break;
  38.         ids.Add(prEntRes.ObjectId);
  39.       }
  40.       if (ids.Count == 1) {
  41.         ed.WriteMessage("\nНичего не выбрано!");
  42.         return;
  43.       }
  44.       Point3dCollection pts = new Point3dCollection();
  45.       using (Transaction tr = doc.TransactionManager.StartTransaction())
  46.       {
  47.         Curve mainCurve = (Curve)tr.GetObject(ids[0], OpenMode.ForRead);
  48.         pts.Add(mainCurve.StartPoint); pts.Add(mainCurve.EndPoint);
  49.         for (int i = 1; i < ids.Count; i++) {
  50.           Curve secondCurve = (Curve)tr.GetObject(ids[i], OpenMode.ForRead);
  51.           mainCurve.IntersectWith(secondCurve, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
  52.         }
  53.         // Итак мы получили все точки (крайние и точки пересечений)
  54.         // Сортируем их по координате X
  55.         Point3d[] ptsa = new Point3d[pts.Count];  pts.CopyTo(ptsa, 0);
  56.         List<Point3d> ptsl = new List<Point3d>(ptsa);
  57.         ptsl.Sort((p1, p2) =>
  58.         {
  59.           if (p1.X < p2.X) return -1;
  60.           else if (p1.X > p2.X) return 1;
  61.           return 0;
  62.         });
  63.         for (int i = 0; i < ptsl.Count - 1; i++)
  64.         {
  65.           ed.WriteMessage($"\nНачало = {ptsl[i].X} Конец = {ptsl[i + 1].X} Длина по X = {ptsl[i + 1].X - ptsl[i].X}");
  66.         }
  67.         tr.Commit();
  68.       }
  69.     }
  70.   }
  71. }
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 10-03-2020, 18:31:39
Спасибо буду пилить.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 14-03-2020, 18:47:29
Вот пример, который дальше будешь "допиливать" для себя:

Пример работает, но если первой выбрать "очередную линию", а в качестве очередной "основную", иначе дельта x = 0.
Я не могу пока понять как обработать вот такой пример, где присутствует "основная линия" по X и по Y?


 
(https://i.postimg.cc/cr27jK4s/2020-03-14-21-11-03.png) (https://postimg.cc/cr27jK4s)
Спасибо!
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 14-03-2020, 21:04:53
Вот пример, который дальше будешь "допиливать" для себя:

Пример работает, но если первой выбрать "очередную линию", а в качестве очередной "основную", иначе дельта x = 0. Cпасибо!
 
Не понял. Если запишешь видео, то надеюсь, что пойму...
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 14-03-2020, 21:41:44
как-то так..
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 14-03-2020, 22:33:18
ДмитрийПетров,
1. Как записывать видео для нашего форума написано у меня в подписи.
2. Ну тут всё понятно и программа работает именно так, как задуманно. Основная линия, с которой ты пересекал остальные, имеет почти вертикальный кусок. Поэтому и расстояние по X (почти) равно 0.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 15-03-2020, 19:26:17
2. Ну тут всё понятно и программа работает именно так, как задуманно. Основная линия, с которой ты пересекал остальные, имеет почти вертикальный кусок. Поэтому и расстояние по X (почти) равно 0.

Я и хотел разобраться как работает этот метод IntersectWith, где можно поподробнее с ним познакомиться, если я хочу получать проекции на ось Х от секущей "основной линии" если она в горизонтальном и в вертикальном расположении?
Код - vb.net [Выбрать]
  1.  mainCurve.IntersectWith(secondCurve, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
что есть что в этой записи, особенно после Intersect.?
в следующем видео я как раз и столкнулся с этой проблемой..
Спасибо.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 15-03-2020, 19:27:50
видео к посту #15
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 15-03-2020, 19:51:29
Я и хотел разобраться как работает этот метод IntersectWith, где можно поподробнее с ним познакомиться
Этот метод просто находит точки пересечения примитивов в AutoCAD.
если я хочу получать проекции на ось Х от секущей "основной линии" если она в горизонтальном и в вертикальном расположении?
А это совершенно отдельная задача и методом IntersectWith её не решают.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 15-03-2020, 19:56:46
Код - vb.net [Выбрать]

     mainCurve.IntersectWith(secondCurve, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);

что есть что в этой записи, особенно после Intersect..
Всё описано в документации:
Цитировать
Entity entityPointer  Input entity with which "this" entity is to intersect 
Autodesk.AutoCAD.DatabaseServices.Intersect intersectType  Input type of intersection requested 
Point3dCollection points  Output with the points of intersection appended 
IntPtr thisGraphicSystemMarker  Input GS marker of subentity of "this" entity that's involved in the intersection operation. Use the 0 default if not applicable. 
IntPtr otherGraphicSystemMarker  Input GS marker of subentity of the entity pointed to by entityPointer that's involved in the intersection operation. Use the 0 default if not applicable. 
Что именно здесь непонятно?
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 15-03-2020, 20:09:46
А это совершенно отдельная задача и методом IntersectWith её не решают.

таак, а где почитать поподробнее как решить мне ее? Спасибо.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 15-03-2020, 20:22:13
таак, а где почитать поподробнее как решить мне ее? Спасибо.
Собственно говоря нигде такого почитать нельзя. Это чистая аналитическая геометрия. В AutoCAD .NET API можно воспользоваться Autodesk.AutoCAD.Geometry. Например:
1) Autodesk.AutoCAD.Geometry.Line3d для создания бесконечной прямой, на которую будем проецировать точку
2) Воспользуемся методом GetProjectedClosestPointTo(Point3d pt /* точка, которую проецируем */, Vector3d norm /* вектор проекции */)
Или:
1) Создаём плоскость Autodesk.AutoCAD.Geometry.Plane с началом в одной из точек прямой для проекции и вектором нормали Vector3d.ZAxis
2) Используем метод Point3d.OrthoProject  для получения проекции точки на прямую.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 15-03-2020, 22:21:07
Например:
1) Autodesk.AutoCAD.Geometry.Line3d для создания бесконечной прямой, на которую будем проецировать точку
2) Воспользуемся методом GetProjectedClosestPointTo(Point3d pt /* точка, которую проецируем */, Vector3d norm /* вектор проекции */)
Или:
1) Создаём плоскость Autodesk.AutoCAD.Geometry.Plane с началом в одной из точек прямой для проекции и вектором нормали Vector3d.ZAxis
2) Используем метод Point3d.OrthoProject  для получения проекции точки на прямую.
Спасибо, буду изучать в этом направлении.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 16-03-2020, 17:52:21
Воспользуемся методом GetProjectedClosestPointTo(Point3d pt /* точка, которую проецируем */, Vector3d norm /* вектор проекции */)
Не нашел никаких примеров как пользоваться этим методом, кроме
"Public Function GetProjectedClosestPointTo(point As Point3d, projectDirection As Vector3d, tolerance As Tolerance) As PointOnCurve3d" из справки Автодеск.
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: Александр Ривилис от 16-03-2020, 18:09:37
ДмитрийПетров,
Код - C# [Выбрать]
  1. /// <summary>
  2. ///  Функция возвращает проекцию точки на прямую, заданную
  3. ///  двумя точками. Проекция по оси Y
  4. /// </summary>
  5. /// <param name="p">Проецирумая точка</param>
  6. /// <param name="p1">первая точка прямой</param>
  7. /// <param name="p2">вторая точка прямой</param>
  8. /// <returns></returns>
  9. Point3d GetProjectPoint(Point3d p, Point3d p1, Point3d p2)
  10. {
  11.   using (Line3d line = new Line3d(p1, p2)) {
  12.     return line.GetProjectedClosestPointTo(p, Vector3d.YAxis).Point;
  13.   }
  14. }
Название: Re: Нахождение длин от пересечения линий Self intersecting Lines
Отправлено: ДмитрийПетров от 17-03-2020, 09:40:33
Спасибо за пример, попробую адаптировать.