007集—— 自动获取图形的外边界(外轮廓)(CAD—C#二次开发入门)

本文只适用于闭合多段线组成的图像,其他情况(圆、弧、椭圆、未封闭line)暂不支持。

效果如下图所示:

原始图:

代码运行后图:

附代码:

cs 复制代码
 public class 外轮廓
 {
     Database db = HostApplicationServices.WorkingDatabase;
     [CommandMethod("xx")]
     public void Demo()
     {
         try
         {
             //ObjectId obj =  db.GetCenterPl();
             // return;
             // List<DBText> dbtext = db.SelectEntities<DBText>();
             // return;
             // db.GetEntities(out List<Curve> curve, "aa");
             // return;
             if (!db.GetEntities(out List<Curve> curve, "框选识别外轮廓的图像"))
                 return;
             List<Line> lines = new List<Line>();
             foreach (var item in curve)
             {
                 if (item is Line) lines.Add(item as Line);
                 else if (item is Polyline pl)
                 {
                     List<Curve> cus = PmPolyLineMethod.ExplodePolyLine(pl);
                     foreach (var cu in cus)
                     {
                         if (cu is Line) lines.Add(cu as Line);
                     }
                 }
             }
             //lines.ForEach(line => line.ColorIndex = 1);
             //foreach (var item in lines)
             //{
             //    db.AddEntityToModeSpace(item);
             //}

             //return;
             Dictionary<Line, List<Point3d>> pointsOnLine = new Dictionary<Line, List<Point3d>>();
             foreach (var item in lines)
             {
                 pointsOnLine.Add(item, new List<Point3d>());
             }
             for (int i = 0; i < lines.Count - 1; i++)
             {
                 for (int j = i + 1; j < lines.Count; j++)
                 {
                     Point3dCollection pos = new Point3dCollection();
                     lines[i].IntersectWith(lines[j], Intersect.OnBothOperands, pos, IntPtr.Zero, IntPtr.Zero);
                     if (pos.Count > 0)
                     {
                         foreach (Point3d item in pos)
                         {
                             pointsOnLine[lines[i]].Add(item);
                             pointsOnLine[lines[j]].Add(item);
                         }
                     }
                 }
             }
             lines.Clear();
             foreach (var item in pointsOnLine)
             {
                 Line line = item.Key;
                 List<Point3d> points = item.Value;
                 if (points.Count == 0)
                 {
                     lines.Add(line);
                 }
                 else
                 {
                     if (points.Count > 1)
                     {
                         points = points.OrderBy(x => line.GetParameterAtPoint(x)).ToList();//点排序
                     }
                     Point3dCollection pos = new Point3dCollection();
                     points.ForEach(x => pos.Add(x));//点集合加点
                     DBObjectCollection dbs = line.GetSplitCurves(pos);//打断线
                     foreach (var dbobject in dbs)
                     {
                         if (dbobject is Line)
                         {
                             lines.Add(dbobject as Line);//最终线段list
                         }
                     }
                 }
             }
             //lines.ForEach(line => line.ColorIndex = 1);
             //lines.ForEach(line => db.AddEntityToModeSpace(line));
             //return;
             if (!PmPolyLineMethod.GetPoint(out Point3d point, "请选择外面一点")) return;
             Line firstLine = lines.OrderBy(x => x.GetClosestPointTo(point, false).DistanceTo(point)).First();
             //firstLine.ColorIndex = 1;
             //db.AddEntityToModeSpace(firstLine);
             //return;
             lines.Remove(firstLine);
             Polyline polyline = new Polyline();
             polyline.AddVertexAt(0, firstLine.StartPoint.Convert2d(new Plane()), 0, 0, 0);
             polyline.AddVertexAt(1, firstLine.EndPoint.Convert2d(new Plane()), 0, 0, 0);
             Vector3d v1 = firstLine.StartPoint - point;
             Vector3d v2 = firstLine.EndPoint - point;
             if (v1.CrossProduct(v2).Z > 0) polyline.ReverseCurve();
             //polyline.ColorIndex = 1;
             //db.AddEntityToModeSpace(polyline);
             //return;
             while (true)
             {
                 List<Line> tmps = new List<Line>();
                 foreach (var item in lines)
                 {
                     if (item.StartPoint == polyline.EndPoint)
                     {
                         tmps.Add(item);
                     }

                     else if (item.EndPoint == polyline.EndPoint)
                     {
                         item.ReverseCurve();
                         tmps.Add(item);
                     }
                 }
                 if (tmps.Count == 0) break;
                 Vector3d vector = -polyline.GetFirstDerivative(polyline.EndPoint);//顺时针
                 double maxAngle = 0;
                 Line bigLine = new Line();
                 foreach (var item in tmps)//
                 {
                     double angle = vector.GetAngleTo(item.Delta, -Vector3d.ZAxis);
                     if (angle > maxAngle)
                     {
                         maxAngle = angle;
                         bigLine = item;
                     }
                 }
                 polyline.JoinEntity(bigLine);
                 lines.Remove(bigLine);
                 if (polyline.EndPoint == polyline.StartPoint) break;
             }
             polyline.ColorIndex = 1;
             db.AddEntityToModeSpace(polyline);
             return;
         }

         catch (System.Exception)
         {
             throw;
         }

     }
 }

说明:db.GetEntities 等函数为本博封装函数。获取联系下方↓↓↓

相关推荐
倔强的石头10617 分钟前
kingbase备份与恢复实战(六)—— 备份自动化与保留策略:Windows任务计划+日志追溯
运维·windows·自动化
FL162386312934 分钟前
基于yolo26实现的免安装环境windows版一键训练工具
windows
游乐码40 分钟前
c#特殊语法
开发语言·c#
.NET修仙日记1 小时前
2026 .NET 面试八股文:高频题 + 答案 + 原理(高级核心篇)
面试·职场和发展·c#·.net·.net core·.net 8
YJlio1 小时前
8.2Windows 11 如何用 Xbox Game Bar 实时监测电脑性能?CPU、内存、GPU、显存与 FPS 瓶颈判断教程
windows·笔记·学习·chatgpt·架构·电脑·xbox
雪度娃娃2 小时前
创建型设计模式——建造者模式
c++·microsoft·设计模式·建造者模式
IT技术分享社区2 小时前
C盘飙红、开机一分钟?用这个工具一键清理,电脑速度快得像新买的
windows·microsoft·微软·电脑软件
kaisun642 小时前
记一次 OpenCode 在 Windows 上“Segmentation fault”的踩坑与修复之路
windows·opencode
寺中人2 小时前
Windows系统的GPT磁盘分区
windows·gpt·数据恢复·工具·winhex·硬盘修复
唐青枫3 小时前
终于不用手搓两级缓存了!C#.NET HybridCache 详解:L1 L2、标签失效与防击穿实战
c#·.net