Как определить положение StartPoint для Arc?

Автор Тема: Как определить положение StartPoint для Arc?  (Прочитано 7066 раз)

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

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вопрос: Как определить положение StartPoint для Arc созданой методом:
Public Sub New(center As Autodesk.AutoCAD.Geometry.Point3d, normal As Autodesk.AutoCAD.Geometry.Vector3d, radius As Double, startAngle As Double, endAngle As Double)
Ответ:
Вот пара вариантов для получения информации о начале/конце дуги:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using AcRx = Autodesk.AutoCAD.Runtime;
  8. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcGe = Autodesk.AutoCAD.Geometry;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12.  
  13. [assembly: CommandClass(typeof(TestArc.MyCommands))]
  14.  
  15. namespace TestArc
  16. {
  17.  
  18.   public class MyCommands
  19.   {
  20.     [CommandMethod("TestArc")]
  21.     public void TestArc()
  22.     {
  23.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  24.       AcEd.Editor ed = doc.Editor;
  25.       AcEd.PromptEntityOptions pr =
  26.         new AcEd.PromptEntityOptions("\nУкажите дугу (ARC) для получения начала и конца (ENTER - завершение): ");
  27.       pr.SetRejectMessage("Это не дуга (ARC). Повторите!");
  28.       pr.AddAllowedClass(typeof(AcDb.Arc),true);
  29.       AcEd.PromptEntityResult res;
  30.       while ((res = ed.GetEntity(pr)).Status == AcEd.PromptStatus.OK)
  31.       {
  32.         AcDb.ObjectId id = res.ObjectId;
  33.         using (AcDb.Arc arc = id.Open(AcDb.OpenMode.ForRead) as AcDb.Arc)
  34.         {
  35.           // Первый вариант получения начала/конца дуги
  36.           ed.WriteMessage("\nStartPoint1 = ({0}) Endpoint1 = ({1}) ",
  37.             arc.StartPoint, arc.EndPoint);
  38.           // Второй вариант получения начала/конца дуги
  39.           ed.WriteMessage("\nStartPoint2 = ({0}) Endpoint2 = ({1}) ",
  40.             arc.GetPointAtParameter(arc.StartParam), arc.GetPointAtParameter(arc.EndParam));
  41.         }
  42.       }
  43.     }
  44.   }
  45. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Код - Visual Basic [Выбрать]
  1.             Dim V1, V2 As Vector3d
  2.             V1 = nP - centrP
  3.             V2 = nVP2.GetPerpendicularVector
  4.             Dim dAngl As Double = V1.GetAngleTo(V2)
  5.             Dim nArc As New Arc(centrP, nVP2, wSegm.radius, dAngl, dAngl + wSegm.beta)

где dAngl - угол между nP и nArc.StartPoint

Получается nArc.StartPoint = CentrV.Add(nVP2.GetPerpendicularVector)
« Последнее редактирование: 21-09-2014, 22:22:43 от trir »

Оффлайн Александр РивилисАвтор темы

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

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Задача, в том, что нужно построить дугу от известной точки, но когда я этим методом её строю, мне нужно знать угол между StartPoint дуги и моей точкой, причём желательно до построения дуги, что бы "довернуть" её на мою точку

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Из этого объяснения мне не стало понятнее. Я понял, что у тебя есть начальная точка дуги. Что есть еще? Радиус? Центр? Конечная точка? Промежуточная точка? Что?
Можно построить дугу по двум точкам и центру, или по начальной конечной и промежуточной точке.
« Последнее редактирование: 19-09-2014, 23:37:54 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр РивилисАвтор темы

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Может это тебе поможет больше:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using AcRx = Autodesk.AutoCAD.Runtime;
  8. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcGe = Autodesk.AutoCAD.Geometry;
  11. using AcEd = Autodesk.AutoCAD.EditorInput;
  12.  
  13. [assembly: CommandClass(typeof(TestArc.MyCommands))]
  14.  
  15. namespace TestArc
  16. {
  17.   public class MyCommands
  18.   {
  19.     /// <summary>
  20.     ///  Функция на основе CircularArc3d создаёт Arc
  21.     /// </summary>
  22.     /// <param name="circArc"></param>
  23.     /// <returns></returns>
  24.     AcDb.Arc circArc3Arc(CircularArc3d circArc)
  25.     {
  26.       AcGe.Point3d center = circArc.Center;
  27.       AcGe.Vector3d normal = circArc.Normal;
  28.       AcGe.Vector3d refVec = circArc.ReferenceVector;
  29.       AcGe.Plane plane = new Plane(center, normal);
  30.       double ang = refVec.AngleOnPlane(plane);
  31.       return new AcDb.Arc(
  32.         center,
  33.         normal,
  34.         circArc.Radius,
  35.         circArc.StartAngle + ang,
  36.         circArc.EndAngle + ang
  37.       );
  38.     }
  39.     /// <summary>
  40.     /// Построение дуги по конечным точкам и точке центра
  41.     /// </summary>
  42.     [CommandMethod("TestArc1")]
  43.     public void TestArc1()
  44.     {
  45.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  46.       AcEd.Editor ed = doc.Editor;
  47.       AcEd.PromptPointOptions pr1 =
  48.         new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
  49.       AcEd.PromptPointOptions pr2 =
  50.         new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
  51.       AcEd.PromptPointOptions prc =
  52.         new AcEd.PromptPointOptions("\nУкажите точку центра дуги: ");
  53.       AcEd.PromptPointResult res1, res2, resc;
  54.       if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
  55.           (res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
  56.           (resc = ed.GetPoint(prc)).Status != AcEd.PromptStatus.OK)
  57.         return;
  58.       AcGe.Point3d p1 = res1.Value, p2 = res2.Value, pc = resc.Value;
  59.       double radius = (p1.DistanceTo(pc) + p2.DistanceTo(pc)) * 0.5;
  60.       AcGe.Point3d pMid = p1 + (p2 - p1) * 0.5;
  61.       pMid = pc + (pc - pMid).GetNormal() * radius;
  62.       AcGe.CircularArc3d arc3 = new AcGe.CircularArc3d(p1, pMid, p2);
  63.       using (AcDb.Arc arc = circArc3Arc(arc3))
  64.       {
  65.         using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  66.         {
  67.           btr.AppendEntity(arc);
  68.         }
  69.       }
  70.     }
  71.     /// <summary>
  72.     /// Построение дуги по конечным точкам и промежуточной точке на дуге
  73.     /// </summary>
  74.     [CommandMethod("TestArc2")]
  75.     public void TestArc2()
  76.     {
  77.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  78.       AcEd.Editor ed = doc.Editor;
  79.       AcEd.PromptPointOptions pr1 =
  80.         new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
  81.       AcEd.PromptPointOptions pr2 =
  82.         new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
  83.       AcEd.PromptPointOptions prm =
  84.         new AcEd.PromptPointOptions("\nУкажите промежуточную на дуге: ");
  85.       AcEd.PromptPointResult res1, res2, resm;
  86.       if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
  87.           (res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
  88.           (resm = ed.GetPoint(prm)).Status != AcEd.PromptStatus.OK)
  89.         return;
  90.       AcGe.Point3d p1 = res1.Value, p2 = res2.Value, pMid = resm.Value;
  91.       if (p1.DistanceTo(pMid) + p2.DistanceTo(pMid) <= p1.DistanceTo(p2))
  92.       {
  93.         ed.WriteMessage("\nПо этим данным нельзя построить дугу!");
  94.         return;
  95.       }
  96.       AcGe.CircularArc3d arc3 = new AcGe.CircularArc3d(p1, pMid, p2);
  97.       using (AcDb.Arc arc = circArc3Arc(arc3))
  98.       {
  99.         using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  100.         {
  101.           btr.AppendEntity(arc);
  102.         }
  103.       }
  104.     }
  105.     /// <summary>
  106.     /// Построение дуги по конечным точкам и радиусу
  107.     /// </summary>
  108.     [CommandMethod("TestArc3")]
  109.     public void TestArc3()
  110.     {
  111.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  112.       AcEd.Editor ed = doc.Editor;
  113.       AcEd.PromptPointOptions pr1 =
  114.         new AcEd.PromptPointOptions("\nУкажите точку начала дуги: ");
  115.       AcEd.PromptPointOptions pr2 =
  116.         new AcEd.PromptPointOptions("\nУкажите точку конца дуги: ");
  117.       AcEd.PromptDistanceOptions prc =
  118.         new AcEd.PromptDistanceOptions("\nУкажите радиус дуги: ");
  119.       AcEd.PromptPointResult res1, res2;
  120.       AcEd.PromptDoubleResult resc;
  121.       if ((res1 = ed.GetPoint(pr1)).Status != AcEd.PromptStatus.OK ||
  122.           (res2 = ed.GetPoint(pr2)).Status != AcEd.PromptStatus.OK ||
  123.           (resc = ed.GetDistance(prc)).Status != AcEd.PromptStatus.OK)
  124.         return;
  125.       AcGe.Point3d p1 = res1.Value, p2 = res2.Value;
  126.       double radius = resc.Value;
  127.       if (radius <= p1.DistanceTo(p2) * 0.5)
  128.       {
  129.         ed.WriteMessage("\nПо этим данным нельзя построить дугу!");
  130.         return;
  131.       }
  132.       AcGe.Vector3d norm = AcGe.Vector3d.ZAxis;
  133.       AcGe.CircularArc3d a1 = new AcGe.CircularArc3d(p1, norm, radius);
  134.       AcGe.CircularArc3d a2 = new AcGe.CircularArc3d(p2, norm, radius);
  135.       AcGe.CurveCurveIntersector3d cint = new AcGe.CurveCurveIntersector3d(a1, a2, norm);
  136.       // Одно пересечение быть не может, так это значит
  137.       // что все точки лежат на одной прямой.
  138.       if (cint.NumberOfIntersectionPoints == 2) {
  139.         AcGe.Point3d pc1 = cint.GetIntersectionPoint(0);
  140.         AcGe.Point3d pc2 = cint.GetIntersectionPoint(1);
  141.         AcGe.CircularArc3d arc31 = new AcGe.CircularArc3d(p1, pc1, p2);
  142.         AcGe.CircularArc3d arc32 = new AcGe.CircularArc3d(p1, pc2, p2);
  143.         using (AcDb.Arc arc1 = circArc3Arc(arc31)) using (AcDb.Arc arc2 = circArc3Arc(arc32))
  144.         {
  145.           using (AcDb.BlockTableRecord btr = doc.Database.CurrentSpaceId.Open(AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord)
  146.           {
  147.             if (arc1.StartPoint.DistanceTo(p1) < arc2.StartPoint.DistanceTo(p1))
  148.               btr.AppendEntity(arc1);
  149.             else
  150.               btr.AppendEntity(arc2);
  151.           }
  152.         }
  153.       }
  154.     }
  155.   }
  156. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Смотрю Александр Наумович разошёлся-то... :) Ну тогда вот ещё один, на этот раз несколько "экзотический" способ. :)

Оффлайн Александр РивилисАвтор темы

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

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
А чем эта экзотика поможет trir создать дугу по (одному ему) известным начальным условиям?
Она к теме относиться лишь той частью, что на выходе формирует дугу (своего рода машина Голдберга). Это было что-то вроде "шутки-юмора", если вы не поняли :) А если серьёзно, то я так и не понял, чего хочет trir, ежели уж его не устраивает приведённые вами выше разжёванные варианты...

Оффлайн Александр РивилисАвтор темы

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

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
В том коде, что я привёл - мне известны все переменные, кроме dAngl, который я в коде и определяю
Я просто думал, что можно похимичить с исходными данными, чтобы получить StartPoint в нужном месте, но это оказалось ошибкой и я решил проблему через dAngl

Оффлайн Александр РивилисАвтор темы

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

Оффлайн trir

  • ADN Club
  • ****
  • Сообщений: 470
  • Карма: 63
Да