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

29/05/2013

Пересечение между плоскостью и кривой в .NET

Вот шаги, которые позволят найти точки пересечения между плоскостью и кривой (на основе объяснения данного моим коллегой Krishnamurthy Kalvai) . Я представляю образец кода, который реализует эти шаги, чтобы найти пересечение эллипса и плоскости.

1. Определяем не лежит ли кривая на плоскости. Можно получить плоскость кривой используя метод Curve.GetPlane(). Проверяем не совпадают ли (или не параллельны ли) плоскости с помощью метода Plane.IntersectWith().

Если плоскости параллельны, то бесконечное число точек пересечения или нет точек пересечения. В этом случае мы можем остановится и не переходить к шагу 2.

2. Проецируем кривую на плоскость, используя метод Curve.GetProjectedCurve().

3. Находим пересечение между спроецированной кривой и оригинальной кривой используя метод IntersectWith(). Точки пересечения должны быть именно те же, что и при пересечении плоскости и кривой.

4. Для итоговой проверки посмотрим, лежит ли точка на плоскости, используя Plane.isOn()

Код - C#: [Выделить]
  1. [CommandMethod("PlaneCurveIntersection")]
  2. public static void PlaneCurveIntersection()
  3. {
  4.     Document activeDoc
  5.         = Application.DocumentManager.MdiActiveDocument;
  6.     Database db = activeDoc.Database;
  7.     Editor ed = activeDoc.Editor;
  8.  
  9.     // Создаём плоскую область и эллипс
  10.     ObjectId regionId = ObjectId.Null;
  11.     ObjectId ellipseId = ObjectId.Null;
  12.     using (Transaction tr
  13.                 = db.TransactionManager.StartTransaction())
  14.     {
  15.         BlockTable bt = tr.GetObject(
  16.                                         db.BlockTableId,
  17.                                         OpenMode.ForRead
  18.                                     ) as BlockTable;
  19.  
  20.         BlockTableRecord modelSpace = tr.GetObject
  21.                         (
  22.                             bt[BlockTableRecord.ModelSpace],
  23.                             OpenMode.ForWrite
  24.                         ) as BlockTableRecord;
  25.  
  26.         Autodesk.AutoCAD.DatabaseServices.Polyline polyline
  27.             = new Autodesk.AutoCAD.DatabaseServices.Polyline();
  28.  
  29.         polyline.Closed = true;
  30.         polyline.AddVertexAt
  31.                     (
  32.                         0,
  33.                         new Point2d(10.0, -10.0),
  34.                         0.0,
  35.                         0.0,
  36.                         0.0
  37.                     );
  38.         polyline.AddVertexAt
  39.                     (    1,
  40.                         new Point2d(10.0, 10.0),
  41.                         0.0,
  42.                         0.0,
  43.                         0.0
  44.                     );
  45.         polyline.AddVertexAt
  46.                     (    2,
  47.                         new Point2d(-10.0, 10.0),
  48.                         0.0,
  49.                         0.0,
  50.                         0.0
  51.                     );
  52.         polyline.AddVertexAt
  53.                     (
  54.                         3,
  55.                         new Point2d(-10.0, -10.0),
  56.                         0.0,
  57.                         0.0,
  58.                         0.0
  59.                     );
  60.         DBObjectCollection coll = new DBObjectCollection();
  61.         coll.Add(polyline);
  62.         DBObjectCollection rgnColl
  63.                                 = Region.CreateFromCurves(coll);
  64.         if (rgnColl.Count > 0)
  65.         {
  66.             Region rgn = rgnColl[0] as Region;
  67.             regionId = modelSpace.AppendEntity(rgn);
  68.             tr.AddNewlyCreatedDBObject(rgn, true);
  69.         }
  70.         Vector3d ellipseNormal
  71.             = Vector3d.ZAxis.RotateBy(
  72.                                         45.0 * Math.PI / 180.0,
  73.                                         Vector3d.XAxis
  74.                                      );
  75.         Vector3d ellipseMajorAxis = new Vector3d(0, 5, 0);
  76.         ellipseMajorAxis
  77.             = ellipseMajorAxis.RotateBy
  78.                                     (
  79.                                         45.0 * Math.PI / 180.0,
  80.                                         Vector3d.XAxis
  81.                                     );
  82.         Ellipse ellipse = new Ellipse
  83.                                     (
  84.                                         Point3d.Origin,
  85.                                         ellipseNormal,
  86.                                         ellipseMajorAxis,
  87.                                         0.5,
  88.                                         0,
  89.                                         0
  90.                                     );
  91.         ellipseId = modelSpace.AppendEntity(ellipse);
  92.         tr.AddNewlyCreatedDBObject(ellipse, true);
  93.         tr.Commit();
  94.     }
  95.  
  96.     // Находим пересечение кривой и плоскости
  97.     using (Transaction tr
  98.             = db.TransactionManager.StartTransaction())
  99.     {
  100.         Region rgn = tr.GetObject
  101.                                 (
  102.                                     regionId,
  103.                                     OpenMode.ForRead
  104.                                 ) as Region;
  105.         DBObjectCollection exploded = new DBObjectCollection();
  106.         rgn.Explode(exploded);
  107.         Entity firstEntity = exploded[0] as Entity;
  108.         Plane intersectionPlane = firstEntity.GetPlane();
  109.         Curve curve = tr.GetObject
  110.                                 (
  111.                                     ellipseId,
  112.                                     OpenMode.ForRead
  113.                                 ) as Curve;
  114.         Plane curvePlane = curve.GetPlane();
  115.         if (curvePlane.IsCoplanarTo(intersectionPlane))
  116.         {
  117.             ed.WriteMessage("\nБесконечное пересечение – плоскости совпали !");
  118.         }
  119.         else if (curvePlane.IsParallelTo(intersectionPlane))
  120.         {
  121.             ed.WriteMessage("\nНет пересечения !");
  122.         }
  123.         else
  124.         {
  125.             Curve projectedCurve
  126.                 = curve.GetProjectedCurve
  127.                                     (
  128.                                         intersectionPlane,
  129.                                         intersectionPlane.Normal
  130.                                     );
  131.             Point3dCollection intPts = new Point3dCollection();
  132.             projectedCurve.IntersectWith
  133.                                     (
  134.                                         curve,
  135.                                         Intersect.OnBothOperands, // В исходном коде была ошибка: Intersect.ExtendBoth
  136.                                         intPts,
  137.                                         IntPtr.Zero,
  138.                                         IntPtr.Zero
  139.                                     );
  140.             foreach (Point3d pt in intPts)
  141.             {
  142.                 if (curvePlane.IsOn(pt))
  143.                 {
  144.                     ed.WriteMessage
  145.                                 (
  146.                         string.Format(
  147.                                         "{0}{1}",
  148.                                         Environment.NewLine,
  149.                                         pt.ToString()
  150.                                      )
  151.                                 );
  152.                 }
  153.             }
  154.         }
  155.         tr.Commit();
  156.     }
  157. }

 

Источник: http://adndevblog.typepad.com/autocad/2012/05/intersection-between-plane-and-a-curve.html

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

Автор перевода: Александр Ривилис
Опубликовано 29.05.2013
Отредактировано 29.08.2016 в 16:14:05