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

26/10/2013

Выравнивание примитива по трем точкам

Ниже приведен пример кода, который выравнивает выбранный примитив по трем базовым и трем целевым точкам. Порядок, в котором точки выбираются, показан на картинке. Приведен пример чертежа для проверки кода.

Код - C#: [Выделить]
  1. Document activeDoc = Application.DocumentManager.MdiActiveDocument;
  2. Database db = activeDoc.Database;
  3. Editor ed = activeDoc.Editor;
  4.  
  5. // Запрос выбора примитива
  6. PromptEntityResult per
  7.     = ed.GetEntity(new PromptEntityOptions("Выберите примитив : "));
  8. if (per.Status != PromptStatus.OK)
  9.     return;
  10.  
  11. ObjectId oid = per.ObjectId;
  12.  
  13. Matrix3d ucs2wcs = ed.CurrentUserCoordinateSystem;
  14.  
  15. // Три исходных точки
  16. Point3d srcpt1 = Point3d.Origin;
  17. Point3d srcpt2 = Point3d.Origin;
  18. Point3d srcpt3 = Point3d.Origin;
  19.  
  20. // Три целевых точки
  21. Point3d destpt1 = Point3d.Origin;
  22. Point3d destpt2 = Point3d.Origin;
  23. Point3d destpt3 = Point3d.Origin;
  24.  
  25. // Исходная точка 1
  26. PromptPointResult ppr1
  27.     = ed.GetPoint(new PromptPointOptions("Первая исходная точка"));
  28. if (ppr1.Status != PromptStatus.OK)
  29.     return;
  30. srcpt1 = ppr1.Value.TransformBy(ucs2wcs);
  31.  
  32. // Целевая точка 1
  33. ppr1 = ed.GetPoint(new PromptPointOptions("Первая целевая точка"));
  34. if (ppr1.Status != PromptStatus.OK)
  35.     return;
  36. destpt1 = ppr1.Value.TransformBy(ucs2wcs);
  37.  
  38. // Показываем временную линию для выбранных точек
  39. IntegerCollection coll = new IntegerCollection();
  40. Line tmpline1 = new Line(srcpt1, destpt1);
  41. TransientManager.CurrentTransientManager.AddTransient
  42.    (tmpline1, TransientDrawingMode.DirectShortTerm, 128, coll);
  43.  
  44. // Исходная точка 2
  45. PromptPointResult ppr2
  46.     = ed.GetPoint(new PromptPointOptions("Вторая исходная точка"));
  47. if (ppr2.Status != PromptStatus.OK)
  48.     return;
  49. srcpt2 = ppr2.Value.TransformBy(ucs2wcs);
  50.  
  51. // Целевая точка 2
  52. ppr2 = ed.GetPoint(new PromptPointOptions("Вторая целевая точка"));
  53. if (ppr2.Status != PromptStatus.OK)
  54.     return;
  55. destpt2 = ppr2.Value.TransformBy(ucs2wcs);
  56.  
  57. // Показываем временную линию для выбранных точек
  58. Line tmpline2 = new Line(srcpt2, destpt2);
  59. TransientManager.CurrentTransientManager.AddTransient
  60.     (tmpline2, TransientDrawingMode.DirectShortTerm, 128, coll);
  61.  
  62. // Исходная точка 3
  63. PromptPointResult ppr3
  64.     = ed.GetPoint(new PromptPointOptions("Третья исходная точка"));
  65. if (ppr3.Status != PromptStatus.OK)
  66.     return;
  67. srcpt3 = ppr3.Value.TransformBy(ucs2wcs);
  68.  
  69. // Целевая точка 3
  70. ppr3 = ed.GetPoint(new PromptPointOptions("Третья целевая точка"));
  71. if (ppr3.Status != PromptStatus.OK)
  72.     return;
  73. destpt3 = ppr3.Value.TransformBy(ucs2wcs);
  74.  
  75. // Показываем временную линию для выбранных точек
  76. Line tmpline3 = new Line(srcpt3, destpt3);
  77. TransientManager.CurrentTransientManager.AddTransient
  78.     (tmpline3, TransientDrawingMode.DirectShortTerm, 128, coll);
  79.  
  80. try
  81. {
  82.     Point3d fromOrigin = srcpt1;
  83.     Vector3d fromXaxis = srcpt2 - srcpt1;
  84.     Vector3d fromYaxis = srcpt3 - srcpt1;
  85.     Vector3d fromZaxis = fromXaxis.CrossProduct(fromYaxis);
  86.  
  87.     Point3d toOrigin = destpt1;
  88.     Vector3d toXaxis =
  89.             (destpt2 - destpt1).GetNormal() * fromXaxis.Length;
  90.     Vector3d toYaxis
  91.            = (destpt3 - destpt1).GetNormal() * fromYaxis.Length;
  92.     Vector3d toZaxis = toXaxis.CrossProduct(toYaxis);
  93.  
  94.     // Получаем матрицу преобразования в новую систему координат
  95.     Matrix3d mat = new Matrix3d();
  96.     mat = Matrix3d.AlignCoordinateSystem(
  97.               fromOrigin,
  98.               fromXaxis,
  99.               fromYaxis,
  100.               fromZaxis,
  101.               toOrigin,
  102.               toXaxis,
  103.               toYaxis,
  104.               toZaxis);
  105.  
  106.     // Преобразуем (выравниваем) выбранный примитив
  107.     using (Transaction tr = db.TransactionManager.StartTransaction())
  108.     {
  109.         Entity ent = tr.GetObject(oid, OpenMode.ForWrite) as Entity;
  110.         ent.TransformBy(mat);
  111.         tr.Commit();
  112.     }
  113. }
  114. catch (Autodesk.AutoCAD.Runtime.Exception ex )
  115. {
  116.     ed.WriteMessage(ex.Message);
  117. }
  118. // Удаляем временные линии
  119. TransientManager.CurrentTransientManager.EraseTransient (tmpline1, coll);
  120. tmpline1.Dispose();
  121. TransientManager.CurrentTransientManager.EraseTransient (tmpline2, coll);
  122. tmpline2.Dispose();
  123. TransientManager.CurrentTransientManager.EraseTransient (tmpline3, coll);
  124. tmpline3.Dispose();

Рисунки показывают в каком порядке выбирались точки и повернутый примитив



А это чертеж для примера: Загрузите тестовый файл

Источник: http://adndevblog.typepad.com/autocad/2013/07/aligning-entity-using-3-points.html

 

Обсуждение: http://adn-cis.org/forum/index.php?topic=287

Опубликовано 26.10.2013