找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2718|回复: 7

[原创] 练习 查找自相交Pline

[复制链接]

已领礼包: 859个

财富等级: 财运亨通

发表于 2014-6-27 11:48:35 | 显示全部楼层 |阅读模式

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

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

×

  1.         [CommandMethod("Test")]
  2.         public static void IsPolylineSeftInters()
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             Transaction tr = db.TransactionManager.StartTransaction();

  8.             TypedValue typevalue = new TypedValue((int) DxfCode.Start, "LWPOLYLINE");
  9.             SelectionFilter filter = new SelectionFilter(new TypedValue[1]{typevalue });

  10.             PromptSelectionResult psr = ed.SelectAll( filter );

  11.             if (psr.Status != PromptStatus.OK) return;
  12.             using (tr)
  13.             {
  14.                 try
  15.                 {
  16.                     SelectionSet ss = psr.Value;
  17.                     ObjectId[] ids = ss.GetObjectIds();
  18.                     List<Entity> entLst = new List<Entity>();
  19.                     for (int i = 0; i < ids.Length; i++)
  20.                     {
  21.                         Entity ent = (Entity)ids[i].GetObject(OpenMode.ForRead);
  22.                         if (IsSelfIntersect(ent))
  23.                         {
  24.                             entLst.Add(ent);
  25.                         }
  26.                     }
  27.                     if (entLst.Count > 0)
  28.                     {
  29.                         for (int i = 0; i < entLst.Count; i++)
  30.                         {
  31.                             entLst[i].UpgradeOpen();
  32.                             entLst[i].ColorIndex = 1;
  33.                             entLst[i].Highlight();
  34.                         }
  35.                     }
  36.                     tr.Commit();
  37.                 }
  38.                 catch (Exception)
  39.                 {
  40.                     
  41.                     throw;
  42.                 }
  43.             }
  44.         }
  45.         /// <summary>
  46.         /// 判断Polyline是否自相交
  47.         /// </summary>
  48.         /// <param name="ent">Entity(Pline)</param>
  49.         /// <returns>true or false</returns>
  50.         private static bool IsSelfIntersect(Entity ent)
  51.         {
  52.             Point3dCollection pts = new Point3dCollection();
  53.             ent.IntersectWith(ent, Intersect.OnBothOperands, pts, IntPtr.Zero, IntPtr.Zero);
  54.             Curve pl = ent as Curve;
  55.             Point3d ep = pl.EndPoint;
  56.             double[] pams = new double[pts.Count];
  57.             for (int i = 0; i < pams.Length ; i++)
  58.             {
  59.                 pams[i] = pl.GetParameterAtPoint(pts[i]);
  60.             }
  61.             return (IsGrade(pams) == 1 | EndPointIsOn(ent, ep) | NumberInters( ent,pams)) ? true : false;
  62.         }
  63.         /// <summary>
  64.         /// 交点数是否等于总顶点数 - 2
  65.         /// </summary>
  66.         /// <param name="ent"></param>
  67.         /// <param name="pams"></param>
  68.         /// <returns></returns>
  69.         private static bool NumberInters(Entity ent, double[] pams)
  70.         {
  71.             Curve pl = ent as Curve;
  72.             return Convert .ToInt32( pl.EndParam - 1) != pams.Length;
  73.         }
  74.         /// <summary>
  75.         /// 判断交点数是否等于顶点
  76.         /// </summary>
  77.         /// <param name="pams"></param>
  78.         /// <returns></returns>
  79.         private static int IsGrade(double[] pams)
  80.         {
  81.             var numPlace = pams.SkipWhile( (num, index) => num -1 == index);
  82.             return numPlace.Count() == 0 ? 0:1;
  83.         }
  84.         /// <summary>
  85.         /// 判断端点是否和其它顶点重合
  86.         /// </summary>
  87.         /// <param name="ent">Entity(多义线)</param>
  88.         /// <param name="p">端点</param>
  89.         /// <returns>重合 true</returns>
  90.         private static bool EndPointIsOn(Entity ent, Point3d p)
  91.         {
  92.             Curve pl = ent as Curve;
  93.             int n = Convert.ToInt32(pl.EndParam);
  94.             bool ret = false ;
  95.             for (int i = 0; i < n-1; i++)
  96.             {
  97.                 if (pl.GetPointAtParameter(Convert .ToDouble( i)).Equals(p))
  98.                 {
  99.                     ret = true;
  100.                     break;
  101.                 }
  102.             }
  103.             return ret;
  104.         }
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-6-27 12:51:12 来自手机 | 显示全部楼层
本帖最后由 csharp 于 2014-6-27 13:02 编辑

三个条件
1 交点数量等于顶点数 - 2
2 交点的参数等于索引值
3 Endpoint单独判断不和任意顶点重合

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

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-6-27 15:21:04 | 显示全部楼层
知道了自交点的判别和交点参数就可以写在自交点处断开了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

使用道具 举报

发表于 2014-6-29 08:27:37 | 显示全部楼层
这里面 using try … Highlight tr.Commit(); 无法完成亮显

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

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-7-3 09:22:40 | 显示全部楼层
判断端点和其它顶点重合循环应该是 i=1, i < n -2, i++
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 859个

财富等级: 财运亨通

 楼主| 发表于 2014-7-10 16:47:11 | 显示全部楼层
本帖最后由 csharp 于 2014-7-10 18:51 编辑

用 CurveCurveIntersector3d 计算更简单快捷,GetIntersectionParameters 返回的不是 Pamram ,是距离起点的距离值(GetDistAtPoint)

  1.         [CommandMethod("MyGroup", "MyCommand", "MyCommandLocal", CommandFlags.Modal)]
  2.         public void MyCommand() // This method can have any name
  3.         {
  4.             Document doc = Application.DocumentManager.MdiActiveDocument;
  5.             Editor ed = doc.Editor;
  6.             Database db = doc.Database;
  7.             Transaction tr = db.TransactionManager.StartTransaction();
  8.             PromptEntityResult per = ed.GetEntity("\nPick Polyline");
  9.             if (per.Status != PromptStatus.OK) return;
  10.             ObjectId plid = per.ObjectId;
  11.             using (tr)
  12.             {
  13.                 try
  14.                 {
  15.                     Curve cv = (Curve) plid.GetObject(OpenMode.ForRead);
  16.                     Plane plan = cv.GetPlane();
  17.                     Vector3d vv = plan.Normal;
  18.                     Curve3d c3d = cv.GetGeCurve();
  19.                     CurveCurveIntersector3d ccid = new CurveCurveIntersector3d(c3d,c3d,vv);
  20.                     for (int i = 0; i < ccid.NumberOfIntersectionPoints; i++)
  21.                     {
  22.                         double[] pams = ccid.GetIntersectionParameters(i);
  23.                         for (int j = 0; j < pams.Length ; j++)
  24.                         {
  25.                             ed.WriteMessage("\n" + pams[j].ToString());
  26.                         }
  27.                         
  28.                     }
  29.                 }
  30.                 catch (Exception)
  31.                 {
  32.                     
  33.                     throw;
  34.                 }
  35.             }
  36.         }

没有自交点时 ccid.NumberOfIntersectionPoints 为 0 !

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-19 02:02 , Processed in 0.420012 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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