038集——quadtree(CAD—C#二次开发入门)
效果如下:


using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using System.Runtime.CompilerServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.GraphicsInterface;
using System.Drawing;
using Autodesk.AutoCAD.Colors;
namespace AcTools
{public class QuadTreeDemo{[CommandMethod("xx")]public static void treedemo(){//四叉树用于存储平面物体的位置数据,并根据位置选定指定对象,随机画8000个圆,圆心在(100,100)到(800,800)之间。 //用户指定一个点,选定这个点附近200范围内所有的圆并高亮显示。Document dm = Z.doc;Random rand = new Random();List<Circle> cirs = new List<Circle>();//做八千个小圆for (int i = 0; i < 8000; i++){Point3d cent = new Point3d(100+ rand.NextDouble() * 800, 100+rand.NextDouble() * 800, 0);Circle cir = new Circle(cent, Vector3d.ZAxis, 1);cir.Radius = 1 + (rand.NextDouble() * (10 - 1));//[1到10)的随机数cir.ColorIndex = rand.Next(255);cirs.Add(cir);}Extents3d ext = new Extents3d();cirs.ForEach(c => ext.AddExtents(c.GeometricExtents));//new 四叉树,把小圆添加到四叉树里,ext是四叉树的整个范围QuadTreeNode<Circle> qtree = new QuadTreeNode<Circle>(ext);for (int i = 0; i < cirs.Count; i++){//添加了圆心和圆的四个象限点并延伸一定距离。所有满足条件的都会选中。qtree.AddNode(cirs[i].Center, cirs[i]);//qtree.AddNode(new Point3d(cirs[i].GetPointAtParameter(0).X + 400, cirs[i].GetPointAtParameter(0).Y + 300, 0), cirs[i]);//qtree.AddNode(new Point3d(cirs[i].GetPointAtParameter(Math.PI / 2).X + 400, cirs[i].GetPointAtParameter(Math.PI / 2).Y + 400, 0), cirs[i]);//qtree.AddNode(cirs[i].GeometricExtents.MinPoint , cirs[i]);//包围盒的两个点//包围盒最大的的x增大200,相当于这个圆的包围盒最大点的x右移200,如果在指定范围,那么选中,如果右移200不到范围,或超出范围,那么不选中,所以图中会有两个区域被选中qtree.AddNode(new Point3d(cirs[i].GeometricExtents.MaxPoint.X+200, cirs[i].GeometricExtents.MaxPoint.Y,0), cirs[i]);}//把圆添加到数据库using (Transaction tr = dm.Database.TransactionManager.StartTransaction()){BlockTable bt = (BlockTable)tr.GetObject(dm.Database.BlockTableId, OpenMode.ForRead);BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);for (int i = 0; i < cirs.Count; i++){cirs[i].SetDatabaseDefaults();btr.AppendEntity(cirs[i]);tr.AddNewlyCreatedDBObject(cirs[i], true);}tr.Commit();}ViewTableRecord acView = new ViewTableRecord();acView.Height = 1000;acView.Width = 1000;acView.CenterPoint = new Point2d(500, 500);dm.Editor.SetCurrentView(acView);//任选一点PromptPointResult ppr = dm.Editor.GetPoint("选择一点");if (ppr.Status == PromptStatus.OK){Point3d pt = ppr.Value;// 查找这个点周围50范围内的对象 List<Circle> cirsref = qtree.GetNodeRecRange(pt, 50);//亮显这些圆Z.db.AddCircleModeSpace(pt, 50);cirsref.ForEach(c => c.Highlight());}/** 四叉树里可以添加任何对象,比如线,文字,块参照,甚至序号,啥都行,* 只要把对象和点对应上,就是用点来表示这个对象的位置,* 如果一个对象不能用一个点来完全表示他的位置。那么重复添加这个对象,并设置多个点* 比如一个直线的两个端点,或者一条曲线上等分的若干个点。一个文字的四个角点,等等。* 请自由发挥。*/}}public class QuadTreeLeaf<T>{private Point3d pos;private T refObject;public QuadTreeLeaf(Point3d pos, T obj){this.pos = pos;refObject = obj;}public T LeafObject{get{return refObject;}}public Point3d Pos{get { return pos; }set { pos = value; }}}/// <summary>/// 四叉树节点/// </summary>/// <typeparam name="T"></typeparam>public class QuadTreeNode<T>{/// <summary>/// 节点拥有的叶子节点/// </summary>public List<QuadTreeLeaf<T>> items;/// <summary>/// 节点拥有的分支/// </summary>public QuadTreeNode<T>[] branch;/// <summary>/// 节点空间最大容量,受minSize影响/// </summary>protected int maxItems;/// <summary>/// 节点空间分割的最小大小(最小宽度,高度)/// </summary>protected double minSize;public const double TOLERANCE = 0.00001f;/// <summary>/// 节点的空间/// </summary>//public Rect bounds;public Extents3d ext;public QuadTreeNode(Extents3d ext, int 每级最多存储数量 = 4, double minSize = -1){this.ext = ext;//bounds = new Rect(ext.MinPoint.X, ext.MinPoint.Y, ext.MaxPoint.X - ext.MinPoint.X, ext.MinPoint.Y - ext.MinPoint.Y);maxItems = 每级最多存储数量;this.minSize = minSize;items = new List<QuadTreeLeaf<T>>();}public bool HasChildren(){if (branch != null)return true;elsereturn false;}/// <summary>/// 将节点空间分割4份/// </summary>protected void Split(){if (minSize != -1){if ((ext.MaxPoint.X - ext.MinPoint.X) <= minSize && (ext.MaxPoint.Y - ext.MinPoint.Y) <= minSize){return;}}var ext4 = ext.Split4();branch = new QuadTreeNode<T>[4];for (int i = 0; i < 4; i++){branch[i] = new QuadTreeNode<T>(ext4[i], maxItems, minSize);}foreach (var item in items){AddNode(item);}items.Clear();}/// <summary>/// 根据坐标获得相应的子空间/// </summary>/// <param name="pos"></param>/// <returns></returns>protected QuadTreeNode<T> GetChild(Point3d pos){if (ext.Contains(pos)){if (branch != null){for (int i = 0; i < branch.Length; i++)if (branch[i].ext.Contains(pos))return branch[i].GetChild(pos);}elsereturn this;}return null;}/// <summary>/// 增加叶子节点数据/// </summary>/// <param name="leaf"></param>/// <returns></returns>private bool AddNode(QuadTreeLeaf<T> leaf){if (branch is null){this.items.Add(leaf);if (this.items.Count > maxItems) Split();return true;}else{QuadTreeNode<T> node = GetChild(leaf.Pos);if (node != null){return node.AddNode(leaf);}}return false;}public bool AddNode(Point3d pos, T obj){return AddNode(new QuadTreeLeaf<T>(pos, obj));}/// <summary>/// 可以是空间任意位置,只是根据这个位置找到所在的空间去删除对象/// </summary>/// <param name="pos"></param>/// <param name="obj"></param>/// <returns></returns>public bool RemoveNode(Point3d pt, T obj){if (branch is null){for (int i = 0; i < items.Count; i++){QuadTreeLeaf<T> qtl = items[i];if (qtl.LeafObject.Equals(obj)){items.RemoveAt(i);return true;}}}else{QuadTreeNode<T> node = GetChild(pt);if (node != null){return node.RemoveNode(pt, obj);}}return false;}public int GetNode(Extents3d ext, ref List<T> nodes){Point2d p0 = new Point2d(ext.MinPoint.X, ext.MinPoint.Y);Vector3d vt = ext.MaxPoint - ext.MinPoint;//Rect rect = new Rect(p0, new Point2d(vt.X, vt.Y));if (branch is null){foreach (QuadTreeLeaf<T> item in items){if (ext.Contains(item.Pos)){nodes.Add(item.LeafObject);}}}else{for (int i = 0; i < branch.Length; i++){if (branch[i].ext.Overlaps(ext))branch[i].GetNode(ext, ref nodes);}}return nodes.Count;}public List<T> GetNode(Extents3d ext){List<T> nodes = new List<T>();GetNode(ext, ref nodes);return nodes;}/// <summary>/// 根据坐标得到坐标附近节点的数据/// </summary>/// <param name="pos"></param>/// <param name="ShortestDistance">离坐标最短距离</param>/// <param name="list"></param>/// <returns></returns>public int GetNodeRecRange(Point3d pos, double ShortestDistance, ref List<T> list){double distance;if (branch is null){foreach (QuadTreeLeaf<T> leaf in items){distance = (pos - leaf.Pos).Length;if (distance < ShortestDistance){list.Add(leaf.LeafObject);}}}else{for (int i = 0; i < branch.Length; i++){double childDistance = branch[i].ext.PointToExtentsDistance(pos);if (childDistance < ShortestDistance * ShortestDistance){branch[i].GetNodeRecRange(pos, ShortestDistance, ref list);}}}return list.Count;}public List<T> GetNodeRecRange(Point3d pos, double ShortestDistance){List<T> list = new List<T>();int n = GetNodeRecRange(pos, ShortestDistance, ref list);return list;}}public static class EX{public static List<Extents3d> Split4(this Extents3d ext){var x1 = ext.MinPoint.X;var x2 = ext.MaxPoint.X;var y1 = ext.MinPoint.Y;var y2 = ext.MaxPoint.Y;var xm = x2 / 2 + x1 / 2;var ym = y2 / 2 + y1 / 2;Extents3d ext1 = new Extents3d(new Point3d(x1, y1, 0), new Point3d(xm, ym, 0));Extents3d ext2 = new Extents3d(new Point3d(x1, ym, 0), new Point3d(xm, y2, 0));Extents3d ext3 = new Extents3d(new Point3d(xm, ym, 0), new Point3d(x2, y2, 0));Extents3d ext4 = new Extents3d(new Point3d(xm, y1, 0), new Point3d(x2, ym, 0));return [ext1, ext2, ext3, ext4];}public static bool Contains(this Extents3d ext, Point3d pt){return pt.X >= ext.MinPoint.X && pt.X <= ext.MaxPoint.X && pt.Y >= ext.MinPoint.Y && pt.Y <= ext.MaxPoint.Y;}public static bool Overlaps(this Extents3d ext, Extents3d other){return other.MaxPoint.X > ext.MinPoint.X && other.MinPoint.X < ext.MaxPoint.X&& other.MaxPoint.Y > ext.MinPoint.Y && other.MinPoint.Y < ext.MaxPoint.Y;}public static Point3d PointToNormalized(Extents3d rectangle, Point3d point){return new Point3d(InverseLerp(rectangle.MinPoint.X, rectangle.MinPoint.X, point.X),InverseLerp(rectangle.MinPoint.X, rectangle.MaxPoint.Y, point.Y),0);}public static double PointToExtentsDistance(this Extents3d ext, Point3d pos){double xdisance;double ydisance;if (ext.MinPoint.X <= pos.X && pos.X <= ext.MaxPoint.X){xdisance = 0;}else{xdisance = Math.Min((Math.Abs(pos.X - ext.MaxPoint.X)), Math.Abs(pos.X - ext.MinPoint.X));}if (ext.MinPoint.Y <= pos.Y && pos.Y <= ext.MaxPoint.Y){ydisance = 0;}else{ydisance = Math.Min(Math.Abs(pos.Y - ext.MaxPoint.Y), Math.Abs(pos.Y - ext.MinPoint.Y));}return xdisance * xdisance + ydisance * ydisance;}public static double InverseLerp(double a, double b, double value){if (a != b){return Clamp01((value - a) / (b - a));}return 0f;}public static double Lerp(double a, double b, double t){return a + (b - a) * Clamp01(t);}public static double Clamp01(double value){if (value < 0){return 0;}if (value > 1){return 1;}return value;}}
}
相关文章:
038集——quadtree(CAD—C#二次开发入门)
效果如下: using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using System; using System.Collections.Generic; using System.Linq; using System.T…...
备赛蓝桥杯--算法题目(1)
1. 链表求和 . - 力扣(LeetCode) class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {ListNode *head nullptr, *tail nullptr;int carry 0;while (l1 || l2) {int n1 l1 ? l1->val: 0;int n2 l2 ? l2->val:…...
机器学习100道经典面试题库(二)
机器学习100道经典面试题库(31-60) 在大规模的语料中,挖掘词的相关性是一个重要的问题。以下哪一个信息不能用于确定两个词的相关性。 A、互信息 B、最大熵 C、卡方检验 D、最大似然比 答案:B 解析:最大熵代表了…...
Unet++改进37:添加KACNConvNDLayer(2024最新改进方法)
本文内容:添加KACNConvNDLayer 目录 论文简介 1.步骤一 2.步骤二 3.步骤三 4.步骤四 论文简介 1.步骤一 新建block/kacn_conv.py文件,添加如下代码: import torch import torch.nn as nn##源码地址:https://github.com/SynodicMonth/ChebyKAN class KACNConvNDLaye…...
基于 Levenberg - Marquardt 法的 BP 网络学习改进算法详解
基于 Levenberg - Marquardt 法的 BP 网络学习改进算法详解 一、引言 BP(Back Propagation)神经网络在众多领域有着广泛应用,但传统 BP 算法存在收敛速度慢、易陷入局部最优等问题。Levenberg - Marquardt(LM)算法作…...
MySQL 8.0与PostgreSQL 15.8的性能对比
根据搜索结果,以下是MySQL 8.0与PostgreSQL 15.8的性能对比: MySQL 8.0性能特点: MySQL在处理大量读操作时表现出色,其存储引擎InnoDB提供了行级锁定和高效的事务处理,适用于并发读取的场景。MySQL通过查询缓存来提高读…...
qt连接postgres数据库时 setConnectOptions函数用法
连接选项,而这些选项没有直接的方法对应,你可能需要采用以下策略之一: 由于Qt SQL API的限制,你可能需要采用一些变通方法或查阅相关文档和社区资源以获取最新的信息和最佳实践。如果你确实需要设置特定的连接选项,并且…...
MySQL45讲 第二十七讲 主库故障应对:从库切换策略与 GTID 详解——阅读总结
文章目录 MySQL45讲 第二十七讲 主库故障应对:从库切换策略与 GTID 详解一、一主多从架构与主备切换的挑战(一)一主多从基本结构(二)主备切换的复杂性 二、基于位点的主备切换(一)同步位点的概念…...
JavaWeb笔记整理——Spring Task、WebSocket
目录 SpringTask cron表达式 WebSocket SpringTask cron表达式 WebSocket...
基于SpringBoot+RabbitMQ完成应⽤通信
前言: 经过上面俩章学习,我们已经知道Rabbit的使用方式RabbitMQ 七种工作模式介绍_rabbitmq 工作模式-CSDN博客 RabbitMQ的工作队列在Spring Boot中实现(详解常⽤的⼯作模式)-CSDN博客作为⼀个消息队列,RabbitMQ也可以⽤作应⽤程…...
Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
问题 IOS14设备,切后台划掉,二次启动崩溃。 原因 IOS14以上 flutter 不支持debugger模式下的二次启动 。 要二次启动需要以release方式编译工程安装至手机。 操作步骤 清理项目:在命令行中运行flutter clean来清理之前的构建文件。重新构…...
React的hook✅
为什么hook必须在组件内的顶层声明? 这是为了确保每次组件渲染时,Hooks 的调用顺序保持一致。React利用 hook 的调用顺序来跟踪各个 hook 的状态。每当一个函数组件被渲染时,所有的 hook 调用都是按照从上到下的顺序依次执行的。React 内部会…...
2024.5 AAAiGLaM:通过邻域分区和生成子图编码对领域知识图谱对齐的大型语言模型进行微调
GLaM: Fine-Tuning Large Language Models for Domain Knowledge Graph Alignment via Neighborhood Partitioning and Generative Subgraph Encoding 问题 如何将特定领域知识图谱直接整合进大语言模型(LLM)的表示中,以提高其在图数据上自…...
从熟练Python到入门学习C++(record 6)
基础之基础之最后一节-结构体 1.结构体的定义 结构体相对于自定义的一种新的变量类型。 四种定义方式,推荐第一种;第四种适合大量定义,也适合查找; #include <iostream> using namespace std; #include <string.h>…...
jenkins的安装(War包安装)
Jenkins是一个开源的持续集成工具,基于Java开发,主要用于监控持续的软件版本发布和测试项目。 它提供了一个开放易用的平台,使软件项目能够实现持续集成。Jenkins的功能包括持续的软件版本发布和测试项目,以及监控外部调用执行…...
WPS 加载项开发说明wpsjs
wpsjs几个常用的CMD命令: 1.打开cmd输入命令测试版本号 npm -v 2.首次安装nodejs,npm默认国外镜像,包下载较慢时,可切换到国内镜像 //下载速度较慢时可切换国内镜像 npm config set registry https://registry.npmmirror.com …...
【Anomaly Detection论文阅读记录】PaDiM与PatchCore模型的区别与联系
PaDiM与PatchCore模型的区别与联系 背景介绍 PADIM(Pretrained Anomaly Detection via Image Matching)和 PatchCore 都是基于深度学习的异常检测方法,主要用于图像异常检测,尤其是在无监督学习设置下。 PADIM 是一种通过利用预训练的视觉模型(例如,ImageNet预训练的卷…...
uni-app Vue3语法实现微信小程序样式穿透uview-plus框架
1 问题描述 我在用 uni-app vue3 语法开发微信小程序时,在项目中使用了 uview-plus 这一开源 UI 框架。在使用 up-text 组件时,想要给它添加一些样式,之前了解到微信小程序存在样式隔离的问题,也在uview-plus官网-注意事项中找到…...
K8S基础概念和环境搭建
K8S的基础概念 1. 什么是K8S K8S的全称是Kubernetes K8S是一个开源的容器编排平台,用于自动化部署、扩缩、管理容器化应用程序。 2. 集群和节点 集群:K8S将多个机器统筹和管理起来,彼此保持通讯,这样的关系称之为集群。 节点…...
[服务器] 腾讯云服务器免费体验,成功部署网站
文章目录 概要整体架构流程概要 腾讯云服务器免费体验一个月。 整体架构流程 腾讯云服务器体验一个月, 选择预装 CentOS 7.5 首要最重要的是: 添加阿里云镜像。 不然国外源速度慢, 且容易失败。 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/li…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
