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…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...