这次来学习一下关于点是否在多段线内部,首先要说明一下的是,该多段线为闭合的多段线。下面使用两种方法:
一、使用多重多边形。使用函数AppendLoopFromBoundary(pline, true, tolerance)传入多段线范围线和容差创建多重多边形,然后根据函数IsPointInsideMPolygon((point, tolerance). Count返回值是否为1来判断是否在多段线内部。
二、使用Region和Brep,几乎所有的实体都适用于Region,通过Region.CreateFromCurves(curves)来创建Region,然后传入到Brep中,利用GetPointContainment(point, out result)返回的BrepEntity来判断是否是
Autodesk.AutoCAD.BoundaryRepresentation.Face,如果是,则最终为多段线内。
当然这里的解释表现得抽象了些,大家可以通过阅读代码来了解细节方面流程。值得注意的是在使用上面的函数时,必须导入acdbmgdbrep、AcMPolygonMGD两个dll动态链接库。可以说MPolygon具有一定的拓扑运算能力,可以弥补AutoCAD在几何拓扑运算方面的小小缺陷。当然了更多MPolygon有待进一步研究。
具体代码如下:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.BoundaryRepresentation;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IsInPolyline
{
public class Class1
{
[CommandMethod("pinpt1")]
public static void test()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("\n选择一条多段线: ");
peo.SetRejectMessage("Only a polyline !");
peo.AddAllowedClass(typeof(Polyline), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
{
Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
PromptPointOptions ppo = new PromptPointOptions("\n拾取一个点 <quit>: ");
ppo.AllowNone = true;
while (true)
{
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
break;
Application.ShowAlertDialog(
pline.IsPointInside(ppr.Value) ? "Inside" : "Outside");
}
}
}
[CommandMethod("pinpt2")]
public void test2() {
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptEntityOptions peo = new PromptEntityOptions("\n选择一条多段线: ");
peo.SetRejectMessage("Only a polyline !");
peo.AddAllowedClass(typeof(Polyline), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status != PromptStatus.OK)
return;
using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
{
Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
if (!pline.Closed)
{
ed.WriteMessage("\n多段线必须为闭合");
return;
}
DBObjectCollection curves = new DBObjectCollection();
curves.Add(pline);
try
{
using (DBObjectCollection regions = Region.CreateFromCurves(curves))
using (Region region = (Region)regions[0])
{
PromptPointOptions ppo = new PromptPointOptions("\nPick a point <quit>: ");
ppo.AllowNone = true;
while (true)
{
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK)
break;
Application.ShowAlertDialog(
GetPointContainment(region, ppr.Value).ToString());
}
}
}
catch (System.Exception exn)
{
ed.WriteMessage("\nError: " + exn.Message);
}
}
}
private PointContainment GetPointContainment(Region region, Point3d point)
{
PointContainment result = PointContainment.Outside;
using (Brep brep = new Brep(region))
{
if (brep != null)
{
using (BrepEntity ent = brep.GetPointContainment(point, out result))
{
if (ent is Autodesk.AutoCAD.BoundaryRepresentation.Face)
{
result = PointContainment.Inside;
}
}
}
}
return result;
}
}
}
更多内容,微信扫二维码关注公众号