首页 > 编程语言 >寻路算法---基于AutoCAD二次开发

寻路算法---基于AutoCAD二次开发

时间:2024-06-03 15:45:06浏览次数:29  
标签:AutoCAD point ljQjCurves curve --- QjPoint 二次开发 new public

在CAD中绘制首尾相连的直线,并据此构件点与点之间的连接关系,考虑到可能会有线连接的地方有一定的距离delta

 

点的信息,用于最开始情况下的点的信息集合

    /// <summary>
    /// 点对应的信息
    /// </summary>
    public class QjPointInfo
    {
        /// <summary>
        /// QjPoint
        /// </summary>
        public QjPoint point;
        /// <summary>
        /// 对应的QjCurve
        /// </summary>
        public QjCurve curve;
        /// <summary>
        /// 对应曲线另一个端点的信息
        /// </summary>
        public QjPointInfo qjPointInfo;

        public QjPointInfo(QjPoint point, QjCurve curve)
        {
            this.point = point;
            this.curve = curve;
        }
    }

QjPoint用于对应点的连接关系

 /// <summary>
 /// 对应点的连接关系
 /// </summary>
 public class QjPoint
 {
     /// <summary>
     /// 对应的当前点
     /// </summary>
     public Point3d point;
     /// <summary>
     /// 对应另一个点和连接另一个点的曲线
     /// </summary>
     public Dictionary<QjPoint,Curve> pcDict;
     /// <summary>
     /// 用于Dijkstra算法
     /// </summary>
     public Connect connect;
     /// <summary>
     /// 唯一编码,用于比较
     /// </summary>
     public string id;
     public double X
     {
         get { return point.X; }
     }

     public QjPoint(Point3d point)
     {
         this.point = point;
         pcDict = new Dictionary<QjPoint, Curve>();
         connect = new Connect();
         id = Guid.NewGuid().ToString();
     }

     public double DistanceTo(QjPoint qjPoint)
     {
         return this.point.DistanceTo(qjPoint.point);
     }
     /// <summary>
     /// 初始化Dijkstra的信息
     /// </summary>
     public void InitConnect()
     {
         connect = new Connect();
     }

 }

 public class Connect
 {
     /// <summary>
     /// 对应最短路径的上一个点
     /// </summary>
     public QjPoint path;
     /// <summary>
     /// 对应连接上一个点的曲线
     /// </summary>
     public Curve curve;
     /// <summary>
     /// 距离起始点的距离
     /// </summary>
     public double dis;
     /// <summary>
     /// 是否已经用过
     /// </summary>
     public bool visted;

     public Connect()
     {
         path = null;
         curve = null;
         dis = double.MaxValue;
         visted = false;
     }
 }

QjCurve用于记录每一条曲线的起始点、曲线和终止点

    public class QjCurve
    {
        public QjPoint startPoint;
        public QjPoint endPoint;
        public Curve curve;
        public QjCurve(Curve curve,QjPoint startPoint,QjPoint endPoint )
        {
            this.curve = curve;
            this.startPoint = startPoint;
            this.endPoint = endPoint;
        }
    }

首先需要构建所有的曲线信息

public void InitQjCurvesDict(List<Curve> curves, out List<QjPoint> qjPoints, out List<QjCurve> qjCurves)
{
    qjPoints = new List<QjPoint>();
    qjCurves = new List<QjCurve>();
    List<QjPointInfo> pointInfos = new List<QjPointInfo>();

    for (int i = 0; i < curves.Count; i++)
    {
        Curve curve = curves[i];
        ///创建曲线对应的起始点和终止点QjPoint
        QjPoint startPoint = new QjPoint(curve.StartPoint);
        QjPoint endPoint = new QjPoint(curve.EndPoint);
        ///创建QjCurve
        QjCurve qjCurve = new QjCurve(curve, startPoint, endPoint);
        qjCurves.Add(qjCurve);
        ///创建QjPointInfo
        QjPointInfo p1 = new QjPointInfo(startPoint, qjCurve);
        QjPointInfo p2 = new QjPointInfo(endPoint, qjCurve);

        p1.qjPointInfo = p2;
        p2.qjPointInfo = p1;

        pointInfos.Add(p1);
        pointInfos.Add(p2);
    }


    ///对所有点进行排序 为后续扫描线方法坐做准备
    pointInfos = pointInfos.OrderBy(p => p.point.X).ToList();
    ///扫描线方法需要的一个记录临时点集的points
    List<QjPointInfo> tempPointInfos = new List<QjPointInfo>();

    ///用于合并可认为视为同一个点的qjpoins
    Dictionary<QjPoint, List<QjCurve>> pcDict = new Dictionary<QjPoint, List<QjCurve>>();

    for (int i = 0; i < pointInfos.Count; i++)
    {
        QjPointInfo qjPointInfo = pointInfos[i];
        for (int j = 0; j < tempPointInfos.Count; j++)
        {
            QjPointInfo tempPointInfo = tempPointInfos[j];
            ///当点的X坐标小于当前的qjpoint,并且距离大于delta,
            ///保证在一定距离范围内的顶点视为同一个点
            ///就将其从tempPointInfos中移出,扫描线方法的核心
            if (tempPointInfo.point.X < qjPointInfo.point.X &&
                tempPointInfo.point.DistanceTo(qjPointInfo.point) > delta)
            {
                tempPointInfos.RemoveAt(j);
                j--;
            }
        }

        bool isContain = Solve(qjPointInfo, tempPointInfos);
        if (!isContain)
        {
            pcDict.Add(qjPointInfo.point, new List<QjCurve>());
        }
        pcDict[qjPointInfo.point].Add(qjPointInfo.curve);
        tempPointInfos.Add(qjPointInfo);
    }

    qjPoints = new List<QjPoint>();
    ///根据pcDict将qjpoint重铸,形成点和点的对应关系
    foreach (var item in pcDict)
    {
        QjPoint qjPoint = item.Key;
        for (int j = 0; j < item.Value.Count; j++)
        {
            if (qjPoint.point == item.Value[j].startPoint.point)
            {
                qjPoint.pcDict.Add(item.Value[j].endPoint, item.Value[j].curve);
            }
            else
            {
                qjPoint.pcDict.Add(item.Value[j].startPoint, item.Value[j].curve);
            }
        }
        qjPoints.Add(qjPoint);
    }
}


 /// <summary>
 /// 在tempPoints中找到qjpoint是否有重合的点,并且对qjpoint点的位置进行重置
 /// </summary>
 /// <param name="qjPointInfo"></param>
 /// <param name="tempPointInfos"></param>
 /// <returns></returns>
 public bool Solve(QjPointInfo qjPointInfo, List<QjPointInfo> tempPointInfos)
 {
     bool isContain = false;
     for (int i = 0; i < tempPointInfos.Count; i++)
     {
         if (qjPointInfo.point.DistanceTo(tempPointInfos[i].point) < delta)
         {
             if (qjPointInfo.curve.startPoint == qjPointInfo.point)
             {
                 qjPointInfo.curve.startPoint = tempPointInfos[i].point;
             }
             else
             {
                 qjPointInfo.curve.endPoint = tempPointInfos[i].point;
             }
             qjPointInfo.point = tempPointInfos[i].point;
             isContain = true;
         }
     }
     return isContain;
 }

 ///根据起始点、终止点利用Dijkstra算法找到最短路径

private List<Curve> GetCurvesByTwoPointAnQjCurves(Point3d pS, Point3d pE, List<QjPoint> qjPoints, List<QjCurve> qjCurves)
        {
            ///首先对所有的qjpoint的connect信息初始化
            qjPoints.ForEach(qjPoint => qjPoint.InitConnect());

            ///找到对应的起始点和终止点的qjpoint
            QjPoint qjStartPoint = GetPoint(pS, qjCurves, out Point3d clostPt1, out QjCurve qjCurve1);
            QjPoint qjEndPoint = GetPoint(pE, qjCurves, out Point3d clostPt2, out QjCurve qjCurve2);
            ///将起点到起点的dis设置为0,visted设置为true
            qjStartPoint.connect.dis = 0;
            qjStartPoint.connect.visted = true;

            Solve(qjStartPoint);
            List<Curve> ljQjCurves = new List<Curve>();

            while (true)
            {
                if (qjEndPoint.id == qjStartPoint.id || qjEndPoint.connect.curve == null)
                {
                    break;
                }
                Curve curve = qjEndPoint.connect.curve.Clone() as Curve;
                ljQjCurves.Add(curve);
                qjEndPoint = qjEndPoint.connect.path;
            }

            //调整起始点
            //如果起始点在起始的Curve上,那么就根据最后的的Curve和下一个curve来区分出Curve并进行替换
            if (clostPt1.DistanceTo(ljQjCurves.Last().GetClosestPointTo(clostPt1, false)) < 0.0001)
            {
                Curve curve = GetCurve(ljQjCurves[ljQjCurves.Count - 1], ljQjCurves[ljQjCurves.Count - 2], clostPt1);
                ljQjCurves[ljQjCurves.Count - 1] = curve;
            }
            //如果起始点不在起始的Curve上,那么就根据现有的Curve和最后的curve来区分出Curve进行Insert
            else
            {
                Curve curve = GetCurve(qjCurve1.curve, ljQjCurves[ljQjCurves.Count - 1], clostPt1);
                ljQjCurves.Add(curve);
            }
            Line line = new Line(pS, clostPt1);
            ljQjCurves.Add(line);

            //调整终止点
            if (clostPt2.DistanceTo(ljQjCurves.First().GetClosestPointTo(clostPt2, false)) < 0.01)
            {
                Curve curve = GetCurve(ljQjCurves[0], ljQjCurves[1], clostPt2);
                ljQjCurves[0] = curve;
            }
            else
            {
                Curve curve = GetCurve(qjCurve2.curve, ljQjCurves[0], clostPt2);
                ljQjCurves.Insert(0, curve);
            }
            line = new Line(pE, clostPt2);
            ljQjCurves.Insert(0, line);

            return ljQjCurves;
        }

 /// <summary>
 /// 最开始初始化startPoint的适合要将startPoint的dis初始化为0
 /// </summary>
 /// <param name="startPoint"></param>
 /// <param name="endPoint"></param>
 /// <param name="qjPoints"></param>
 public void Solve(QjPoint startPoint)
 {
     ///使用队列进行BFS算法来形成所有点到起点的最短路径
     Queue<QjPoint> qjPointQueue = new Queue<QjPoint>();
     qjPointQueue.Enqueue(startPoint);
     while (qjPointQueue.Count() != 0)
     {
         QjPoint qjPoint = qjPointQueue.Dequeue();
         qjPoint.connect.visted = true;
         foreach (var item in qjPoint.pcDict)
         {
             double dis = qjPoint.connect.dis + item.Value.Ex_GetLength();
             if (dis < item.Key.connect.dis)
             {
                 item.Key.connect.dis = dis;
                 item.Key.connect.path = qjPoint;
                 item.Key.connect.curve = item.Value;
             }
         }
         var keys = qjPoint.pcDict.Keys.OrderBy(k => k.connect.dis);

         foreach (var key in keys)
         {
             if (key.connect.visted == false)
             {
                 qjPointQueue.Enqueue(key);
             }
         }
     }
 }

 

标签:AutoCAD,point,ljQjCurves,curve,---,QjPoint,二次开发,new,public
From: https://www.cnblogs.com/HRDK-CADeveloper/p/18228957

相关文章

  • Install-Package 和 dotnet add package安装NuGet包对比
    关于使用场景Install-PackageSSH.NET和dotnetaddpackageSSH.NET这两个命令都用于安装NuGet包,但它们是用于不同命令行工具和环境的。这里是两者的主要区别:Install-PackageSSH.NET:这是一个用于NuGet包管理器控制台的命令,这个控制台是集成在VisualStudio中的。主要用......
  • 国内首个开源网络流量可视化分析平台 -- 流影
    流影:基于流量的网络行为高级分析平台  流影是一款基于全流量的高级网络行为分析平台,该系统是由深海鱼(北京)科技有限公司流影项目组研发设计,首发开源是1.0版本。项目简介  深海鱼(北京)科技有限公司专注于为客户提供优质的数据分析相关服务,近年来立足于客户的数字安全需求,深耕......
  • git-更换本地远程仓库地址
    命令不删除远程仓库修改#查看远端地址gitremote-v#查看远端仓库名gitremote#重新设置远程仓库gitremoteset-urloriginhttps://gitee.com/xx/xx.git(新地址).git配置config文件修改修改.git隐藏文件夹下的config文件内容,将[remote"origin"]下的url修......
  • 深入跨域 - 解决方案
    1前言前文《深入跨域-从初识到入门》中,大家已经对同源与跨域的产生历史与重要性等有了一个初步的了解了,那么我们应该如何解决在日常开发中遇到的跨域引起的问题呢? 2一览图我们将日常开发中的跨域解决方案大体分为两类:iframe跨域与API跨域:       ......
  • 【攻防世界】catcat-new
    catcat-new题目来源攻防世界NO.GFSJ1168题解dirsearch爆破目录,得到http://61.147.171.105:55027/admin,没有有用信息点开主页的图片,观察URL,尝试读取/etc/passwd,成功,可以读取文件读取/proc/self/cmdline文件,发现有app.py/proc/self/cmdline是一个特殊的文件,它提供了......
  • Python基础-- 组合类型
    Python基础--组合类型Python基础--组合类型Python基础--组合类型(一)列表的特征(二)列表的创建(三)列表的访问(四)列表的操作方法(五)列表支持的运算符二、元组(一)元组特征和基本概念(一)元组和列表的对比三、字典(一)字典的特征(二)字典元素的访问(三)字典的操作......
  • Python基础---程序的控制结构
    Python基础—程序的控制结构Python基础---程序的控制结构一、程序流程成图(一)顺序结构(二)程序的分支控制结构1:单分支结构2.二分支结构3.多分支结构4.分支嵌套(三)程序的循环结构1、while循环2.while循环扩展模式3.for循环4.for循环扩展模式二、循环控制语句(一)conti......
  • How about a push-type floor scrubber
    Thehand-pushfloorscrubberisanelectriccleaningequipmentsuitablefordifferentfloormaterialsanddifferentcleaningplaces.Whilecleaningthefloor,itsucksupthesewageandtakesthesewageawayfromthesite.Theworkingprincipleissimple,......
  • 计算机网络基础-VRRP原理与配置
    目录一、了解VRRP1、VRRP的基本概述2、VRRP的作用二、VRRP的基本原理1、VRRP的基本结构图2、设备类型(Master,Backup) 3、VRRP抢占功能3.1:抢占模式3.2、非抢占模式4、VRRP设备的优先级5、VRRP工作原理三、VRRP的基本配置3.1、配置主设备与备用设备​ 3.2、结果......
  • MySQL从入门到高级 --- 12.事务 && 13.锁机制 && 14.日志
    文章目录第十二章&&第十三章&&第十四章:12.事务12.1特性12.2隔离级别13.锁机制13.1各存储引擎对锁的支持状况:13.2锁特性13.3MyISAM表锁13.3.1加表锁13.4InnoDB行锁13.4.1行锁特点13.4.2行锁模式14.日志14.1错误日志14.2二进制日志14.2.1日志格式14.3......