当前位置: 首页 > article >正文

031集——获取外轮廓(只支持线段多段线)(CAD—C#二次开发入门)

此版本跟007集相比,增加了个识别断线头的功能,即原始图形中线段可不闭合。

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace AcTools
{
    public static class Outershape
    {
        public static void Demo()
        {
            try
            {
                
                if (!Z.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 = Z.ed.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);//一个line被他上面的点打成多个line后加入列表
                            }
                        }
                }
                //}
                List<Line> goodlines = Outershape.RepairLine(lines);//清除线头
                List<Line> goodlines2 = Outershape.RecycleLine(goodlines);
                if (goodlines2.Count == 0) return;
                //foreach (var item in goodlines2)
                //{
                //    item.ChangeEntityColor(2);
                //}
                //Z.db.AddEntityToModeSpace(goodlines2.ToArray());
                //return;
                lines.Clear();
                lines = goodlines2;
                // if (!PmPolyLineMethod.GetPoint(out Point3d point, "请选择外面一点")) return;
                if (! Z.ed.GetPoint(out Point3d point, "请选择外面一点"))return;
                Line firstLine = lines.OrderBy(x => x.GetClosestPointTo(point, false).DistanceTo(point)).First();
                //firstLine.ColorIndex = 5;
                //Z.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;
                Z.db.AddEntityToModeSpace(polyline);
                return;
            }

            catch (System.Exception)
            {
                throw;
            }

        }
        public static List<Line> RepairLine(List<Line> lines)
        {
            if (lines.Count == 0 ) return new List<Line>();
            bool leftHandOk = false; 
            bool rightHandOk = false;
            List<Line> goodlines = new List<Line>();
            for (int i = 0; i < lines.Count; i++)
            {       leftHandOk = false;
                    rightHandOk = false;
                //if (i == 6) Debugger.Break();
                Point3d point = new Point3d((lines[i].StartPoint.X + lines[i].EndPoint.X) / 2, (lines[i].StartPoint.Y + lines[i].EndPoint.Y) / 2, 0);
                DBText text = new DBText() { Position = point, TextString = $"{i}:", Height = 1 };
                Z.db.AddEntityToModeSpace(text);
                for (int j = 0; j < lines.Count; j++)
                {
                   
                    if (i == j) continue;
                    if ((lines[i].StartPoint == lines[j].StartPoint)|| (lines[i].StartPoint == lines[j].EndPoint))
                    {
                        leftHandOk = true;
                    }
                    if ((lines[i].EndPoint == lines[j].StartPoint) || (lines[i].EndPoint == lines[j].EndPoint))
                    {
                        rightHandOk = true;
                    }
                    if (leftHandOk && rightHandOk)
                    {
                        if (!goodlines.Contains(lines[i]))
                        {
                            goodlines.Add(lines[i]);
                        }
                        
                    }
                }

            }
            return goodlines;
        }
        public static List<Line> RecycleLine(List<Line> lines)
        {
            if (lines.Count == 0) return new List<Line>();
            List<Line> templine = lines;
            int tempnum = lines.Count;
            while (true)
            {
                if (RepairLine(templine).Count == tempnum)
                {
                    break;
                    
                }
                else
                {
                    templine = RepairLine(templine);
                    tempnum = templine.Count;
                }
            }
            return templine;
        }
    }
}

 


http://www.kler.cn/a/392786.html

相关文章:

  • 代码 RNN原理及手写复现
  • 《EasyQuotation 与MongoDB在股市信息的奇妙融合》
  • 【前端】JavaScript高级教程:线程机制与事件机制
  • 超子物联网HAL库笔记:定时器[外部模式]篇
  • 使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径
  • 问:MySQL主从同步的机制梳理?
  • 海思Hi3516DV300上播放G711U音频文件
  • 【Hadoop】【hdfs】【大数据技术基础】实验三 HDFS 基础编程实验
  • 【监控】如何调出电脑的中摄像头,从摄像头获取视频流
  • STM32完全学习——点亮LED灯
  • C#发票识别、发票查验接口集成、电子发票(航空运输电子行程单)
  • 【再谈设计模式】抽象工厂模式~对象创建的统筹者
  • Python酷库之旅-第三方库Pandas(214)
  • 利用编程语言和脚本编写技术,实现自动化渗透测试和安全工具的开发
  • Llama微调测试记录
  • Go 加密算法工具方法
  • 嵌入式linux系统中RTC硬件的控制与实现
  • Go语言入门教案
  • 【vue】toRefs 和 toRef——如何在解构响应式对象时保持响应性
  • 免费,WPS Office教育考试专用版
  • 【初阶数据结构篇】插入、希尔、选择、堆排序
  • 约束(MYSQL)
  • github高分项目 WGCLOUD - 运维实时管理工具
  • A032-基于Spring Boot的健康医院门诊在线挂号系统
  • PCB+SMT线上报价系统+PCB生产ERP系统自动化拼板模块升级
  • 【网络安全】X-Forwarded-For漏洞成因及防范