找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 668|回复: 8

[分享] 判断点是否在封闭多段线内【转载】

[复制链接]

已领礼包: 104个

财富等级: 日进斗金

发表于 2021-10-21 16:11:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 qq1254582201 于 2021-10-22 10:00 编辑
一、使用多重多边形。使用函数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有待进一步研究。
————————————————
版权声明:本文为CSDN博主「yGIS」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010608964/article/details/82533064
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.BoundaryRepresentation;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.Runtime;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;

  11. namespace IsInPolyline
  12. {
  13.     public class Class1
  14.     {
  15.         
  16.         [CommandMethod("pinpt1")]
  17.         public static void test()
  18.         {
  19.             Document doc = Application.DocumentManager.MdiActiveDocument;
  20.             Database db = doc.Database;
  21.             Editor ed = doc.Editor;

  22.             PromptEntityOptions peo = new PromptEntityOptions("\n选择一条多段线: ");
  23.             peo.SetRejectMessage("Only a polyline !");
  24.             peo.AddAllowedClass(typeof(Polyline), true);
  25.             PromptEntityResult per = ed.GetEntity(peo);
  26.             if (per.Status != PromptStatus.OK)
  27.                 return;

  28.             using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
  29.             {
  30.                 Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
  31.                 PromptPointOptions ppo = new PromptPointOptions("\n拾取一个点 <quit>: ");
  32.                 ppo.AllowNone = true;
  33.                 while (true)
  34.                 {
  35.                     PromptPointResult ppr = ed.GetPoint(ppo);
  36.                     if (ppr.Status != PromptStatus.OK)
  37.                         break;
  38.                     Application.ShowAlertDialog(
  39.                         pline.IsPointInside(ppr.Value) ? "Inside" : "Outside");
  40.                 }
  41.                
  42.             }
  43.         }

  44.         [CommandMethod("pinpt2")]
  45.         public void test2() {
  46.             Document doc = Application.DocumentManager.MdiActiveDocument;
  47.             Database db = doc.Database;
  48.             Editor ed = doc.Editor;

  49.             PromptEntityOptions peo = new PromptEntityOptions("\n选择一条多段线: ");
  50.             peo.SetRejectMessage("Only a polyline !");
  51.             peo.AddAllowedClass(typeof(Polyline), true);
  52.             PromptEntityResult per = ed.GetEntity(peo);
  53.             if (per.Status != PromptStatus.OK)
  54.                 return;
  55.             using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
  56.             {
  57.                  Polyline pline = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
  58.                  if (!pline.Closed)
  59.                  {
  60.                      ed.WriteMessage("\n多段线必须为闭合");
  61.                      return;
  62.                  }
  63.                  DBObjectCollection curves = new DBObjectCollection();
  64.                  curves.Add(pline);
  65.                  try
  66.                  {
  67.                      using (DBObjectCollection regions = Region.CreateFromCurves(curves))
  68.                      using (Region region = (Region)regions[0])
  69.                      {
  70.                           PromptPointOptions ppo = new PromptPointOptions("\nPick a point <quit>: ");
  71.                           ppo.AllowNone = true;
  72.                           while (true)
  73.                           {
  74.                               PromptPointResult ppr = ed.GetPoint(ppo);
  75.                               if (ppr.Status != PromptStatus.OK)
  76.                                   break;
  77.                               Application.ShowAlertDialog(
  78.                                                   GetPointContainment(region, ppr.Value).ToString());
  79.                           }
  80.                      }
  81.                  }
  82.                  catch (System.Exception exn)
  83.                  {

  84.                      ed.WriteMessage("\nError: " + exn.Message);
  85.                  }
  86.             }
  87.         }

  88.         private PointContainment GetPointContainment(Region region, Point3d point)
  89.         {
  90.             PointContainment result = PointContainment.Outside;
  91.             using (Brep brep = new Brep(region))
  92.             {
  93.                 if (brep != null)
  94.                 {
  95.                     using (BrepEntity ent = brep.GetPointContainment(point, out result))
  96.                     {
  97.                         if (ent is Autodesk.AutoCAD.BoundaryRepresentation.Face)
  98.                         {
  99.                             result = PointContainment.Inside;
  100.                         }
  101.                     }
  102.                 }
  103.             }
  104.             return result;
  105.         }
  106.     }
  107. }
以上是原作者的代码。但是方法一缺少了重要的pline.IsPointInside(pt),以下为自己东拼西凑的:IsPointInside(this Polyline pline, Point3d pt)
游客,如果您要查看本帖隐藏内容请回复



论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 58个

财富等级: 招财进宝

发表于 2021-11-21 19:55:30 | 显示全部楼层
感谢分享 学习学习学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3719个

财富等级: 富可敌国

发表于 2021-11-21 22:48:45 | 显示全部楼层
回复看看、学习学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2022-6-11 09:36:00 | 显示全部楼层
学习学习!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复

使用道具 举报

已领礼包: 3个

财富等级: 恭喜发财

发表于 2022-8-15 12:48:30 | 显示全部楼层
谢谢分享很实用
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2022-9-4 22:35:04 | 显示全部楼层
回复看看、学习学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

发表于 2022-12-31 14:03:23 | 显示全部楼层
感谢分享,涨涨见识
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2023-1-7 17:32:16 | 显示全部楼层
感谢分享 学习学习学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2023-6-5 08:02:07 | 显示全部楼层
回复看看、学习学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-19 23:03 , Processed in 0.389075 second(s), 44 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表