From 8cec18a141bb5074d9762b5d0ae8eb25c6e0caf3 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Tue, 14 Oct 2025 11:49:39 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=80=9F=E9=89=B4=20PointHashGrid3?= =?UTF-8?q?d=20=E4=BC=98=E5=8C=96=E7=A9=BA=E9=97=B4=E5=93=88=E5=B8=8C?= =?UTF-8?q?=E7=BD=91=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改进内容: 1. 使用 ScaleGridIndexer3 实现更清晰的坐标转换(职责分离) 2. 优化 FindInRadius:提前判断 distanceFunc 是否为 null,避免循环中重复检查 3. 使用 TryGetValue 避免字典的两次查找 4. 增强代码注释,说明设计参考和增强点 参考 geometry3Sharp 的 PointHashGrid3d 设计,但保留了我们实现的优势: - 支持返回范围内所有对象(不仅是最近的一个) - 支持直接访问网格单元 - 提供详细的统计信息 --- src/Core/Spatial/SpatialHashGrid.cs | 49 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/Core/Spatial/SpatialHashGrid.cs b/src/Core/Spatial/SpatialHashGrid.cs index 415ca40..a2e593b 100644 --- a/src/Core/Spatial/SpatialHashGrid.cs +++ b/src/Core/Spatial/SpatialHashGrid.cs @@ -7,12 +7,18 @@ namespace NavisworksTransport.Core.Spatial /// /// 自定义3D空间哈希网格 /// 用于高效的空间范围查询,复杂度 O(1) 平均 + /// + /// 设计参考 geometry3Sharp 的 PointHashGrid3d,但提供了以下增强: + /// 1. 支持返回范围内的所有对象(而不仅是最近的一个) + /// 2. 支持直接访问网格单元(GetObjectsInCell) + /// 3. 提供详细的统计信息用于性能分析 + /// 4. 使用 ScaleGridIndexer3 实现更清晰的坐标转换 /// /// 存储的对象类型 public class SpatialHashGrid { private readonly Dictionary> _grid; - private readonly double _cellSize; + private readonly ScaleGridIndexer3 _indexer; /// /// 创建空间哈希网格 @@ -23,14 +29,14 @@ namespace NavisworksTransport.Core.Spatial if (cellSize <= 0) throw new ArgumentException("格子大小必须大于0", nameof(cellSize)); - _cellSize = cellSize; + _indexer = new ScaleGridIndexer3() { CellSize = cellSize }; _grid = new Dictionary>(); } /// /// 格子大小(模型单位) /// - public double CellSize => _cellSize; + public double CellSize => _indexer.CellSize; /// /// 格子总数 @@ -60,14 +66,15 @@ namespace NavisworksTransport.Core.Spatial /// 对象的3D位置 public void Insert(T item, Vector3d position) { - var gridCell = ToGridCoordinates(position); + var gridCell = _indexer.ToGrid(position); - if (!_grid.ContainsKey(gridCell)) + if (!_grid.TryGetValue(gridCell, out var cellList)) { - _grid[gridCell] = new List(); + cellList = new List(); + _grid[gridCell] = cellList; } - _grid[gridCell].Add(item); + cellList.Add(item); } /// @@ -111,8 +118,11 @@ namespace NavisworksTransport.Core.Spatial var results = new HashSet(); // 计算需要检查的格子范围 - int gridRadius = (int)Math.Ceiling(radius / _cellSize); - var centerGrid = ToGridCoordinates(center); + int gridRadius = (int)Math.Ceiling(radius / _indexer.CellSize); + var centerGrid = _indexer.ToGrid(center); + + // 优化:提前创建忽略函数,避免在循环中检查 null(借鉴 PointHashGrid3d) + bool hasDistanceCheck = (distanceFunc != null); // 遍历查询范围内的所有格子 for (int dx = -gridRadius; dx <= gridRadius; dx++) @@ -127,12 +137,13 @@ namespace NavisworksTransport.Core.Spatial centerGrid.z + dz ); + // 使用 TryGetValue 避免两次字典查找(借鉴 PointHashGrid3d) if (_grid.TryGetValue(gridCell, out var cellObjects)) { foreach (var obj in cellObjects) { // 如果提供了距离函数,进行精确距离检查 - if (distanceFunc != null) + if (hasDistanceCheck) { double distance = distanceFunc(obj); if (distance <= radius) @@ -185,21 +196,7 @@ namespace NavisworksTransport.Core.Spatial } /// - /// 将世界坐标转换为网格坐标 - /// - /// 世界坐标 - /// 网格坐标 - private Vector3i ToGridCoordinates(Vector3d position) - { - return new Vector3i( - (int)Math.Floor(position.x / _cellSize), - (int)Math.Floor(position.y / _cellSize), - (int)Math.Floor(position.z / _cellSize) - ); - } - - /// - /// 获取网格统计信息(用于调试) + /// 获取网格统计信息(用于调试和性能分析) /// /// 统计信息字符串 public string GetStatistics() @@ -230,7 +227,7 @@ namespace NavisworksTransport.Core.Spatial minObjectsPerCell = 0; return $"空间哈希网格统计:\n" + - $" 格子大小: {_cellSize:F2} 模型单位\n" + + $" 格子大小: {_indexer.CellSize:F2} 模型单位\n" + $" 总格子数: {_grid.Count}\n" + $" 总对象数: {totalObjects}\n" + $" 平均每格对象数: {avgObjectsPerCell:F2}\n" +