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" +