Нахождение длин от пересечения линий Self intersecting Lines

Автор Тема: Нахождение длин от пересечения линий Self intersecting Lines  (Прочитано 8488 раз)

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

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Всем привет! Вопрос, как получить отдельные участки длин от пересечения линий в .net на примере рисунка. Спасибо!

находить точки пересечения предполагается примерно так:
Код - 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. }
« Последнее редактирование: 10-03-2020, 12:12:58 от Александр Ривилис »

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

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

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Для начала нужно нормально сформулировать задачу. Из рисунка я только понял, что нужно находить разность координат X точек.

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

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

Спасибо!

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

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

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Нужно найти все точки пересечении ипоместить их в "массив". Массив отсортитровать по координате X. И этого судя по тому, что я вижу должно быть достаточно.

хм..да, точки пересечений нужно обязательно найти и поместить в "массив", но и координаты начала и конца секущейся линии тоже нужно найти и поместить в "массив"? иначе как я буду искать длину участка до пересечения и после пересечения?
p.s. может быть и достаточно.
Пример бы хоть какой-нибудь.. Спасибо.

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

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

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Да.

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

p.s. возможно даже точки не нужно создавать, а может быть просто создать новые линии на уже существующих до пересечения с секущей линией и после нее. возможно это будет на мой взгляд проще.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
p.s. возможно даже точки не нужно создавать, а может быть просто создать новые линии на уже существующих до пересечения с секущей линией и после нее. возможно это будет на мой взгляд проще.
И даже это не нужно. Имея координаты (X и Y) начала и конца и используя основы аналитической геометрии (на уровне школьного курса) вычисляется длина отрезка. Только судя по картинке нужна не длина отрезка, а длина проекции отрезка, т.е. разница координат X точек, о чем я уже в третий раз намекаю...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
И даже это не нужно. Имея координаты (X и Y) начала и конца и используя основы аналитической геометрии (на уровне школьного курса) вычисляется длина отрезка. Только судя по картинке нужна не длина отрезка, а длина проекции отрезка, т.е. разница координат X точек, о чем я уже в третий раз намекаю...

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

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

p.s. (с) Суха теория друг мой, а древо жизни пышно зеленеет.
« Последнее редактирование: 10-03-2020, 16:24:44 от Александр Ривилис »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
А где бы почитать как в c#.net реализовано с линией пересечения
Не линия пересечения, а точка (или точки) пересечения. И в предложенном вами коде эти точки вычисляются в строке:
Код - C# [Выбрать]
  1. l.IntersectWith(c, Intersect.OnBothOperands, intersectionPoints, IntPtr.Zero, IntPtr.Zero);
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Не линия пересечения, а точка (или точки) пересечения. И в предложенном вами коде эти точки вычисляются в строке:

Хотел увидеть именно с линиями пересечения, ну если нет подобных примеров, то буду пробовать с точками.
код не мой поэтому я не сильно вникал, но уже понял, куда смотреть.
я на форуме не так давно, поэтому глубоко не "рыл", думал, если кто уже решал подобные задачи смог бы поделиться..
Спасибо.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вот пример, который дальше будешь "допиливать" для себя:
Код - 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. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Спасибо буду пилить.

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Вот пример, который дальше будешь "допиливать" для себя:

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


 

Спасибо!
« Последнее редактирование: 14-03-2020, 21:21:06 от ДмитрийПетров »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вот пример, который дальше будешь "допиливать" для себя:

Пример работает, но если первой выбрать "очередную линию", а в качестве очередной "основную", иначе дельта x = 0. Cпасибо!
 
Не понял. Если запишешь видео, то надеюсь, что пойму...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
как-то так..
« Последнее редактирование: 14-03-2020, 22:27:09 от ДмитрийПетров »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ДмитрийПетров,
1. Как записывать видео для нашего форума написано у меня в подписи.
2. Ну тут всё понятно и программа работает именно так, как задуманно. Основная линия, с которой ты пересекал остальные, имеет почти вертикальный кусок. Поэтому и расстояние по X (почти) равно 0.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
2. Ну тут всё понятно и программа работает именно так, как задуманно. Основная линия, с которой ты пересекал остальные, имеет почти вертикальный кусок. Поэтому и расстояние по X (почти) равно 0.

Я и хотел разобраться как работает этот метод IntersectWith, где можно поподробнее с ним познакомиться, если я хочу получать проекции на ось Х от секущей "основной линии" если она в горизонтальном и в вертикальном расположении?
Код - vb.net [Выбрать]
  1.  mainCurve.IntersectWith(secondCurve, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
что есть что в этой записи, особенно после Intersect.?
в следующем видео я как раз и столкнулся с этой проблемой..
Спасибо.
« Последнее редактирование: 15-03-2020, 20:01:32 от ДмитрийПетров »

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
видео к посту #15

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

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

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Код - 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. 
Что именно здесь непонятно?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
А это совершенно отдельная задача и методом IntersectWith её не решают.

таак, а где почитать поподробнее как решить мне ее? Спасибо.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
таак, а где почитать поподробнее как решить мне ее? Спасибо.
Собственно говоря нигде такого почитать нельзя. Это чистая аналитическая геометрия. В 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  для получения проекции точки на прямую.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Например:
1) Autodesk.AutoCAD.Geometry.Line3d для создания бесконечной прямой, на которую будем проецировать точку
2) Воспользуемся методом GetProjectedClosestPointTo(Point3d pt /* точка, которую проецируем */, Vector3d norm /* вектор проекции */)
Или:
1) Создаём плоскость Autodesk.AutoCAD.Geometry.Plane с началом в одной из точек прямой для проекции и вектором нормали Vector3d.ZAxis
2) Используем метод Point3d.OrthoProject  для получения проекции точки на прямую.
Спасибо, буду изучать в этом направлении.

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Воспользуемся методом GetProjectedClosestPointTo(Point3d pt /* точка, которую проецируем */, Vector3d norm /* вектор проекции */)
Не нашел никаких примеров как пользоваться этим методом, кроме
"Public Function GetProjectedClosestPointTo(point As Point3d, projectDirection As Vector3d, tolerance As Tolerance) As PointOnCurve3d" из справки Автодеск.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
ДмитрийПетров,
Код - 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. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ДмитрийПетровАвтор темы

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: petroffdv
Спасибо за пример, попробую адаптировать.