From 9f42c6f38168f973600b6866ddf80199dfc3def1 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Sun, 7 Sep 2025 00:45:45 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=BD=91=E6=A0=BC=E7=82=B9?=
=?UTF-8?q?=E5=A4=A7=E5=B0=8F=E4=B8=BA=E8=87=AA=E9=80=82=E5=BA=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
NavisworksTransportPlugin.csproj | 2 +-
src/Core/PathPlanningManager.cs | 27 +++++++-----
src/Core/PathPointRenderPlugin.cs | 34 ++++++++++++---
src/PathPlanning/AutoPathFinder.cs | 19 ++++-----
src/PathPlanning/ChannelBasedGridBuilder.cs | 4 +-
src/PathPlanning/ChannelHeightDetector.cs | 16 ++++----
src/PathPlanning/GridMap.cs | 41 +++++++++----------
src/PathPlanning/GridMapGenerator.cs | 18 ++++----
.../{Point2D.cs => GridPoint2D.cs} | 28 ++++++-------
9 files changed, 108 insertions(+), 81 deletions(-)
rename src/PathPlanning/{Point2D.cs => GridPoint2D.cs} (79%)
diff --git a/NavisworksTransportPlugin.csproj b/NavisworksTransportPlugin.csproj
index 670764d..b4de73a 100644
--- a/NavisworksTransportPlugin.csproj
+++ b/NavisworksTransportPlugin.csproj
@@ -149,7 +149,7 @@
-
+
diff --git a/src/Core/PathPlanningManager.cs b/src/Core/PathPlanningManager.cs
index 0331435..6953574 100644
--- a/src/Core/PathPlanningManager.cs
+++ b/src/Core/PathPlanningManager.cs
@@ -921,18 +921,20 @@ namespace NavisworksTransport
throw new Exception($"路径查找失败: {ex.Message}", ex);
}
- if (pathResult == null || pathResult.PathPoints.Count < 2)
+ // 1. 检查路径查找是否完全失败
+ if (pathResult == null)
{
- if (pathResult != null && !pathResult.IsComplete)
- {
- throw new Exception($"路径不完整,只能到达 {pathResult.CompletionPercentage:F1}% 的目标距离");
- }
- else
- {
- throw new Exception("未找到可行路径");
- }
+ throw new Exception("路径查找失败");
}
+ // 2. 检查是否找到了可用的路径点(至少2个点才能构成路径)
+ if (pathResult.PathPoints.Count < 2)
+ {
+ throw new Exception("未找到可行路径(起点或终点不可达)");
+ }
+
+ // 3. 部分路径也是有效路径,不再抛出异常,继续正常处理
+
LogManager.Info($"A*算法找到路径,包含 {pathResult.PathPoints.Count} 个点,完成度: {pathResult.CompletionPercentage:F1}%");
// 6. 创建PathRoute对象
@@ -3124,6 +3126,11 @@ namespace NavisworksTransport
return;
}
+ // 设置网格大小以实现自适应点大小
+ // gridMap.CellSize是模型单位,需要转换为米
+ double gridSizeInMeters = UnitsConverter.ConvertToMeters(gridMap.CellSize);
+ renderPlugin.SetGridSize(gridSizeInMeters);
+
// 清除之前的网格可视化
ClearGridVisualization();
@@ -3158,7 +3165,7 @@ namespace NavisworksTransport
var cell = gridMap.Cells[x, y];
// 计算网格单元格的世界中心位置
- var gridPos = new NavisworksTransport.PathPlanning.Point2D(x, y);
+ var gridPos = new NavisworksTransport.PathPlanning.GridPoint2D(x, y);
var worldCenter = gridMap.GridToWorld3D(gridPos, cell.WorldPosition.Z);
var visualizationPoint = worldCenter;
diff --git a/src/Core/PathPointRenderPlugin.cs b/src/Core/PathPointRenderPlugin.cs
index 417ef8f..f1569b3 100644
--- a/src/Core/PathPointRenderPlugin.cs
+++ b/src/Core/PathPointRenderPlugin.cs
@@ -113,6 +113,9 @@ namespace NavisworksTransport
// 预览连线标记
private List _previewLines = new List();
+ // 当前网格大小(米),用于自适应点大小计算
+ private double _currentGridSizeInMeters = 0.5;
+
// 静态实例,用于外部访问
private static PathPointRenderPlugin _instance;
@@ -564,7 +567,7 @@ namespace NavisworksTransport
{
Center = point.Position,
Normal = new Vector3D(0, 0, 1),
- Radius = isGridVisualization ? GetRadiusForGridVisualization() : GetRadiusForPointType(point.Type),
+ Radius = isGridVisualization ? GetRadiusForGridVisualization(_currentGridSizeInMeters) : GetRadiusForPointType(point.Type),
Color = isGridVisualization ? gridColor : GetColorForPointType(point.Type),
Alpha = 1.0,
Filled = true,
@@ -578,12 +581,33 @@ namespace NavisworksTransport
/// 获取网格可视化小球的半径(比正常路径点小)
///
/// 网格可视化半径
- private double GetRadiusForGridVisualization()
+ private double GetRadiusForGridVisualization(double gridSizeInMeters = 0.5)
{
- // 网格可视化小球使用0.1米的物理尺寸(原来的一半),比正常路径点更小
- double baseRadiusInMeters = 0.1;
+ // 实现自适应网格点大小逻辑:
+ // - 小于0.5米:用网格大小的1/5
+ // - 大于等于0.5米:固定使用0.1米
+ double radiusInMeters;
+ if (gridSizeInMeters < 0.5)
+ {
+ radiusInMeters = gridSizeInMeters / 5.0;
+ }
+ else
+ {
+ radiusInMeters = 0.1;
+ }
+
double metersToModelUnits = GetMetersToModelUnitsConversionFactor();
- return baseRadiusInMeters * metersToModelUnits;
+ return radiusInMeters * metersToModelUnits;
+ }
+
+ ///
+ /// 设置当前网格大小(米),用于自适应点大小计算
+ ///
+ /// 网格大小(米)
+ public void SetGridSize(double gridSizeInMeters)
+ {
+ _currentGridSizeInMeters = gridSizeInMeters;
+ LogManager.WriteLog($"[网格点大小] 设置网格大小: {gridSizeInMeters:F2}米");
}
///
diff --git a/src/PathPlanning/AutoPathFinder.cs b/src/PathPlanning/AutoPathFinder.cs
index f83dfa4..4d6d85d 100644
--- a/src/PathPlanning/AutoPathFinder.cs
+++ b/src/PathPlanning/AutoPathFinder.cs
@@ -333,7 +333,7 @@ namespace NavisworksTransport.PathPlanning
// RoyT.AStar返回的Position是米坐标,需要转换为网格索引
var startGridX = (int)Math.Floor(startNode.Position.X / cellSizeInMeters);
var startGridY = (int)Math.Floor(startNode.Position.Y / cellSizeInMeters);
- var startGridPos = new Point2D(startGridX, startGridY);
+ var startGridPos = new GridPoint2D(startGridX, startGridY);
var startCell = gridMap.GetCell(startGridPos);
var startWorldPos = gridMap.GridToWorld3D(startGridPos, startCell?.WorldPosition.Z ?? 0);
LogManager.Info($"[路径转换] 起始节点: A*米坐标({startNode.Position.X:F2}, {startNode.Position.Y:F2}) -> 网格索引({startGridPos.X}, {startGridPos.Y}) -> 世界坐标({startWorldPos.X:F2}, {startWorldPos.Y:F2}, {startWorldPos.Z:F2})");
@@ -347,7 +347,7 @@ namespace NavisworksTransport.PathPlanning
// RoyT.AStar返回的Position是米坐标,需要转换为网格索引
var gridX = (int)Math.Floor(edge.End.Position.X / cellSizeInMeters);
var gridY = (int)Math.Floor(edge.End.Position.Y / cellSizeInMeters);
- var gridPos = new Point2D(gridX, gridY);
+ var gridPos = new GridPoint2D(gridX, gridY);
var cell = gridMap.GetCell(gridPos);
var worldPos = gridMap.GridToWorld3D(gridPos, cell?.WorldPosition.Z ?? 0);
@@ -445,7 +445,7 @@ namespace NavisworksTransport.PathPlanning
/// 终点网格坐标
/// 网格地图
/// 是否畅通
- private bool IsDirectGridPathClear(Point2D start, Point2D end, GridMap gridMap)
+ private bool IsDirectGridPathClear(GridPoint2D start, GridPoint2D end, GridMap gridMap)
{
// 使用Bresenham直线算法
int x0 = start.X, y0 = start.Y;
@@ -462,7 +462,7 @@ namespace NavisworksTransport.PathPlanning
while (true)
{
// 检查当前网格单元格是否可通行
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (!gridMap.IsValidGridPosition(gridPos) || !gridMap.IsWalkable(gridPos))
{
return false;
@@ -524,10 +524,10 @@ namespace NavisworksTransport.PathPlanning
for (int i = 1; i < path.Count - 1; i++)
{
- var v1 = new Point2D(
+ var v1 = new GridPoint2D(
(int)(path[i].X - path[i - 1].X),
(int)(path[i].Y - path[i - 1].Y));
- var v2 = new Point2D(
+ var v2 = new GridPoint2D(
(int)(path[i + 1].X - path[i].X),
(int)(path[i + 1].Y - path[i].Y));
@@ -590,15 +590,12 @@ namespace NavisworksTransport.PathPlanning
{
var correctedPoint = new Point3D(originalPoint.X, originalPoint.Y, preciseHeight);
correctedPath.Add(correctedPoint);
- correctedCount++;
-
- LogManager.Info($"[高度校正] 点{i}: ({originalPoint.X:F2}, {originalPoint.Y:F2}) 高度校正: {originalPoint.Z:F2} -> {preciseHeight:F2} (使用通道顶面)");
+ correctedCount++;
}
else
{
// 高度已经正确,无需校正
correctedPath.Add(originalPoint);
- LogManager.Debug($"[高度校正] 点{i}: ({originalPoint.X:F2}, {originalPoint.Y:F2}) 高度无需校正: {originalPoint.Z:F2}");
}
}
catch (Exception ex)
@@ -882,7 +879,7 @@ namespace NavisworksTransport.PathPlanning
var lastNode = astarPath.Edges.Last().End;
var actualEndGridX = (int)Math.Floor(lastNode.Position.X / cellSizeInMeters);
var actualEndGridY = (int)Math.Floor(lastNode.Position.Y / cellSizeInMeters);
- var actualEndGrid = new Point2D(actualEndGridX, actualEndGridY);
+ var actualEndGrid = new GridPoint2D(actualEndGridX, actualEndGridY);
var actualEndCell = gridMap.GetCell(actualEndGrid);
var actualEndWorld = gridMap.GridToWorld3D(actualEndGrid, actualEndCell?.WorldPosition.Z ?? 0);
diff --git a/src/PathPlanning/ChannelBasedGridBuilder.cs b/src/PathPlanning/ChannelBasedGridBuilder.cs
index c25720b..93b0367 100644
--- a/src/PathPlanning/ChannelBasedGridBuilder.cs
+++ b/src/PathPlanning/ChannelBasedGridBuilder.cs
@@ -226,7 +226,7 @@ namespace NavisworksTransport.PathPlanning
{
for (int y = minGrid.Y; y <= maxGrid.Y; y++)
{
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (gridMap.IsValidGridPosition(gridPos))
{
var worldPos = gridMap.GridToWorld3D(gridPos, 0); // 2D检测,Z坐标不重要
@@ -248,7 +248,7 @@ namespace NavisworksTransport.PathPlanning
/// 网格地图
/// 网格位置
/// 关联的模型物品
- private void SetCellAsChannel(GridMap gridMap, Point2D gridPos, ModelItem relatedItem)
+ private void SetCellAsChannel(GridMap gridMap, GridPoint2D gridPos, ModelItem relatedItem)
{
// 使用GridMap提供的方法设置通道单元格
gridMap.SetCellAsChannel(gridPos, ChannelType.Corridor, relatedItem);
diff --git a/src/PathPlanning/ChannelHeightDetector.cs b/src/PathPlanning/ChannelHeightDetector.cs
index 54c9657..1e29740 100644
--- a/src/PathPlanning/ChannelHeightDetector.cs
+++ b/src/PathPlanning/ChannelHeightDetector.cs
@@ -121,7 +121,7 @@ namespace NavisworksTransport.PathPlanning
{
// 🔥 关键修改:返回通道顶面高度而不是底面高度
var topHeight = cachedInfo.CeilingHeight;
- LogManager.Info($"[高度检测] 使用缓存的顶面高度信息: {topHeight:F2}");
+ //LogManager.Info($"[高度检测] 使用缓存的顶面高度信息: {topHeight:F2}");
return topHeight;
}
@@ -133,7 +133,7 @@ namespace NavisworksTransport.PathPlanning
// 🔥 关键修改:返回通道顶面高度(楼板表面,车辆行驶面)
var topHeight = heightInfo.CeilingHeight;
- LogManager.Info($"[高度检测] 计算得到通道顶面高度: {topHeight:F2}");
+ //LogManager.Info($"[高度检测] 计算得到通道顶面高度: {topHeight:F2}");
return topHeight;
}
@@ -459,7 +459,7 @@ namespace NavisworksTransport.PathPlanning
}
// 将3D世界坐标投影到屏幕坐标
- if (TryProjectWorldToScreen(position, activeView, out Point2D screenPoint))
+ if (TryProjectWorldToScreen(position, activeView, out GridPoint2D screenPoint))
{
// 检查屏幕坐标是否在视图范围内
if (screenPoint.X >= 0 && screenPoint.X < activeView.Width &&
@@ -510,16 +510,16 @@ namespace NavisworksTransport.PathPlanning
///
/// 将3D世界坐标投影到屏幕坐标
///
- private bool TryProjectWorldToScreen(Point3D worldPoint, View view, out Point2D screenPoint)
+ private bool TryProjectWorldToScreen(Point3D worldPoint, View view, out GridPoint2D screenPoint)
{
- screenPoint = new Point2D(0, 0);
+ screenPoint = new GridPoint2D(0, 0);
try
{
// 使用Navisworks View API的ProjectPoint方法进行精确投影
var projectionResult = view.ProjectPoint(worldPoint, false, false);
if (projectionResult != null)
{
- screenPoint = new Point2D((int)projectionResult.X, (int)projectionResult.Y);
+ screenPoint = new GridPoint2D((int)projectionResult.X, (int)projectionResult.Y);
LogManager.Debug($"[投影] 3D世界坐标 ({worldPoint.X:F2}, {worldPoint.Y:F2}, {worldPoint.Z:F2}) 投影到屏幕坐标 ({projectionResult.X:F1}, {projectionResult.Y:F1})");
return true;
}
@@ -620,7 +620,7 @@ namespace NavisworksTransport.PathPlanning
var testPoint = new Point3D(position.X, position.Y, testHeight);
// 将3D点投影到屏幕
- if (TryProjectWorldToScreen(testPoint, activeView, out Point2D screenPoint))
+ if (TryProjectWorldToScreen(testPoint, activeView, out GridPoint2D screenPoint))
{
// 检查屏幕坐标是否在视图范围内
if (screenPoint.X >= 0 && screenPoint.X < activeView.Width &&
@@ -762,7 +762,7 @@ namespace NavisworksTransport.PathPlanning
foreach (var samplePoint in samplePoints)
{
- if (TryProjectWorldToScreen(samplePoint, activeView, out Point2D screenPoint))
+ if (TryProjectWorldToScreen(samplePoint, activeView, out GridPoint2D screenPoint))
{
if (screenPoint.X >= 0 && screenPoint.X < activeView.Width &&
screenPoint.Y >= 0 && screenPoint.Y < activeView.Height)
diff --git a/src/PathPlanning/GridMap.cs b/src/PathPlanning/GridMap.cs
index 2c83f30..18206ea 100644
--- a/src/PathPlanning/GridMap.cs
+++ b/src/PathPlanning/GridMap.cs
@@ -154,8 +154,7 @@ namespace NavisworksTransport.PathPlanning
for (int y = 0; y < Height; y++)
{
// 只计算2D世界坐标,Z坐标将在有规划点信息后单独设置
- var world2D = GridToWorld2D(new Point2D(x, y));
- var worldPos = new Point3D(world2D.X, world2D.Y, 0); // Z坐标暂时设为0
+ var worldPos = GridToWorld2D(new GridPoint2D(x, y)); // 直接使用返回的Point3D,Z=0
var cell = new GridCell
{
@@ -177,12 +176,12 @@ namespace NavisworksTransport.PathPlanning
///
/// 世界坐标点
/// 网格坐标(可能超出边界)
- public Point2D WorldToGrid(Point3D worldPosition)
+ public GridPoint2D WorldToGrid(Point3D worldPosition)
{
double gridX = (worldPosition.X - Origin.X) / CellSize;
double gridY = (worldPosition.Y - Origin.Y) / CellSize;
- return new Point2D((int)Math.Floor(gridX), (int)Math.Floor(gridY));
+ return new GridPoint2D((int)Math.Floor(gridX), (int)Math.Floor(gridY));
}
///
@@ -190,12 +189,12 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格坐标
/// 世界2D坐标点
- public Point2D GridToWorld2D(Point2D gridPosition)
+ public Point3D GridToWorld2D(GridPoint2D gridPosition)
{
double worldX = Origin.X + (gridPosition.X + 0.5) * CellSize;
double worldY = Origin.Y + (gridPosition.Y + 0.5) * CellSize;
- return new Point2D((int)worldX, (int)worldY);
+ return new Point3D(worldX, worldY, 0); // Z设为0,调用者可以替换
}
///
@@ -204,7 +203,7 @@ namespace NavisworksTransport.PathPlanning
/// 网格坐标
/// Z坐标值
/// 世界3D坐标点
- public Point3D GridToWorld3D(Point2D gridPosition, double z)
+ public Point3D GridToWorld3D(GridPoint2D gridPosition, double z)
{
var world2D = GridToWorld2D(gridPosition);
return new Point3D(world2D.X, world2D.Y, z);
@@ -261,7 +260,7 @@ namespace NavisworksTransport.PathPlanning
for (int y = 0; y < Height; y++)
{
var cell = Cells[x, y];
- var world2D = GridToWorld2D(new Point2D(x, y));
+ var world2D = GridToWorld2D(new GridPoint2D(x, y));
double interpolatedZ = CalculateInterpolatedZ(world2D.X, world2D.Y);
// 更新单元格的WorldPosition.Z坐标
@@ -278,7 +277,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格坐标
/// 是否有效
- public bool IsValidGridPosition(Point2D gridPosition)
+ public bool IsValidGridPosition(GridPoint2D gridPosition)
{
return gridPosition.X >= 0 && gridPosition.X < Width &&
gridPosition.Y >= 0 && gridPosition.Y < Height;
@@ -289,7 +288,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格坐标
/// 是否可通行
- public bool IsWalkable(Point2D gridPosition)
+ public bool IsWalkable(GridPoint2D gridPosition)
{
if (!IsValidGridPosition(gridPosition))
return false;
@@ -304,7 +303,7 @@ namespace NavisworksTransport.PathPlanning
/// 是否可通行
/// 遍历成本
/// 单元格类型
- public void SetCell(Point2D gridPosition, bool isWalkable, double cost, CategoryAttributeManager.LogisticsElementType cellType)
+ public void SetCell(GridPoint2D gridPosition, bool isWalkable, double cost, CategoryAttributeManager.LogisticsElementType cellType)
{
if (!IsValidGridPosition(gridPosition))
return;
@@ -343,7 +342,7 @@ namespace NavisworksTransport.PathPlanning
/// 网格坐标
/// 通道类型
/// 关联的模型物品
- public void SetCellAsChannel(Point2D gridPosition, ChannelType channelType = ChannelType.Corridor, ModelItem relatedItem = null)
+ public void SetCellAsChannel(GridPoint2D gridPosition, ChannelType channelType = ChannelType.Corridor, ModelItem relatedItem = null)
{
if (!IsValidGridPosition(gridPosition))
return;
@@ -369,7 +368,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格坐标
/// 高度区间
- public void AddPassableHeight(Point2D gridPosition, HeightInterval heightInterval)
+ public void AddPassableHeight(GridPoint2D gridPosition, HeightInterval heightInterval)
{
if (!IsValidGridPosition(gridPosition))
return;
@@ -389,7 +388,7 @@ namespace NavisworksTransport.PathPlanning
/// 网格坐标
/// 检查的高度
/// 是否可通行
- public bool IsPassableAtHeight(Point2D gridPosition, double height)
+ public bool IsPassableAtHeight(GridPoint2D gridPosition, double height)
{
if (!IsValidGridPosition(gridPosition))
return false;
@@ -410,9 +409,9 @@ namespace NavisworksTransport.PathPlanning
/// 获取所有通道类型的网格单元
///
/// 通道网格单元列表
- public List<(Point2D Position, GridCell Cell)> GetChannelCells()
+ public List<(GridPoint2D Position, GridCell Cell)> GetChannelCells()
{
- var channelCells = new List<(Point2D Position, GridCell Cell)>();
+ var channelCells = new List<(GridPoint2D Position, GridCell Cell)>();
for (int x = 0; x < Width; x++)
{
@@ -421,7 +420,7 @@ namespace NavisworksTransport.PathPlanning
var cell = Cells[x, y];
if (cell.IsInChannel || cell.CellType == CategoryAttributeManager.LogisticsElementType.通道)
{
- channelCells.Add((new Point2D(x, y), cell));
+ channelCells.Add((new GridPoint2D(x, y), cell));
}
}
}
@@ -506,7 +505,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 网格坐标
/// 单元格信息
- public GridCell? GetCell(Point2D gridPosition)
+ public GridCell? GetCell(GridPoint2D gridPosition)
{
if (!IsValidGridPosition(gridPosition))
return null;
@@ -623,17 +622,17 @@ namespace NavisworksTransport.PathPlanning
var stats = $"=== 网格统计详细信息 ===\n";
stats += $"网格尺寸: {Width}x{Height} (总计 {Width * Height} 个单元格)\n";
- stats += $"总体分布: 可通行 {totalWalkable} 个, 不可通行 {totalNonWalkable} 个\n\n";
+ stats += $"总体分布: 可通行 {totalWalkable} 个, 不可通行 {totalNonWalkable} 个\n";
stats += $"【可通行单元格详细统计】\n";
stats += $" 楼板: {walkable_楼板}, 通道: {walkable_通道}, 走廊: {walkable_走廊}\n";
stats += $" 门: {walkable_门}, 装卸区: {walkable_装卸区}, 停车位: {walkable_停车位}\n";
- stats += $" 楼梯: {walkable_楼梯}, 电梯: {walkable_电梯}, 其他: {walkable_Other}\n\n";
+ stats += $" 楼梯: {walkable_楼梯}, 电梯: {walkable_电梯}, 其他: {walkable_Other}\n";
stats += $"【不可通行单元格详细统计】\n";
stats += $" Unknown/空洞: {nonWalkable_Unknown}, 障碍物: {nonWalkable_障碍物}\n";
stats += $" 不可通行楼板: {nonWalkable_楼板}, 不可通行门: {nonWalkable_门}\n";
- stats += $" 不可通行通道: {nonWalkable_通道}, 其他不可通行: {nonWalkable_Other}\n\n";
+ stats += $" 不可通行通道: {nonWalkable_通道}, 其他不可通行: {nonWalkable_Other}\n";
stats += $"内存使用: {GetMemoryUsage() / 1024.0:F1} KB";
diff --git a/src/PathPlanning/GridMapGenerator.cs b/src/PathPlanning/GridMapGenerator.cs
index 45ed44e..cd7d272 100644
--- a/src/PathPlanning/GridMapGenerator.cs
+++ b/src/PathPlanning/GridMapGenerator.cs
@@ -309,7 +309,7 @@ namespace NavisworksTransport.PathPlanning
if (cell.CellType == CategoryAttributeManager.LogisticsElementType.通道 && cell.IsInChannel)
{
// 使用网格的实际Z坐标
- var worldPos = gridMap.GridToWorld3D(new Point2D(x, y), cell.WorldPosition.Z);
+ var worldPos = gridMap.GridToWorld3D(new GridPoint2D(x, y), cell.WorldPosition.Z);
// 重要修复:使用通道顶面作为垂直扫描的起点,而不是底面
// 从通道构建器的日志可知通道总边界MaxZ = 38.8,这是正确的扫描起点
@@ -402,7 +402,7 @@ namespace NavisworksTransport.PathPlanning
{
// 通道区域有足够净空高度,设置为可通行
// 🔥 关键修复:使用SetCell方法正确更新网格统计
- var gridPos = new Point2D(gridX, gridY);
+ var gridPos = new GridPoint2D(gridX, gridY);
gridMap.SetCell(gridPos, true, 1.0, CategoryAttributeManager.LogisticsElementType.通道);
// 设置世界坐标和高度信息
@@ -415,7 +415,7 @@ namespace NavisworksTransport.PathPlanning
else
{
// 通道区域但净空高度不足,标记为不可通行但保持通道类型
- var gridPos = new Point2D(gridX, gridY);
+ var gridPos = new GridPoint2D(gridX, gridY);
gridMap.SetCell(gridPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.通道);
// 设置世界坐标和高度信息
@@ -758,7 +758,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 标记大型障碍物的边界轮廓,而不是完全填充
///
- private void MarkLargeObstacleBoundary(GridMap gridMap, Point2D minGrid, Point2D maxGrid,
+ private void MarkLargeObstacleBoundary(GridMap gridMap, GridPoint2D minGrid, GridPoint2D maxGrid,
ref int newlyMarkedCells, ref int totalMarkedCells)
{
try
@@ -772,7 +772,7 @@ namespace NavisworksTransport.PathPlanning
// 上边界
for (int y = Math.Max(0, minGrid.Y); y <= Math.Min(gridMap.Height - 1, Math.Min(maxGrid.Y, minGrid.Y + boundaryThickness - 1)); y++)
{
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (gridMap.IsWalkable(gridPos))
{
gridMap.SetCell(gridPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.障碍物);
@@ -784,7 +784,7 @@ namespace NavisworksTransport.PathPlanning
// 下边界
for (int y = Math.Max(0, Math.Max(minGrid.Y, maxGrid.Y - boundaryThickness + 1)); y <= Math.Min(gridMap.Height - 1, maxGrid.Y); y++)
{
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (gridMap.IsWalkable(gridPos))
{
gridMap.SetCell(gridPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.障碍物);
@@ -800,7 +800,7 @@ namespace NavisworksTransport.PathPlanning
// 左边界
for (int x = Math.Max(0, minGrid.X); x <= Math.Min(gridMap.Width - 1, Math.Min(maxGrid.X, minGrid.X + boundaryThickness - 1)); x++)
{
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (gridMap.IsWalkable(gridPos))
{
gridMap.SetCell(gridPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.障碍物);
@@ -812,7 +812,7 @@ namespace NavisworksTransport.PathPlanning
// 右边界
for (int x = Math.Max(0, Math.Max(minGrid.X, maxGrid.X - boundaryThickness + 1)); x <= Math.Min(gridMap.Width - 1, maxGrid.X); x++)
{
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
if (gridMap.IsWalkable(gridPos))
{
gridMap.SetCell(gridPos, false, double.MaxValue, CategoryAttributeManager.LogisticsElementType.障碍物);
@@ -1013,7 +1013,7 @@ namespace NavisworksTransport.PathPlanning
LogManager.Info($"[高效膨胀] 应用进度: {progress:F1}% ({processedCells}/{totalCells})");
}
- var gridPos = new Point2D(x, y);
+ var gridPos = new GridPoint2D(x, y);
// 只有满足以下所有条件才进行膨胀:
// 1. 当前位置原本是可通行的
diff --git a/src/PathPlanning/Point2D.cs b/src/PathPlanning/GridPoint2D.cs
similarity index 79%
rename from src/PathPlanning/Point2D.cs
rename to src/PathPlanning/GridPoint2D.cs
index 50b4f2f..81ec953 100644
--- a/src/PathPlanning/Point2D.cs
+++ b/src/PathPlanning/GridPoint2D.cs
@@ -6,7 +6,7 @@ namespace NavisworksTransport.PathPlanning
/// 2D坐标点结构体
/// 用于网格坐标系统
///
- public struct Point2D
+ public struct GridPoint2D
{
///
/// X坐标
@@ -23,7 +23,7 @@ namespace NavisworksTransport.PathPlanning
///
/// X坐标
/// Y坐标
- public Point2D(int x, int y)
+ public GridPoint2D(int x, int y)
{
X = x;
Y = y;
@@ -34,7 +34,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 另一个点
/// 距离
- public double DistanceTo(Point2D other)
+ public double DistanceTo(GridPoint2D other)
{
double dx = other.X - X;
double dy = other.Y - Y;
@@ -46,7 +46,7 @@ namespace NavisworksTransport.PathPlanning
///
/// 另一个点
/// 曼哈顿距离
- public int ManhattanDistanceTo(Point2D other)
+ public int ManhattanDistanceTo(GridPoint2D other)
{
return Math.Abs(other.X - X) + Math.Abs(other.Y - Y);
}
@@ -67,7 +67,7 @@ namespace NavisworksTransport.PathPlanning
/// 是否相等
public override bool Equals(object obj)
{
- if (obj is Point2D other)
+ if (obj is GridPoint2D other)
{
return X == other.X && Y == other.Y;
}
@@ -95,7 +95,7 @@ namespace NavisworksTransport.PathPlanning
/// 左操作数
/// 右操作数
/// 是否相等
- public static bool operator ==(Point2D left, Point2D right)
+ public static bool operator ==(GridPoint2D left, GridPoint2D right)
{
return left.Equals(right);
}
@@ -106,7 +106,7 @@ namespace NavisworksTransport.PathPlanning
/// 左操作数
/// 右操作数
/// 是否不相等
- public static bool operator !=(Point2D left, Point2D right)
+ public static bool operator !=(GridPoint2D left, GridPoint2D right)
{
return !left.Equals(right);
}
@@ -117,9 +117,9 @@ namespace NavisworksTransport.PathPlanning
/// 左操作数
/// 右操作数
/// 相加结果
- public static Point2D operator +(Point2D left, Point2D right)
+ public static GridPoint2D operator +(GridPoint2D left, GridPoint2D right)
{
- return new Point2D(left.X + right.X, left.Y + right.Y);
+ return new GridPoint2D(left.X + right.X, left.Y + right.Y);
}
///
@@ -128,24 +128,24 @@ namespace NavisworksTransport.PathPlanning
/// 左操作数
/// 右操作数
/// 相减结果
- public static Point2D operator -(Point2D left, Point2D right)
+ public static GridPoint2D operator -(GridPoint2D left, GridPoint2D right)
{
- return new Point2D(left.X - right.X, left.Y - right.Y);
+ return new GridPoint2D(left.X - right.X, left.Y - right.Y);
}
///
/// 零点常量
///
- public static readonly Point2D Zero = new Point2D(0, 0);
+ public static readonly GridPoint2D Zero = new GridPoint2D(0, 0);
///
/// 单位X向量
///
- public static readonly Point2D UnitX = new Point2D(1, 0);
+ public static readonly GridPoint2D UnitX = new GridPoint2D(1, 0);
///
/// 单位Y向量
///
- public static readonly Point2D UnitY = new Point2D(0, 1);
+ public static readonly GridPoint2D UnitY = new GridPoint2D(0, 1);
}
}
\ No newline at end of file