Пересечение между плоскостью и кривой в .NET
Вот шаги, которые позволят найти точки пересечения между плоскостью и кривой (на основе объяснения данного моим коллегой Krishnamurthy Kalvai) . Я представляю образец кода, который реализует эти шаги, чтобы найти пересечение эллипса и плоскости.
1. Определяем не лежит ли кривая на плоскости. Можно получить плоскость кривой используя метод Curve.GetPlane(). Проверяем не совпадают ли (или не параллельны ли) плоскости с помощью метода Plane.IntersectWith().
Если плоскости параллельны, то бесконечное число точек пересечения или нет точек пересечения. В этом случае мы можем остановится и не переходить к шагу 2.
2. Проецируем кривую на плоскость, используя метод Curve.GetProjectedCurve().
3. Находим пересечение между спроецированной кривой и оригинальной кривой используя метод IntersectWith(). Точки пересечения должны быть именно те же, что и при пересечении плоскости и кривой.
4. Для итоговой проверки посмотрим, лежит ли точка на плоскости, используя Plane.isOn()
- [CommandMethod("PlaneCurveIntersection")]
- public static void PlaneCurveIntersection()
- {
- Document activeDoc
- = Application.DocumentManager.MdiActiveDocument;
- Database db = activeDoc.Database;
- Editor ed = activeDoc.Editor;
- // Создаём плоскую область и эллипс
- ObjectId regionId = ObjectId.Null;
- ObjectId ellipseId = ObjectId.Null;
- using (Transaction tr
- = db.TransactionManager.StartTransaction())
- {
- BlockTable bt = tr.GetObject(
- db.BlockTableId,
- OpenMode.ForRead
- ) as BlockTable;
- BlockTableRecord modelSpace = tr.GetObject
- (
- bt[BlockTableRecord.ModelSpace],
- OpenMode.ForWrite
- ) as BlockTableRecord;
- Autodesk.AutoCAD.DatabaseServices.Polyline polyline
- = new Autodesk.AutoCAD.DatabaseServices.Polyline();
- polyline.Closed = true;
- polyline.AddVertexAt
- (
- 0,
- new Point2d(10.0, -10.0),
- 0.0,
- 0.0,
- 0.0
- );
- polyline.AddVertexAt
- ( 1,
- new Point2d(10.0, 10.0),
- 0.0,
- 0.0,
- 0.0
- );
- polyline.AddVertexAt
- ( 2,
- new Point2d(-10.0, 10.0),
- 0.0,
- 0.0,
- 0.0
- );
- polyline.AddVertexAt
- (
- 3,
- new Point2d(-10.0, -10.0),
- 0.0,
- 0.0,
- 0.0
- );
- DBObjectCollection coll = new DBObjectCollection();
- coll.Add(polyline);
- DBObjectCollection rgnColl
- = Region.CreateFromCurves(coll);
- if (rgnColl.Count > 0)
- {
- Region rgn = rgnColl[0] as Region;
- regionId = modelSpace.AppendEntity(rgn);
- tr.AddNewlyCreatedDBObject(rgn, true);
- }
- Vector3d ellipseNormal
- = Vector3d.ZAxis.RotateBy(
- 45.0 * Math.PI / 180.0,
- Vector3d.XAxis
- );
- Vector3d ellipseMajorAxis = new Vector3d(0, 5, 0);
- ellipseMajorAxis
- = ellipseMajorAxis.RotateBy
- (
- 45.0 * Math.PI / 180.0,
- Vector3d.XAxis
- );
- Ellipse ellipse = new Ellipse
- (
- Point3d.Origin,
- ellipseNormal,
- ellipseMajorAxis,
- 0.5,
- 0,
- 0
- );
- ellipseId = modelSpace.AppendEntity(ellipse);
- tr.AddNewlyCreatedDBObject(ellipse, true);
- tr.Commit();
- }
- // Находим пересечение кривой и плоскости
- using (Transaction tr
- = db.TransactionManager.StartTransaction())
- {
- Region rgn = tr.GetObject
- (
- regionId,
- OpenMode.ForRead
- ) as Region;
- DBObjectCollection exploded = new DBObjectCollection();
- rgn.Explode(exploded);
- Entity firstEntity = exploded[0] as Entity;
- Plane intersectionPlane = firstEntity.GetPlane();
- Curve curve = tr.GetObject
- (
- ellipseId,
- OpenMode.ForRead
- ) as Curve;
- Plane curvePlane = curve.GetPlane();
- if (curvePlane.IsCoplanarTo(intersectionPlane))
- {
- ed.WriteMessage("\nБесконечное пересечение – плоскости совпали !");
- }
- else if (curvePlane.IsParallelTo(intersectionPlane))
- {
- ed.WriteMessage("\nНет пересечения !");
- }
- else
- {
- Curve projectedCurve
- = curve.GetProjectedCurve
- (
- intersectionPlane,
- intersectionPlane.Normal
- );
- Point3dCollection intPts = new Point3dCollection();
- projectedCurve.IntersectWith
- (
- curve,
- Intersect.OnBothOperands, // В исходном коде была ошибка: Intersect.ExtendBoth
- intPts,
- IntPtr.Zero,
- IntPtr.Zero
- );
- foreach (Point3d pt in intPts)
- {
- if (curvePlane.IsOn(pt))
- {
- ed.WriteMessage
- (
- string.Format(
- "{0}{1}",
- Environment.NewLine,
- pt.ToString()
- )
- );
- }
- }
- }
- tr.Commit();
- }
- }
Источник: 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