优化吊装路径点处理,禁止删除关键点并在删除后自动优化路径
This commit is contained in:
parent
60bbd468d8
commit
da89105269
@ -1893,12 +1893,135 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测两点之间是否为斜线,如果是则插入中间转折点或修正坐标
|
||||
/// </summary>
|
||||
/// <param name="points">路径点列表</param>
|
||||
/// <param name="startIndex">开始检查的索引</param>
|
||||
/// <returns>是否进行了修改(插入点或修正坐标)</returns>
|
||||
private bool InsertIntermediatePointForDiagonal(IList<PathPoint> points, int startIndex)
|
||||
{
|
||||
if (points == null || startIndex < 0 || startIndex >= points.Count - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentPoint = points[startIndex];
|
||||
var nextPoint = points[startIndex + 1];
|
||||
|
||||
LogManager.Info($"[斜线处理] 检查索引 {startIndex} 和 {startIndex + 1} 之间的连线");
|
||||
LogManager.Info($"[斜线处理] 当前点 [{startIndex}]: {currentPoint.Name}, 位置: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
LogManager.Info($"[斜线处理] 下一点 [{startIndex + 1}]: {nextPoint.Name}, 位置: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
|
||||
|
||||
double deltaX = Math.Abs(nextPoint.Position.X - currentPoint.Position.X);
|
||||
double deltaY = Math.Abs(nextPoint.Position.Y - currentPoint.Position.Y);
|
||||
|
||||
// 检测斜线(X和Y都变化)
|
||||
bool isDiagonal = deltaX > 0.01 && deltaY > 0.01;
|
||||
|
||||
if (!isDiagonal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 区分两种情况:
|
||||
// 1. 真正的斜线:deltaX和deltaY都比较大(>2.0)→ 插入中间点
|
||||
// 2. 微小偏差:其中一个值很小(<0.5)→ 修改下一点坐标,使其与上一点对齐
|
||||
|
||||
if (deltaX > 2.0 && deltaY > 2.0)
|
||||
{
|
||||
// 真正的斜线:插入中间点
|
||||
LogManager.Info($"[斜线处理] 检测到斜线,需要插入中间点 (deltaX={deltaX:F2}, deltaY={deltaY:F2})");
|
||||
|
||||
int intermediateIndex = points.Count > 0 ? points.Count : 1;
|
||||
var intermediatePoint = new PathPoint(
|
||||
new Point3D(
|
||||
nextPoint.Position.X, // 使用新点的X
|
||||
currentPoint.Position.Y, // 保持上一个点的Y
|
||||
currentPoint.Position.Z // 保持吊装高度
|
||||
),
|
||||
$"路径点{intermediateIndex}",
|
||||
PathPointType.WayPoint);
|
||||
intermediatePoint.Direction = HoistingPointDirection.Longitudinal; // 纵向移动
|
||||
|
||||
int insertPosition = startIndex + 1;
|
||||
points.Insert(insertPosition, intermediatePoint);
|
||||
|
||||
// 更新所有点的索引
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
points[i].Index = i;
|
||||
}
|
||||
|
||||
LogManager.Info($"[斜线处理] 已插入中间点: {intermediatePoint.Name}, 位置: ({intermediatePoint.Position.X:F2}, {intermediatePoint.Position.Y:F2}, {intermediatePoint.Position.Z:F2}) - 方向: 纵向");
|
||||
LogManager.Info($"[斜线处理] 插入位置: 索引 {insertPosition}, 当前路径点总数: {points.Count}");
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (deltaX < 0.5 && deltaY > 0.5)
|
||||
{
|
||||
// X方向微小偏差,Y方向移动:修改下一点坐标,保持X与上一点对齐(垂直线)
|
||||
LogManager.Info($"[斜线处理] 检测到X方向微小偏差 (deltaX={deltaX:F2}, deltaY={deltaY:F2}),修正下一点坐标使其垂直");
|
||||
|
||||
nextPoint.Position = new Point3D(
|
||||
currentPoint.Position.X, // 保持上一个点的X
|
||||
nextPoint.Position.Y, // 保持新点的Y
|
||||
nextPoint.Position.Z); // 保持新点的Z
|
||||
|
||||
LogManager.Info($"[斜线处理] 已修正下一点 {nextPoint.Name} 坐标: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
|
||||
return true;
|
||||
}
|
||||
else if (deltaY < 0.5 && deltaX > 0.5)
|
||||
{
|
||||
// Y方向微小偏差,X方向移动:修改下一点坐标,保持Y与上一点对齐(水平线)
|
||||
LogManager.Info($"[斜线处理] 检测到Y方向微小偏差 (deltaX={deltaX:F2}, deltaY={deltaY:F2}),修正下一点坐标使其水平");
|
||||
|
||||
nextPoint.Position = new Point3D(
|
||||
nextPoint.Position.X, // 保持新点的X
|
||||
currentPoint.Position.Y, // 保持上一个点的Y
|
||||
nextPoint.Position.Z); // 保持新点的Z
|
||||
|
||||
LogManager.Info($"[斜线处理] 已修正下一点 {nextPoint.Name} 坐标: ({nextPoint.Position.X:F2}, {nextPoint.Position.Y:F2}, {nextPoint.Position.Z:F2})");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 中等程度的偏差,插入中间点
|
||||
LogManager.Info($"[斜线处理] 检测到中等程度斜线,需要插入中间点 (deltaX={deltaX:F2}, deltaY={deltaY:F2})");
|
||||
|
||||
int intermediateIndex = points.Count > 0 ? points.Count : 1;
|
||||
var intermediatePoint = new PathPoint(
|
||||
new Point3D(
|
||||
nextPoint.Position.X, // 使用新点的X
|
||||
currentPoint.Position.Y, // 保持上一个点的Y
|
||||
currentPoint.Position.Z // 保持吊装高度
|
||||
),
|
||||
$"路径点{intermediateIndex}",
|
||||
PathPointType.WayPoint);
|
||||
intermediatePoint.Direction = HoistingPointDirection.Longitudinal; // 纵向移动
|
||||
|
||||
int insertPosition = startIndex + 1;
|
||||
points.Insert(insertPosition, intermediatePoint);
|
||||
|
||||
// 更新所有点的索引
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
{
|
||||
points[i].Index = i;
|
||||
}
|
||||
|
||||
LogManager.Info($"[斜线处理] 已插入中间点: {intermediatePoint.Name}, 位置: ({intermediatePoint.Position.X:F2}, {intermediatePoint.Position.Y:F2}, {intermediatePoint.Position.Z:F2}) - 方向: 纵向");
|
||||
LogManager.Info($"[斜线处理] 插入位置: 索引 {insertPosition}, 当前路径点总数: {points.Count}");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 优化直角转折路径点:出现斜线时插入点,在同一直线上时清除多余点
|
||||
/// </summary>
|
||||
/// <param name="route">要优化的路径</param>
|
||||
/// <returns>是否进行了优化</returns>
|
||||
private bool OptimizeRightAnglePathPoints(PathRoute route)
|
||||
public bool OptimizeRightAnglePathPoints(PathRoute route)
|
||||
{
|
||||
if (route == null || route.Points.Count < 2)
|
||||
{
|
||||
@ -1908,79 +2031,96 @@ namespace NavisworksTransport
|
||||
bool hasChanges = false;
|
||||
var points = route.Points;
|
||||
double tolerance = 0.001; // 容差,用于判断是否在同一直线上
|
||||
double smallDeviation = 0.5; // 微小偏差阈值,用于修正坐标
|
||||
double minDistance = 1.0; // 最小距离阈值,小于此距离不删除点
|
||||
|
||||
// 第一步:处理斜线,插入转折点
|
||||
for (int i = 0; i < points.Count - 1; i++)
|
||||
// 第一步:处理斜线,插入转折点或修正坐标
|
||||
// 注意:由于可能插入点,需要从后往前遍历或使用while循环
|
||||
int i = 0;
|
||||
while (i < points.Count - 1)
|
||||
{
|
||||
var currentPoint = points[i];
|
||||
var nextPoint = points[i + 1];
|
||||
|
||||
// 判断是否为斜线(X和Y都不同)
|
||||
bool isDiagonal = (Math.Abs(currentPoint.Position.X - nextPoint.Position.X) > tolerance &&
|
||||
Math.Abs(currentPoint.Position.Y - nextPoint.Position.Y) > tolerance);
|
||||
|
||||
if (isDiagonal)
|
||||
int originalCount = points.Count;
|
||||
if (InsertIntermediatePointForDiagonal(points, i))
|
||||
{
|
||||
// 插入中间转折点
|
||||
Point3D intermediatePosition;
|
||||
HoistingPointDirection direction;
|
||||
|
||||
// 查找提升点的Z坐标作为吊装高度
|
||||
double aerialHeight = currentPoint.Position.Z;
|
||||
for (int j = 0; j < points.Count; j++)
|
||||
hasChanges = true;
|
||||
// 如果插入了点,points.Count会增加
|
||||
// 新插入的点在位置i+1,继续检查从i开始
|
||||
if (points.Count > originalCount)
|
||||
{
|
||||
if (points[j].Name == "提升点")
|
||||
{
|
||||
aerialHeight = points[j].Position.Z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 计算距离差
|
||||
double deltaX = Math.Abs(nextPoint.Position.X - currentPoint.Position.X);
|
||||
double deltaY = Math.Abs(nextPoint.Position.Y - currentPoint.Position.Y);
|
||||
|
||||
if (deltaX > deltaY)
|
||||
{
|
||||
// 纵向移动优先,先移动X
|
||||
intermediatePosition = new Point3D(
|
||||
nextPoint.Position.X,
|
||||
currentPoint.Position.Y,
|
||||
aerialHeight);
|
||||
direction = HoistingPointDirection.Longitudinal;
|
||||
// 插入了点,继续检查当前索引(因为插入点可能需要进一步优化)
|
||||
LogManager.Debug($"[直角路径优化] 索引{i}处插入了点,继续检查");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 横向移动优先,先移动Y
|
||||
intermediatePosition = new Point3D(
|
||||
currentPoint.Position.X,
|
||||
nextPoint.Position.Y,
|
||||
aerialHeight);
|
||||
direction = HoistingPointDirection.Lateral;
|
||||
// 只修改了坐标,继续下一个点
|
||||
i++;
|
||||
}
|
||||
|
||||
// 创建中间路径点
|
||||
var intermediatePoint = new PathPoint(
|
||||
intermediatePosition,
|
||||
$"中间点_{i + 1}",
|
||||
PathPointType.WayPoint);
|
||||
|
||||
// 设置方向属性
|
||||
intermediatePoint.Direction = direction;
|
||||
|
||||
// 插入到两点之间
|
||||
points.Insert(i + 1, intermediatePoint);
|
||||
hasChanges = true;
|
||||
|
||||
LogManager.Debug($"[直角路径优化] 在斜线处插入转折点 {i + 1}: ({intermediatePosition.X:F2}, {intermediatePosition.Y:F2}, {intermediatePosition.Z:F2})");
|
||||
|
||||
// 跳过新插入的点
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 第二步:清除在同一直线上的多余点
|
||||
for (int i = 1; i < points.Count - 1; i++)
|
||||
// 第二步:处理微小转折(X或Y方向微小偏差)
|
||||
for (i = 1; i < points.Count - 1; i++)
|
||||
{
|
||||
var prevPoint = points[i - 1];
|
||||
var currentPoint = points[i];
|
||||
var nextPoint = points[i + 1];
|
||||
|
||||
// 计算两个方向的偏差
|
||||
double deltaX1 = Math.Abs(currentPoint.Position.X - prevPoint.Position.X);
|
||||
double deltaY1 = Math.Abs(currentPoint.Position.Y - prevPoint.Position.Y);
|
||||
double deltaX2 = Math.Abs(nextPoint.Position.X - currentPoint.Position.X);
|
||||
double deltaY2 = Math.Abs(nextPoint.Position.Y - currentPoint.Position.Y);
|
||||
|
||||
// 检测微小转折:前一段和后一段都有微小偏差,但方向不同
|
||||
// 例如:前一段X变化很小,Y变化较大;后一段X变化较大,Y变化很小
|
||||
bool hasSmallTurn = false;
|
||||
|
||||
// 前一段垂直,后一段水平
|
||||
if (deltaX1 < smallDeviation && deltaY1 > smallDeviation &&
|
||||
deltaY2 < smallDeviation && deltaX2 > smallDeviation)
|
||||
{
|
||||
hasSmallTurn = true;
|
||||
}
|
||||
// 前一段水平,后一段垂直
|
||||
else if (deltaY1 < smallDeviation && deltaX1 > smallDeviation &&
|
||||
deltaX2 < smallDeviation && deltaY2 > smallDeviation)
|
||||
{
|
||||
hasSmallTurn = true;
|
||||
}
|
||||
|
||||
if (hasSmallTurn && currentPoint.Type == PathPointType.WayPoint)
|
||||
{
|
||||
// 修正转折点坐标,使其完全垂直
|
||||
if (deltaX1 < smallDeviation)
|
||||
{
|
||||
// 前一段垂直:调整转折点X与上一点对齐
|
||||
currentPoint.Position = new Point3D(
|
||||
prevPoint.Position.X,
|
||||
currentPoint.Position.Y,
|
||||
currentPoint.Position.Z);
|
||||
LogManager.Debug($"[直角路径优化] 修正微小转折点 {i} X坐标: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
hasChanges = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 前一段水平:调整转折点Y与上一点对齐
|
||||
currentPoint.Position = new Point3D(
|
||||
currentPoint.Position.X,
|
||||
prevPoint.Position.Y,
|
||||
currentPoint.Position.Z);
|
||||
LogManager.Debug($"[直角路径优化] 修正微小转折点 {i} Y坐标: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 第三步:清除在同一直线上的多余点
|
||||
i = 1;
|
||||
while (i < points.Count - 1)
|
||||
{
|
||||
var prevPoint = points[i - 1];
|
||||
var currentPoint = points[i];
|
||||
@ -1989,12 +2129,14 @@ namespace NavisworksTransport
|
||||
// 只删除普通的WayPoint,不删除起点、终点、起吊点、提升点、下降点等特殊点
|
||||
if (currentPoint.Type != PathPointType.WayPoint)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 额外检查:不删除提升点和下降点(通过名称识别)
|
||||
if (currentPoint.Name == "提升点" || currentPoint.Name == "下降点")
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2006,16 +2148,29 @@ namespace NavisworksTransport
|
||||
|
||||
bool isCollinear = sameX || sameY;
|
||||
|
||||
// 额外检查:中间点到前后两点的距离都大于最小距离
|
||||
if (isCollinear)
|
||||
{
|
||||
// 删除中间点
|
||||
points.RemoveAt(i);
|
||||
hasChanges = true;
|
||||
LogManager.Debug($"[直角路径优化] 删除共线的多余点 {i}: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
double distToPrev = GeometryHelper.CalculatePointDistance(currentPoint.Position, prevPoint.Position);
|
||||
double distToNext = GeometryHelper.CalculatePointDistance(currentPoint.Position, nextPoint.Position);
|
||||
|
||||
// 调整索引,因为删除了一个点
|
||||
i--;
|
||||
if (distToPrev > minDistance || distToNext > minDistance)
|
||||
{
|
||||
// 删除中间点
|
||||
points.RemoveAt(i);
|
||||
hasChanges = true;
|
||||
LogManager.Debug($"[直角路径优化] 删除共线的多余点 {i}: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
|
||||
// 不调整索引,因为删除了一个点,新位置的点会在下一次循环被检查
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Debug($"[直角路径优化] 跳过距离过近的共线点 {i}: ({currentPoint.Position.X:F2}, {currentPoint.Position.Y:F2}, {currentPoint.Position.Z:F2})");
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if (hasChanges)
|
||||
@ -2045,19 +2200,16 @@ namespace NavisworksTransport
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新路径点位置
|
||||
var pointToUpdate = CurrentRoute.Points[_editingPointIndex];
|
||||
pointToUpdate.Position = _editingPreviewPoint.Position;
|
||||
|
||||
// 吊装路径:自动更新关联点
|
||||
UpdateAerialPathRelatedPoints(CurrentRoute, _editingPointIndex);
|
||||
|
||||
// 吊装路径:优化路径点(处理斜线和清除多余点)
|
||||
// 吊装路径:调用专用方法处理
|
||||
if (CurrentRoute.PathType == PathType.Hoisting)
|
||||
{
|
||||
OptimizeRightAnglePathPoints(CurrentRoute);
|
||||
return UpdateHoistingPathPointPosition();
|
||||
}
|
||||
|
||||
// 更新路径点位置(非吊装路径)
|
||||
var pointToUpdate = CurrentRoute.Points[_editingPointIndex];
|
||||
pointToUpdate.Position = _editingPreviewPoint.Position;
|
||||
|
||||
// 核心修复:调用统一更新函数
|
||||
CurrentRoute.RecalculateAndSaveRoute($"修改路径点 {pointToUpdate.Name} 位置");
|
||||
|
||||
@ -2102,6 +2254,99 @@ namespace NavisworksTransport
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新吊装路径点位置(专用方法)
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 智能处理吊装路径点的坐标更新:
|
||||
/// - 空中路径点(提升点、下降点、中间路径点):只更新XY坐标,保留原有Z坐标(吊装高度)
|
||||
/// - 地面路径点(起吊点、落地点):更新完整XYZ坐标
|
||||
/// </remarks>
|
||||
/// <returns>是否成功更新</returns>
|
||||
private bool UpdateHoistingPathPointPosition()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (PathEditState != PathEditState.EditingPoint ||
|
||||
_editingPointIndex == -1 ||
|
||||
_editingPreviewPoint == null ||
|
||||
CurrentRoute == null)
|
||||
{
|
||||
RaiseErrorOccurred("当前不在修改路径点状态或没有预览点");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新路径点位置(吊装路径:智能处理Z坐标)
|
||||
var pointToUpdate = CurrentRoute.Points[_editingPointIndex];
|
||||
|
||||
// 空中路径点只更新XY坐标,保持原有吊装高度
|
||||
if (pointToUpdate.Name != "起吊点" && pointToUpdate.Name != "落地点")
|
||||
{
|
||||
double originalZ = pointToUpdate.Position.Z;
|
||||
pointToUpdate.Position = new Point3D(
|
||||
_editingPreviewPoint.Position.X,
|
||||
_editingPreviewPoint.Position.Y,
|
||||
originalZ // 保留原有Z坐标(吊装高度)
|
||||
);
|
||||
LogManager.Info($"[修改吊装路径点] 空中路径点 {pointToUpdate.Name},保留原有高度: {originalZ:F3}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 起吊点/落地点使用完整位置
|
||||
pointToUpdate.Position = _editingPreviewPoint.Position;
|
||||
LogManager.Info($"[修改吊装路径点] 地面路径点 {pointToUpdate.Name},更新完整位置");
|
||||
}
|
||||
|
||||
// 吊装路径:自动更新关联点
|
||||
UpdateAerialPathRelatedPoints(CurrentRoute, _editingPointIndex);
|
||||
|
||||
// 吊装路径:优化路径点(处理斜线和清除多余点)
|
||||
OptimizeRightAnglePathPoints(CurrentRoute);
|
||||
|
||||
// 核心修复:调用统一更新函数
|
||||
CurrentRoute.RecalculateAndSaveRoute($"修改吊装路径点 {pointToUpdate.Name} 位置");
|
||||
|
||||
// 添加历史记录
|
||||
var historyEntry = new PathHistoryEntry(
|
||||
CurrentRoute.Id,
|
||||
PathHistoryOperationType.Edited,
|
||||
CurrentRoute,
|
||||
$"修改吊装路径点 {pointToUpdate.Name} 位置");
|
||||
_historyManager.AddHistoryEntry(historyEntry);
|
||||
|
||||
// 清理修改预览可视化(会自动清除预览并重新渲染正常路径)
|
||||
ClearEditingPreviewVisualization();
|
||||
|
||||
// 清理修改状态
|
||||
ClearEditingState();
|
||||
|
||||
// 切换回查看状态
|
||||
PathEditState = PathEditState.Viewing;
|
||||
|
||||
// 停用ToolPlugin
|
||||
DeactivateToolPlugin();
|
||||
|
||||
// 更新可视化
|
||||
DrawRouteVisualization(CurrentRoute, isAutoPath: false);
|
||||
|
||||
// 立即保存到数据库
|
||||
SavePathToDatabase(CurrentRoute);
|
||||
|
||||
// 触发路径点列表更新事件
|
||||
RaisePathPointsListUpdated(CurrentRoute, "路径点修改完成");
|
||||
|
||||
RaiseStatusChanged($"吊装路径点 {pointToUpdate.Name} 修改完成", PathPlanningStatusType.Success);
|
||||
LogManager.Info($"吊装路径点修改完成: {pointToUpdate.Name}");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseErrorOccurred($"确认修改吊装路径点失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消修改路径点
|
||||
/// </summary>
|
||||
@ -2454,22 +2699,85 @@ namespace NavisworksTransport
|
||||
|
||||
try
|
||||
{
|
||||
// 创建正式的路径点
|
||||
var confirmPoint = new PathPoint
|
||||
PathPoint confirmPoint;
|
||||
|
||||
// 吊装路径:使用专门的空中路径点生成逻辑
|
||||
if (CurrentRoute.PathType == PathType.Hoisting)
|
||||
{
|
||||
Name = GeneratePointName(_previewPoint.Type),
|
||||
Position = _previewPoint.Position,
|
||||
Type = _previewPoint.Type
|
||||
};
|
||||
|
||||
// 根据保存的插入索引决定添加方式
|
||||
if (_previewInsertIndex >= 0 && _previewInsertIndex <= CurrentRoute.Points.Count)
|
||||
{
|
||||
CurrentRoute.InsertPoint(confirmPoint, _previewInsertIndex);
|
||||
LogManager.Info($"[预览点-吊装路径] 开始创建空中路径点");
|
||||
|
||||
// 获取上一个路径点
|
||||
Point3D previousPoint;
|
||||
int previousPointIndex;
|
||||
|
||||
if (_previewInsertIndex >= 0 && _previewInsertIndex < CurrentRoute.Points.Count)
|
||||
{
|
||||
// 插入模式:上一个点是插入位置前的一个点
|
||||
previousPointIndex = _previewInsertIndex - 1;
|
||||
previousPoint = CurrentRoute.Points[previousPointIndex].Position;
|
||||
LogManager.Info($"[预览点-吊装路径] 插入模式,上一个点索引: {previousPointIndex}, 名称: {CurrentRoute.Points[previousPointIndex].Name}");
|
||||
}
|
||||
else if (CurrentRoute.Points.Count > 0)
|
||||
{
|
||||
// 追加模式:上一个点是最后一个点
|
||||
previousPointIndex = CurrentRoute.Points.Count - 1;
|
||||
previousPoint = CurrentRoute.Points[previousPointIndex].Position;
|
||||
LogManager.Info($"[预览点-吊装路径] 追加模式,上一个点索引: {previousPointIndex}, 名称: {CurrentRoute.Points[previousPointIndex].Name}");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogManager.Error("[预览点-吊装路径] 没有上一个路径点");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取吊装高度
|
||||
double liftHeightMeters = CurrentRoute.LiftHeightMeters > 0 ? CurrentRoute.LiftHeightMeters : 3.0;
|
||||
|
||||
// 使用 AerialPathGenerator 生成空中路径点
|
||||
var generator = new AerialPathGenerator();
|
||||
confirmPoint = generator.GenerateSmartHoistingPoint(
|
||||
previousPoint,
|
||||
_previewPoint.Position, // 用户点击的地面位置
|
||||
liftHeightMeters,
|
||||
CurrentRoute.Points.Count > 0 ? CurrentRoute.Points.Count : 1);
|
||||
|
||||
LogManager.Info($"[预览点-吊装路径] 已生成空中路径点: {confirmPoint.Name}, 位置: ({confirmPoint.Position.X:F2}, {confirmPoint.Position.Y:F2}, {confirmPoint.Position.Z:F2})");
|
||||
|
||||
// 插入到正确位置
|
||||
if (_previewInsertIndex >= 0 && _previewInsertIndex <= CurrentRoute.Points.Count)
|
||||
{
|
||||
CurrentRoute.InsertPoint(confirmPoint, _previewInsertIndex);
|
||||
LogManager.Info($"[预览点-吊装路径] 已插入到索引 {_previewInsertIndex}");
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentRoute.AddPoint(confirmPoint);
|
||||
LogManager.Info($"[预览点-吊装路径] 已追加到末尾");
|
||||
}
|
||||
|
||||
// 调用路径优化方法处理斜线、微小转折和共线点
|
||||
OptimizeRightAnglePathPoints(CurrentRoute);
|
||||
LogManager.Info($"[预览点-吊装路径] 路径优化完成,当前路径点数: {CurrentRoute.Points.Count}");
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentRoute.AddPoint(confirmPoint);
|
||||
// 非吊装路径:创建普通路径点
|
||||
confirmPoint = new PathPoint
|
||||
{
|
||||
Name = GeneratePointName(_previewPoint.Type),
|
||||
Position = _previewPoint.Position,
|
||||
Type = _previewPoint.Type
|
||||
};
|
||||
|
||||
// 根据保存的插入索引决定添加方式
|
||||
if (_previewInsertIndex >= 0 && _previewInsertIndex <= CurrentRoute.Points.Count)
|
||||
{
|
||||
CurrentRoute.InsertPoint(confirmPoint, _previewInsertIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentRoute.AddPoint(confirmPoint);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除预览状态
|
||||
@ -3190,16 +3498,29 @@ namespace NavisworksTransport
|
||||
|
||||
if (aerialPoint != null)
|
||||
{
|
||||
// 保存上一个路径点的索引(用于插入中间点)
|
||||
int previousPointIndex = CurrentRoute.Points.Count - 1;
|
||||
var previousPathPoint = CurrentRoute.Points[previousPointIndex];
|
||||
LogManager.Info($"[吊装模式] 上一个路径点索引: {previousPointIndex}, 名称: {previousPathPoint.Name}, 位置: ({previousPathPoint.Position.X:F2}, {previousPathPoint.Position.Y:F2})");
|
||||
|
||||
// 记录原始地面点击位置
|
||||
_hoistingGroundIntermediatePoints.Add(clickedPoint);
|
||||
LogManager.Debug($"[吊装模式] 已记录地面点击点: ({clickedPoint.X:F2}, {clickedPoint.Y:F2}, {clickedPoint.Z:F2})");
|
||||
|
||||
// 添加到当前路径
|
||||
// 添加空中路径点(临时)
|
||||
CurrentRoute.AddPoint(aerialPoint);
|
||||
LogManager.Info($"[吊装模式] 已添加空中路径点: {aerialPoint.Name} ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}, {aerialPoint.Position.Z:F2}) - 方向: {aerialPoint.Direction}");
|
||||
LogManager.Info($"[吊装模式] 已添加空中路径点: {aerialPoint.Name}, 位置: ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}), 当前路径点数: {CurrentRoute.Points.Count}");
|
||||
|
||||
// 优化路径点:处理斜线和清除多余点
|
||||
// 调用路径优化方法处理斜线、微小转折和共线点
|
||||
OptimizeRightAnglePathPoints(CurrentRoute);
|
||||
LogManager.Info($"[吊装模式] 路径优化完成,当前路径点数: {CurrentRoute.Points.Count}");
|
||||
for (int i = 0; i < CurrentRoute.Points.Count; i++)
|
||||
{
|
||||
var p = CurrentRoute.Points[i];
|
||||
LogManager.Info($" [{i}] {p.Name}: ({p.Position.X:F2}, {p.Position.Y:F2}, {p.Position.Z:F2})");
|
||||
}
|
||||
|
||||
LogManager.Info($"[吊装模式] 已添加空中路径点: {aerialPoint.Name} ({aerialPoint.Position.X:F2}, {aerialPoint.Position.Y:F2}, {aerialPoint.Position.Z:F2}) - 方向: {aerialPoint.Direction}");
|
||||
|
||||
// 渲染路径
|
||||
if (_renderPlugin != null)
|
||||
|
||||
@ -106,50 +106,35 @@ namespace NavisworksTransport.PathPlanning
|
||||
if (liftHeightMeters <= 0)
|
||||
throw new ArgumentException("提升高度必须大于0", nameof(liftHeightMeters));
|
||||
|
||||
double liftHeightModelUnits = UnitsConverter.ConvertFromMeters(liftHeightMeters);
|
||||
|
||||
// 计算两个方向的距离
|
||||
double deltaX = Math.Abs(clickedGroundPoint.X - previousPoint.X);
|
||||
double deltaY = Math.Abs(clickedGroundPoint.Y - previousPoint.Y);
|
||||
|
||||
Point3D newPoint;
|
||||
HoistingPointDirection direction;
|
||||
string pointName;
|
||||
// 直接使用地面点的完整XY值,不调整位置
|
||||
Point3D newPoint = new Point3D(
|
||||
clickedGroundPoint.X,
|
||||
clickedGroundPoint.Y,
|
||||
previousPoint.Z); // 使用上一个路径点的Z坐标(保持吊装高度)
|
||||
|
||||
// 判断移动方向
|
||||
// 判断移动方向(仅用于记录,不影响位置)
|
||||
HoistingPointDirection direction;
|
||||
if (Math.Abs(deltaX - deltaY) < DIRECTION_TOLERANCE)
|
||||
{
|
||||
// 距离相等,默认选择纵向
|
||||
newPoint = new Point3D(
|
||||
clickedGroundPoint.X,
|
||||
previousPoint.Y,
|
||||
previousPoint.Z); // 使用上一个路径点的Z坐标(保持吊装高度)
|
||||
direction = HoistingPointDirection.Longitudinal;
|
||||
pointName = $"路径点{pointIndex}";
|
||||
}
|
||||
else if (deltaX > deltaY)
|
||||
{
|
||||
// 更偏向纵向移动(X轴)
|
||||
// 保持Y坐标不变,使用点击的X坐标
|
||||
newPoint = new Point3D(
|
||||
clickedGroundPoint.X,
|
||||
previousPoint.Y,
|
||||
previousPoint.Z); // 使用上一个路径点的Z坐标(保持吊装高度)
|
||||
direction = HoistingPointDirection.Longitudinal;
|
||||
pointName = $"路径点{pointIndex}";
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更偏向横向移动(Y轴)
|
||||
// 保持X坐标不变,使用点击的Y坐标
|
||||
newPoint = new Point3D(
|
||||
previousPoint.X,
|
||||
clickedGroundPoint.Y,
|
||||
previousPoint.Z); // 使用上一个路径点的Z坐标(保持吊装高度)
|
||||
direction = HoistingPointDirection.Lateral;
|
||||
pointName = $"路径点{pointIndex}";
|
||||
}
|
||||
|
||||
string pointName = $"路径点{pointIndex}";
|
||||
var pathPoint = new PathPoint(newPoint, pointName, PathPointType.WayPoint);
|
||||
pathPoint.Direction = direction;
|
||||
|
||||
|
||||
@ -1911,10 +1911,25 @@ namespace NavisworksTransport.UI.WPF.ViewModels
|
||||
LogManager.Info($"终点被删除,上一个路径点 {prevPoint.Name} 已设为新的终点");
|
||||
}
|
||||
|
||||
// 吊装路径:禁止删除关键点(提升点、下降点)
|
||||
if (coreRoute.PathType == PathType.Hoisting &&
|
||||
(corePoint.Name == "提升点" || corePoint.Name == "下降点"))
|
||||
{
|
||||
LogManager.Warning($"不能删除吊装路径的关键点: {corePoint.Name}");
|
||||
UpdateMainStatus($"❌ 无法删除:{corePoint.Name} 是吊装路径的关键点");
|
||||
return;
|
||||
}
|
||||
|
||||
// 删除Core数据
|
||||
coreRoute.Points.Remove(corePoint);
|
||||
LogManager.Info($"已从Core数据删除路径点: {corePoint.Name}");
|
||||
|
||||
// 吊装路径:优化路径点(处理斜线和清除多余点)
|
||||
if (coreRoute.PathType == PathType.Hoisting)
|
||||
{
|
||||
_pathPlanningManager?.OptimizeRightAnglePathPoints(coreRoute);
|
||||
}
|
||||
|
||||
// 调用PathPlanningManager的3D删除方法
|
||||
_pathPlanningManager.RemovePathPoint(corePoint);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user