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

ADN Club => AutoCAD .NET API => Тема начата: Алексей (IdeaSoft) от 08-06-2017, 11:07:38

Название: Преобразовать сплайн в полилинию
Отправлено: Алексей (IdeaSoft) от 08-06-2017, 11:07:38
Возможно в AutoCAD API
объект Сплайн превратить в полилинию?

Название: Re: Преобразовать сплайн в полилинию
Отправлено: Александр Ривилис от 08-06-2017, 11:15:08
Да. Это называется аппроксимацией сплайна. В результате получишь полилинию с линейными сегментами.
Использовать следует Curve3d.GetSamplePoints
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Алексей (IdeaSoft) от 08-06-2017, 11:17:35
Спасибо буду пробовать.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Александр Ривилис от 08-06-2017, 11:18:47
Тут описано подробнее: http://adn-cis.org/forum/index.php?topic=57.msg22255#msg22255
Название: Re: Преобразовать сплайн в полилинию
Отправлено: avc от 08-06-2017, 11:38:40
Я испробовал кучу методов, и остановился на таком:
Код - C# [Выбрать]
  1.       double len = spline.Length();
  2.       if (len <= tol.EqualPoint) return null;
  3.       uint count = (uint)Math.Ceiling(len / (tol.EqualPoint * (lineOnly ? 1 : 2)));
  4.       if (count == 0) return null;
  5.       Polyline pl = null;
  6.       try
  7.       {
  8.         pl = spline.ToPolyline(count) as Polyline;
  9.       }
  10.       catch (Autodesk.AutoCAD.Runtime.Exception ex)
  11.       {
  12.         if (ex.ErrorStatus == Autodesk.AutoCAD.Runtime.ErrorStatus.InvalidInput) // Автокад считает count слишком маленьким - пусть сам выберет по больше
  13.           pl = spline.ToPolyline() as Polyline;
  14.       }
  15.       if (pl == null) return null;
  16.       // автокад умудряется не дотянуть полилинию до конечных точек исходного сплайна. Исправляем:
  17.       if (pl.StartPoint.DistanceTo(spline.StartPoint) > ZeroSize)
  18.       {
  19.         Point3d start = spline.StartPoint;
  20.         pl.AddVertexAt(0, new Point2d(start.X, start.Y), 0, pl.GetStartWidthAt(0), pl.GetStartWidthAt(0));
  21.       }
  22.  
  23.       if (pl.EndPoint.DistanceTo(spline.EndPoint) > ZeroSize)
  24.       {
  25.         Point3d end = spline.EndPoint;
  26.         pl.AddVertexAt(pl.NumberOfVertices, new Point2d(end.X, end.Y), 0, pl.GetEndWidthAt(pl.NumberOfVertices - 1), pl.GetEndWidthAt(pl.NumberOfVertices - 1));
  27.       }
  28.  
этот метод дает результаты в пределах заданной точности tol. ZeroSize - это самый маленький размер с которым реально работать в Автокаде. Эмперически я его вычислил как = 0.0000001. lineOnly - это запрет на использование дуг (bool).
В результитующей полилинии неизбежно будут тысячи сегментов. Причем многие нулевой длины или меньше ZeroSize - требуется десегментация.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Алексей (IdeaSoft) от 08-06-2017, 12:43:27
В моей задаче особо точность не нужна
достаточно аппроскимировать кривую
отрезками длинной в 1 целую ед.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: avc от 08-06-2017, 13:01:56
Если вам не важно что получится, то проще использовать
Код - C# [Выбрать]
  1. int prec = (lineOnly ? 1 : 4);
  2. curve = spline.ToPolylineWithPrecision(prec); // обычно получается Polyline2d или Polyline3d
А если четко задано не выйти за погрешность в 1 - то действуйте как я писал выше с
Код - C# [Выбрать]
  1. tol = new Tolerance( Math.PI / 180, 1); // погрешность по углу не имеет значения в этом контексте
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Дмитрий Загорулькин от 08-06-2017, 13:04:10
В моей задаче особо точность не нужна
достаточно аппроскимировать кривую
отрезками длинной в 1 целую ед.
Так вот откуда потом в чертежах берутся эти кривые, состоящие из несколько сотен вершин!  :-X :)
Как-то разбирался, почему файл средней по размеру топосъемки был огромных размеров и сильно тормозил при работе. Оказалось, что в нем каждая горизонталь была отрисована полилинией из нескольких сотен мелких прямолинейных сегментов. После того, как прогнали "прополку полилиний" из известного комплекта PL-Tools, файл "похудел" на десяток мегабайт и перестал тормозить.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: avc от 08-06-2017, 13:18:26
Хорошо если "сотен вершин". Обычное SPlineEdit выдает тысячи и десятки тысяч. А если это потом вытянуть в солид, то вообще кранты Автокаду.
Тут не возбраняется самореклама?
Извините, вам запрещён просмотр содержимого спойлеров.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Debalance от 21-07-2017, 09:36:23
ZeroSize - это самый маленький размер с которым реально работать в Автокаде. Эмперически я его вычислил как = 0.0000001.
Интересно! Поделитесь Вашими изысканиями. Что значит фраза "реально работать"? На сколько я помню допуск по-умолчанию составляет 1.e-10.
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Александр Ривилис от 21-07-2017, 09:39:15
На сколько я помню допуск по-умолчанию составляет 1.e-10.
Это было до AutoCAD 2015 - потом его "загрубили".
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Debalance от 21-07-2017, 09:47:18
Это было до AutoCAD 2015 - потом его "загрубили".
Смотрю в документации OARX 2016 и вижу те же данные для AcGeContext gTol (equalPoint and equalVector tolerances set to 1.e-10).
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Александр Ривилис от 21-07-2017, 09:51:07
"...не верь глазам своим...": http://adn-cis.org/metod-acdbregion-transformby.html
Название: Re: Преобразовать сплайн в полилинию
Отправлено: Debalance от 21-07-2017, 09:56:29
"...не верь глазам своим..."
Ха! Вы приоткрыли мне калитку в неведомое...