修改网格点大小为自适应
This commit is contained in:
parent
eba60b23c7
commit
9f42c6f381
@ -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" />
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
/// </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";
|
||||
|
||||
|
||||
@ -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. 当前位置原本是可通行的
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user