Некорректное определение средней точки для сплайна

Автор Тема: Некорректное определение средней точки для сплайна  (Прочитано 26177 раз)

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

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 475
  • Карма: 63
для простых полилиний? это очевидно
А вот у NURBS всё очень весело

Хотелось бы, что бы документация была бы полнее, но тогда она начнёт напоминать учебник по Геометрии
Но если держать под рукой нужные книжки, многие вещи выглядят очевидными

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Но если держать под рукой нужные книжки, многие вещи выглядят очевидными
Это было бы очевидным, если бы разработчики AutoCAD в документации давали бы ссылки на главы в "нужных книжках". А в нынешней ситуации остаётся только ломать голову и догадываться: "так это или не так...?"

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Кстати, можешь воспользоваться ARXDBG-> Curve Test для тестирования:
Продолжая тестировать CurveTest у меня возник вопрос. В данной утилите есть два исполнения getClosestPointTo:



В моём случае getClosestPointTo (projected) даёт более точные результаты. Но мне не совсем понятно как программно реализуется данная функция (в отличии от просто getClosesstPointTo)?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
В моём случае getClosestPointTo (projected) даёт более точные результаты. Но мне не совсем понятно как программно реализуется данная функция (в отличии от просто getClosesstPointTo)?
Читаем ObjectARX SDK Docs:
Цитировать
This function projects the curve onto the plane defined by givenPnt and normal, finds the point on the projected curve that is nearest to givenPnt, then projects this nearest point back onto the original curve and sets pointOnCurve to the result.
Вопросы еще остались?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Вопросы еще остались?
Увы да и много. Кластер вопросов вытекает опять же из темы связанной со сплайнами и функцией getClosestPointTo.
Имеем конкретный сплайн (см. чертёж во вложении). И пытаемся определить на нём ближайшую точку к некой точке в пространстве:



На рисунке точка совпадает с центром жёлтого кружка. Однако, ближайшая точка определяется совсем в неожиданном месте (голубой маркер).
И так вопросы:
1. Это что уникальность сплайна?
2. Может это быть глюком самого AutoCAD?
3. Существует ли достойное решение нахождения ближайшей точки в таком случае (ибо аналогичные сплайны в моём случае попадаются весьма часто)?

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
1. Это что уникальность сплайна?
2. Может это быть глюком самого AutoCAD?
Допускаю, что может. Мы как-то на DWG.RU коллективно составляли метод, которые корректно определял бы BoundingBox для сплайна, т.к. стандартный метод возвращал некорректный результат: http://forum.dwg.ru/showthread.php?t=41621&highlight=%EF%E5%F7%E0%F2%FC&page=2 сообщения #24 - #52.
Возможно, что и с определением ближайшей точки проблемы.

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
т.к. стандартный метод возвращал некорректный результат
Ну БаундингБокс это отдельная тема - он и для дуги выдаёт некорректные результаты (в своё время я с этим тоже накувыркался). А если это касается точки на кривой - то Автокаду грош цена как инженерной системе...

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Сплайник-то длиной 0,1 ед. чертежа. Погрешность определения точки в этом случае составляет около 0,01 ед.чертежа. Зачем Вам такая точность?
Если хотя бы в 10 раз увеличить - ближайшая точка корректно определяется.

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Погрешность определения точки в этом случае составляет около 0,01 ед.чертежа
Откуда Вы взяли эту цифру?

Зачем Вам такая точность?
Ну значит нужна. А что, это разве большая точность для точного машиностроения и для возможностей AutoCAD?

Если хотя бы в 10 раз увеличить - ближайшая точка корректно определяется.
ХОТЯ БЫ В Д-Е-С-Я-Т-Ь?!!! То есть всё-таки глюк?

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Откуда Вы взяли эту цифру?
Измерил расстояние между полученной точкой и той, которую ожидалось получить.
Ну значит нужна. А что, это разве большая точность для точного машиностроения и для возможностей AutoCAD?
Тогда, наверное, лучше сплайн не использовать. Видимо, у него есть искусственное ограничение по точности вычисления. Подозреваю, что это ввели специально, чтобы не страдало быстродействие.

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Измерил расстояние между полученной точкой и той, которую ожидалось получить.
Я предпочитаю измерять погрешность в процентах. И в данном случае погрешность составляет примерно 400%.

Тогда, наверное, лучше сплайн не использовать.
Весьма жаль. В связи с этим область применения AutoCAD'а резко "скукоживается".

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

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

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

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Выходит движок AutoCAD весьма негибкий ибо не может приспосабливаться к масштабу чертежа.
Немного не так. Механизм сплайнов в AutoCAD не позволяет их использовать в нанотехнологиях :) Но с другими объектами все не так уж и плохо. В .NET API у сплайна есть метод ToPolylineWithPrecision. С его помощью можно получить нужную точку (переписать на C++ думаю не будет проблемой):
Код - 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.  
  7. namespace AcadTest
  8. {
  9.     public class CurveTest
  10.     {
  11.         [CommandMethod("TestClosestPoint")]
  12.         public void ClosestPoint()
  13.         {
  14.             SupportMethods.InitializeVars
  15.                 (out Document adoc, out Editor ed, out Database db);
  16.  
  17.             ObjectId id = SupportMethods.SelectEntity(ed, "\nSelect curve:");
  18.             if (!id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(Curve))))
  19.             {
  20.                 ed.WriteMessage("\nIt's not curve!");
  21.                 return;
  22.             }
  23.  
  24.             Point3d? pt = SupportMethods.GetPoint(ed);
  25.             if (!pt.HasValue)
  26.             {
  27.                 ed.WriteMessage("\nNo point!");
  28.                 return;
  29.             }
  30.  
  31.             Point3d? closPt = null;
  32.  
  33.             using (Curve curve = id.Open(OpenMode.ForRead) as Curve)
  34.             {
  35.                 if (curve != null)
  36.                 {
  37.                     if (curve is Spline spline)
  38.                     {
  39.                         using (Curve plCurve = spline.ToPolylineWithPrecision(5))
  40.                         {
  41.                             closPt = plCurve.GetClosestPointTo(pt.Value, false);
  42.                         }
  43.                     }
  44.                     else
  45.                     {
  46.                         closPt = curve.GetClosestPointTo(pt.Value, false);
  47.                     }
  48.                 }
  49.             }
  50.  
  51.             if (closPt.HasValue)
  52.             {
  53.                 using (Circle circle = new Circle())
  54.                 {
  55.                     circle.Center = closPt.Value;
  56.                     circle.Radius = 0.1 * closPt.Value.DistanceTo(pt.Value);
  57.                     circle.ColorIndex = 1;
  58.                     using (BlockTableRecord cSpace
  59.                         = id.Database.CurrentSpaceId.Open(OpenMode.ForWrite) as BlockTableRecord)
  60.                     {
  61.                         if (cSpace != null)
  62.                         cSpace.AppendEntity(circle);
  63.                     }
  64.                 }
  65.             }
  66.         }
  67.  
  68.         internal static class SupportMethods
  69.         {
  70.             public static void InitializeVars(out Document adoc, out Editor ed, out Database db)
  71.             {
  72.                 adoc = Application.DocumentManager.MdiActiveDocument;
  73.                 ed = adoc.Editor;
  74.                 db = adoc.Database;
  75.             }
  76.  
  77.             public static ObjectId SelectEntity(Editor ed, string msg = "\nSelect entity: ")
  78.             {
  79.                 PromptEntityResult entRes = ed.GetEntity(msg);
  80.                 return entRes.Status == PromptStatus.OK ? entRes.ObjectId : ObjectId.Null;
  81.             }
  82.  
  83.             public static string GetString(Editor ed, string msg = "\nInput string value: ")
  84.             {
  85.                 PromptResult stringRes = ed.GetString(msg);
  86.                 return stringRes.Status == PromptStatus.OK ? stringRes.StringResult : null;
  87.             }
  88.  
  89.             public static Point3d? GetPoint(Editor ed, string msg = "\nSelect point: ")
  90.             {
  91.                 PromptPointResult ptRes = ed.GetPoint(msg);
  92.                 return ptRes.Status == PromptStatus.OK ? (Point3d?)ptRes.Value : null;
  93.             }
  94.         }
  95.     }
  96. }
  97.  

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

  • ADN Club
  • ****
  • Сообщений: 421
  • Карма: 16
    • Advanced software for AutoCAD
  • Skype: Debalance
Мы не обсуждаем это на данном форуме.
А между тем это ключевая тема для любого программиста. Мы должны чётко понимать исходные возможности среды. Где я могу получить информацию о допусках при работе со сплайнами? И правильно ли я понял из Вашей безапелляционной тезы (что у меня всего лишь один выход), что это не является багом движка AutoCAD, а всего лишь изначально заложенное ограничение?

Механизм сплайнов в AutoCAD не позволяет их использовать в нанотехнологиях
Это Ваше предположение? К тому же насколько я помню нанотехнологии начинаются после точностей 0.000000001 ед.

В .NET API у сплайна есть метод ToPolylineWithPrecision
Ривилис уже предложил аппроксимировать, а это одно и тоже. Рудиментарный метод - вместо математической модели я буду хранить кучу точек с посредственной для "нанотехнологий" точностью.

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

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