修改网格点大小为自适应

This commit is contained in:
tian 2025-09-07 00:45:45 +08:00
parent eba60b23c7
commit 9f42c6f381
9 changed files with 108 additions and 81 deletions

View File

@ -149,7 +149,7 @@
<Compile Include="src\PathPlanning\GridMap.cs" />
<Compile Include="src\PathPlanning\GridMapGenerator.cs" />
<Compile Include="src\PathPlanning\AutoPathFinder.cs" />
<Compile Include="src\PathPlanning\Point2D.cs" />
<Compile Include="src\PathPlanning\GridPoint2D.cs" />
<Compile Include="src\PathPlanning\AutoPathPlanningValidationResult.cs" />
<Compile Include="src\PathPlanning\ChannelHeightDetector.cs" />
<Compile Include="src\PathPlanning\SlopeAnalyzer.cs" />

View File

@ -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;

View File

@ -113,6 +113,9 @@ namespace NavisworksTransport
// 预览连线标记
private List<LineMarker> _previewLines = new List<LineMarker>();
// 当前网格大小(米),用于自适应点大小计算
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
/// 获取网格可视化小球的半径(比正常路径点小)
/// </summary>
/// <returns>网格可视化半径</returns>
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;
}
/// <summary>
/// 设置当前网格大小(米),用于自适应点大小计算
/// </summary>
/// <param name="gridSizeInMeters">网格大小(米)</param>
public void SetGridSize(double gridSizeInMeters)
{
_currentGridSizeInMeters = gridSizeInMeters;
LogManager.WriteLog($"[网格点大小] 设置网格大小: {gridSizeInMeters:F2}米");
}
/// <summary>

View File

@ -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
/// <param name="end">终点网格坐标</param>
/// <param name="gridMap">网格地图</param>
/// <returns>是否畅通</returns>
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);

View File

@ -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
/// <param name="gridMap">网格地图</param>
/// <param name="gridPos">网格位置</param>
/// <param name="relatedItem">关联的模型物品</param>
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);

View File

@ -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
/// <summary>
/// 将3D世界坐标投影到屏幕坐标
/// </summary>
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)

View File

@ -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)); // 直接使用返回的Point3DZ=0
var cell = new GridCell
{
@ -177,12 +176,12 @@ namespace NavisworksTransport.PathPlanning
/// </summary>
/// <param name="worldPosition">世界坐标点</param>
/// <returns>网格坐标(可能超出边界)</returns>
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));
}
/// <summary>
@ -190,12 +189,12 @@ namespace NavisworksTransport.PathPlanning
/// </summary>
/// <param name="gridPosition">网格坐标</param>
/// <returns>世界2D坐标点</returns>
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调用者可以替换
}
/// <summary>
@ -204,7 +203,7 @@ namespace NavisworksTransport.PathPlanning
/// <param name="gridPosition">网格坐标</param>
/// <param name="z">Z坐标值</param>
/// <returns>世界3D坐标点</returns>
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
/// </summary>
/// <param name="gridPosition">网格坐标</param>
/// <returns>是否有效</returns>
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
/// </summary>
/// <param name="gridPosition">网格坐标</param>
/// <returns>是否可通行</returns>
public bool IsWalkable(Point2D gridPosition)
public bool IsWalkable(GridPoint2D gridPosition)
{
if (!IsValidGridPosition(gridPosition))
return false;
@ -304,7 +303,7 @@ namespace NavisworksTransport.PathPlanning
/// <param name="isWalkable">是否可通行</param>
/// <param name="cost">遍历成本</param>
/// <param name="cellType">单元格类型</param>
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
/// <param name="gridPosition">网格坐标</param>
/// <param name="channelType">通道类型</param>
/// <param name="relatedItem">关联的模型物品</param>
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
/// </summary>
/// <param name="gridPosition">网格坐标</param>
/// <param name="heightInterval">高度区间</param>
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
/// <param name="gridPosition">网格坐标</param>
/// <param name="height">检查的高度</param>
/// <returns>是否可通行</returns>
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
/// 获取所有通道类型的网格单元
/// </summary>
/// <returns>通道网格单元列表</returns>
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
/// </summary>
/// <param name="gridPosition">网格坐标</param>
/// <returns>单元格信息</returns>
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";

View File

@ -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
/// <summary>
/// 标记大型障碍物的边界轮廓,而不是完全填充
/// </summary>
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. 当前位置原本是可通行的

View File

@ -6,7 +6,7 @@ namespace NavisworksTransport.PathPlanning
/// 2D坐标点结构体
/// 用于网格坐标系统
/// </summary>
public struct Point2D
public struct GridPoint2D
{
/// <summary>
/// X坐标
@ -23,7 +23,7 @@ namespace NavisworksTransport.PathPlanning
/// </summary>
/// <param name="x">X坐标</param>
/// <param name="y">Y坐标</param>
public Point2D(int x, int y)
public GridPoint2D(int x, int y)
{
X = x;
Y = y;
@ -34,7 +34,7 @@ namespace NavisworksTransport.PathPlanning
/// </summary>
/// <param name="other">另一个点</param>
/// <returns>距离</returns>
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
/// </summary>
/// <param name="other">另一个点</param>
/// <returns>曼哈顿距离</returns>
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
/// <returns>是否相等</returns>
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
/// <param name="left">左操作数</param>
/// <param name="right">右操作数</param>
/// <returns>是否相等</returns>
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
/// <param name="left">左操作数</param>
/// <param name="right">右操作数</param>
/// <returns>是否不相等</returns>
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
/// <param name="left">左操作数</param>
/// <param name="right">右操作数</param>
/// <returns>相加结果</returns>
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);
}
/// <summary>
@ -128,24 +128,24 @@ namespace NavisworksTransport.PathPlanning
/// <param name="left">左操作数</param>
/// <param name="right">右操作数</param>
/// <returns>相减结果</returns>
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);
}
/// <summary>
/// 零点常量
/// </summary>
public static readonly Point2D Zero = new Point2D(0, 0);
public static readonly GridPoint2D Zero = new GridPoint2D(0, 0);
/// <summary>
/// 单位X向量
/// </summary>
public static readonly Point2D UnitX = new Point2D(1, 0);
public static readonly GridPoint2D UnitX = new GridPoint2D(1, 0);
/// <summary>
/// 单位Y向量
/// </summary>
public static readonly Point2D UnitY = new Point2D(0, 1);
public static readonly GridPoint2D UnitY = new GridPoint2D(0, 1);
}
}