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…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...
