凸包算法—— cad c#二次开发

 效果如下:

 代码如下:


using IfoxDemo;
//[assembly: CommandClass(typeof(IFoxDemo.凸包class))]//只允许此类快捷键命令
namespace IFoxDemo
{
    public class 凸包class
    {
        public static class 凸包助手
        {
            /// <summary>
            /// 计算点集的凸包并返回多段线
            /// </summary>
            /// <param name="pts">点集合</param>
            /// <returns>凸包多段线</returns>
            public static Polyline 计算凸包(List<Point2d> pts)
            {
                if (pts == null || pts.Count < 3)
                {
                    throw new ArgumentException("至少需要三个点来计算凸包。");
                }

                // 计算凸包点集
                List<Point2d> convexHullPoints = 筛选凸包点(pts);

                // 创建多段线
                Polyline convexHullPolyline = new Polyline();
                for (int i = 0; i < convexHullPoints.Count; i++)
                {
                    convexHullPolyline.AddVertexAt(i, convexHullPoints[i], 0, 0, 0);
                }

                // 闭合多段线
                convexHullPolyline.AddVertexAt(convexHullPoints.Count, convexHullPoints[0], 0, 0, 0);
                convexHullPolyline.Closed = true;

                return convexHullPolyline;
            }

            /// <summary>
            /// 使用 Andrew's monotone chain 算法计算凸包
            /// </summary>
            /// <param name="points">输入点集</param>
            /// <returns>凸包点集</returns>
            private static List<Point2d> 筛选凸包点(List<Point2d> points)
            {
                // 按 X 坐标排序,如果 X 相同则按 Y 排序
                points.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : a.X.CompareTo(b.X));

                List<Point2d> hull = new List<Point2d>();

                // 构建下凸包
                foreach (var pt in points)
                {
                    while (hull.Count >= 2 && Cross(hull[hull.Count - 2], hull[hull.Count - 1], pt) <= 0)
                    {
                        hull.RemoveAt(hull.Count - 1);
                    }
                    hull.Add(pt);
                }

                // 构建上凸包
                int lowerHullCount = hull.Count + 1;
                for (int i = points.Count - 1; i >= 0; i--)
                {
                    var pt = points[i];
                    while (hull.Count >= lowerHullCount && Cross(hull[hull.Count - 2], hull[hull.Count - 1], pt) <= 0)
                    {
                        hull.RemoveAt(hull.Count - 1);
                    }
                    hull.Add(pt);
                }

                // 移除最后一个点,因为它是第一个点的重复
                hull.RemoveAt(hull.Count - 1);

                return hull;
            }

            /// <summary>
            /// 计算叉积
            /// </summary>
            /// <param name="O">起点</param>
            /// <param name="A">点 A</param>
            /// <param name="B">点 B</param>
            /// <returns>叉积值</returns>
            private static double Cross(Point2d O, Point2d A, Point2d B)
            {
                return (A.X - O.X) * (B.Y - O.Y) - (A.Y - O.Y) * (B.X - O.X);
            }
        }
        public class 凸包Demo类
        {
            [CommandMethod("tub")]
            public void 凸包Demo()
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Database db = doc.Database;
                Editor ed = doc.Editor;
                var pts = new List<DBPoint>();
                if  (! ed.GetEntities(out pts ,"") ) return;
                //List<Point2d> points = new List<Point2d>();
                //foreach (DBPoint p in pts)
                //{
                //    points.Add(new Point2d(p.Position.X,p.Position.Y));
                //}下面为lambda等效写法
                List<Point2d> points = pts.Select(p => new Point2d(p.Position.X, p.Position.Y)).ToList();
                #region
                 获取点集合(这里假设用户已经选择了一些点)
                //PromptPointOptions ppo = new PromptPointOptions("\n选择点: ");
                //ppo.AllowNone = false;
                //ppo.Keywords.Add("Done");

                //List<Point2d> points = new List<Point2d>();
                //while (true)
                //{
                //    PromptPointResult ppr = ed.GetPoint(ppo);
                //    if (ppr.Status == PromptStatus.Keyword && ppr.StringResult == "Done")
                //    {
                //        break;
                //    }
                //    points.Add(new Point2d(ppr.Value.X, ppr.Value.Y));
                //}

                //if (points.Count < 3)
                #endregion
                if (points.Count < 3)
                    {
                    ed.WriteMessage("\n至少需要三个点来计算凸包。");
                    return;
                }

                // 计算凸包
                Polyline pl = 凸包助手.计算凸包(points);

                // 将多段线添加到当前图形
                #region
                //using (Transaction tr = db.TransactionManager.StartTransaction())
                //{
                //    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                //    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                //    btr.AppendEntity(convexHullPolyline);
                //    tr.AddNewlyCreatedDBObject(convexHullPolyline, true);

                //    tr.Commit();
                //}
                #endregion
                using var dbtrans = new DBTrans();
                dbtrans.CurrentSpace.AddEntity(pl);
                ed.WriteMessage("\n凸包多段线已创建。");
            }
        }
        public class 产生随机点
        {
            [CommandMethod("cssjd")]
            public void CreateRandomPoints()
            {
                Document doc = Application.DocumentManager.MdiActiveDocument;
                Database db = doc.Database;
                Editor ed = doc.Editor;

                // 提示用户输入点的数量
                PromptIntegerOptions pio = new PromptIntegerOptions("\n请输入要创建的点数量: ");
                pio.AllowNegative = false;
                pio.AllowZero = false;
                pio.DefaultValue = 10;

                PromptIntegerResult pir = ed.GetInteger(pio);
                if (pir.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n用户取消操作。");
                    return;
                }

                int pointCount = pir.Value;

                // 提示用户输入随机点的范围
                PromptPointOptions ppo = new PromptPointOptions("\n指定随机点的范围(左下角点): ");
                PromptPointResult ppr1 = ed.GetPoint(ppo);
                if (ppr1.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n用户取消操作。");
                    return;
                }

                ppo.Message = "\n指定随机点的范围(右上角点): ";
                PromptPointResult ppr2 = ed.GetPoint(ppo);
                if (ppr2.Status != PromptStatus.OK)
                {
                    ed.WriteMessage("\n用户取消操作。");
                    return;
                }

                Point3d lowerLeft = ppr1.Value;
                Point3d upperRight = ppr2.Value;

                // 创建随机点
                Random random = new Random();
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                    BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                    for (int i = 0; i < pointCount; i++)
                    {
                        double x = lowerLeft.X + (upperRight.X - lowerLeft.X) * random.NextDouble();
                        double y = lowerLeft.Y + (upperRight.Y - lowerLeft.Y) * random.NextDouble();

                        Point2d randomPoint2d = new Point2d(x, y);
                        Point3d randomPoint3d = new Point3d(randomPoint2d.X, randomPoint2d.Y, 0);

                        // 创建点实体
                        DBPoint dbPoint = new DBPoint(randomPoint3d);
                        btr.AppendEntity(dbPoint);
                        tr.AddNewlyCreatedDBObject(dbPoint, true);
                    }

                    tr.Commit();
                }

                ed.WriteMessage($"\n成功创建 {pointCount} 个随机点。");
            }
        }
    }
}

逆时针最小夹角

 cad 二次开发、插件代写↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/970645.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式】【行为型模式】解释器模式(Interpreter)

&#x1f44b;hi&#xff0c;我不是一名外包公司的员工&#xff0c;也不会偷吃茶水间的零食&#xff0c;我的梦想是能写高端CRUD &#x1f525; 2025本人正在沉淀中… 博客更新速度 &#x1f44d; 欢迎点赞、收藏、关注&#xff0c;跟上我的更新节奏 &#x1f3b5; 当你的天空突…

进阶数据结构——离散化

目录 一、离散化的核心思想与本质二、离散化的应用场景三、离散化的实现步骤四、离散化的复杂度分析五、离散化的优化技巧六、常见误区与调试技巧七、代码模版&#xff08;c&#xff09;八、经典例题数列离散化寻找满足高度的最大山峦美丽值 九、总结与学习建议 一、离散化的核…

VNC远程控制Mac

前言 macOS系统自带有VNC远程桌面&#xff0c;我们可以在控制端上安装配置VNC客户端&#xff0c;以此来实现远程控制macOS。但通常需要在不同网络下进行远程控制&#xff0c;为此&#xff0c;我们可以在macOS被控端上使用cpolar做内网穿透&#xff0c;映射VNC默认端口5…

[0689].第04节:Kafka与第三方的集成 – Kafka集成SpringBoot

Kafka笔记大纲 SpringBoot 是一个在 JavaEE 开发中非常常用的组件。可以用于 Kafka 的生产者&#xff0c;也可以用于 SpringBoot 的消费者 一、SpringBoot 环境准备 1.1.创建一个 Spring Initializr 1.2.引入场景启动器&#xff1a; <?xml version"1.0" encod…

「软件设计模式」装饰者模式(Decorator)

深入解析装饰者模式&#xff1a;动态扩展功能的艺术&#xff08;C实现&#xff09; 一、模式思想与应用场景 1.1 模式定义 装饰者模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过将对象放入包含行为的特殊封装对象中&#xff0c;动态地…

简单几个步骤完成 Oracle 到金仓数据库(KingbaseES)的迁移目标

作为国产数据库的领军选手&#xff0c;金仓数据库&#xff08;KingbaseES&#xff09;凭借其成熟的技术架构和广泛的市场覆盖&#xff0c;在国内众多领域中扮演着至关重要的角色。无论是国家电网、金融行业&#xff0c;还是铁路、医疗等关键领域&#xff0c;金仓数据库都以其卓…

【Jenkins流水线搭建】

Jenkins流水线搭建 01、SpringBoot项目 - Jenkins基于Jar持续集成搭建文档基于手动方式发布项目基于dockerfile基于jenkins + dockerfile + jenkinsfile +pieline基于jenkins + jar方式的发布01、环境说明01、准备项目02、准备服务器03、安装git04、安装jdk1.805、安装maven依赖…

简单记录一下自己对springboot过程的理解

仅为个人简单理解&#xff0c;欢迎大家来一起讨论。 执行启动类main函数&#xff1b;读取依赖和配置文件&#xff1b;创建spring容器&#xff0c;并自动注入Bean&#xff1b;启动Tomcat。

使用 GPT-SoVITS 克隆声音,很详细

使用 GPT-SoVITS 克隆声音&#xff0c;很详细 一、前言二、下载三、启动四、克隆声音1、准备克隆音频2、分离人声伴奏3、音频分割4、语音降噪5、ASR工具6、语音文本校对标注工具7、训练模型8、微调训练9、推理 一、前言 最近对文本转语言很感兴趣&#xff0c;但对直接在网站上…

金融风控项目-业务基础

文章目录 一. 案例背景介绍二. 代码实现1. 加载数据2. 数据处理3. 查询 三. 业务解读 一. 案例背景介绍 通过对业务数据分析了解信贷业务状况 数据集说明 从开源数据改造而来&#xff0c;基本反映真实业务数据销售&#xff0c;客服可以忽略账单周期&#xff0c;放款日期账单金…

Django 创建表时 “__str__ ”方法的使用

在 Django 模型中&#xff0c;__str__ 方法是一个 Python 特殊方法&#xff08;也称为“魔术方法”&#xff09;&#xff0c;用于定义对象的字符串表示形式。它的作用是控制当对象被转换为字符串时&#xff0c;应该返回什么样的内容。 示例&#xff1a; 我在初学ModelForm时尝…

Spring Boot中如何自定义Starter

文章目录 Spring Boot中如何自定义Starter概念和作用1. 概念介绍2. 作用和优势2.1 简化依赖管理2.2 提供开箱即用的自动配置2.3 标准化和模块化开发2.4 提高开发效率2.5 提供灵活的配置覆盖3. 应用场景创建核心依赖1. 确定核心依赖的作用2. 创建 starter-core 模块2.1 依赖管理…

Python 面向对象的三大特征

前言&#xff1a;本篇讲解面向对象的三大特征&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff0c;还有比较细致的&#xff08;类属性类方法&#xff0c;静态方法&#xff09;&#xff0c;分步骤讲解&#xff0c;比较适合理清楚三大特征的思路 面向对象的…

Windows 11 安装 Docker

1.以管理员身份打开 Windows PowerShell 2.执行下面三行命令来启动WSL和虚拟机平台 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestartdism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norest…

CRMEB PHP多门店版v3.1.1源码全开源+PC端+Uniapp前端+搭建教程

一.介绍 CRMEB多店版是一款为品牌连锁门店打造的私域电商解决方案&#xff0c;以三大运营模式为核心&#xff0c;助力品牌连锁门店轻松构建全渠道、一体化的私域电商生态&#xff0c;促进“线上电商”与“线下门店”销售运营融合&#xff0c;加速品牌数字化转型&#xff0c;为…

Notepad++ 中删除所有以 “pdf“ 结尾的行

Notepad 中删除所有以 “pdf” 结尾的行 操作步骤 1.打开文件&#xff1a; 在 Notepad 中打开你需要处理的文本文件。 2.打开查找和替换对话框&#xff1a; 按快捷键 Ctrl F&#xff0c;打开“查找和替换”对话框。 3.启用正则表达式模式&#xff1a; 在对话框的底部&#xf…

基于SSM+uniapp的鲜花销售小程序+LW示例参考

1.项目介绍 系统角色&#xff1a;管理员、商户功能模块&#xff1a;用户管理、商户管理、鲜花分类管理、鲜花管理、订单管理、收藏管理、购物车、充值、下单等技术选型&#xff1a;SSM&#xff0c;Vue&#xff08;后端管理web&#xff09;&#xff0c;uniapp等测试环境&#x…

项目版本号生成

需求 项目想要生成一个更新版本号&#xff0c;格式为v2.0.20250101。 其中v2.0为版本号&#xff0c;更新时进行配置&#xff1b;20250101为更新日期&#xff0c;版本更新时自动生成。 实现思路 创建一个配置文件version.properties&#xff0c;在其中配置版本号&#xff1b…

Unity UI个人总结

个人总结&#xff0c;太简单的直接跳过。 一、缩放模式 1.固定像素大小 就是设置一个100x100的方框&#xff0c;在1920x1080像素下在屏幕中长度占比1/19&#xff0c;在3840x2160&#xff0c;方框在屏幕中长度占比1/38。也就是像素长款不变&#xff0c;在屏幕中占比发生变化 2.…

ArcGIS基础知识之ArcMap基础设置——ArcMap选项:常规选项卡设置及作用

作为一名 GIS 从业者,ArcMap 是我们日常工作中不可或缺的工具。对于初学者来说,掌握 ArcMap 的基础设置是迈向 GIS 分析与制图的第一步。今天,就让我们一起深入了解 ArcMap 选项中常规选项卡的各个设置,帮助大家更好地使用这款强大的软件。 在 ArcMap 中,常规选项卡是用户…