AutoCAD二次开发&判断点是否在多边形内部

这次来学习一下关于点是否在多段线内部,首先要说明一下的是,该多段线为闭合的多段线。下面使用两种方法:

一、使用多重多边形。使用函数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;
        }
    }
}

                                                             更多内容,微信扫二维码关注公众号

                                                              


 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值