明确车辆长宽高和坐标系的关系,修改通行空间对其的使用。

This commit is contained in:
tian 2026-01-19 17:44:05 +08:00
parent 582ccfe1d6
commit b6dd1ca61b
4 changed files with 72 additions and 47 deletions

View File

@ -350,6 +350,31 @@ msiexec /i NavisworksTransport.Setup.msi /qn /l*v install.log
- **对外输出**: 转换为米(m)单位(用户界面、日志、数据库存储等)
- **单位转换**: 使用 `UnitsConverter.ConvertToMeters()``UnitsConverter.ConvertFromMeters()` 进行转换
- **向后兼容**: 不写回退和向后兼容代码,出错即抛异常
- **代码复用**: 优先使用现有的辅助方法和工具类,避免重复代码。例如:
- 查找物流属性模型时,使用 `CategoryAttributeManager.GetLogisticsItemsByType()` 而不是手动创建 Search 对象
- 提取几何数据时,使用 `GeometryHelper` 中的现有方法
- 计算距离时,使用 `GeometryHelper.CalculatePointDistance()` 等工具方法
- **车辆尺寸与XYZ轴关系** (关键约定):
- **X轴**: 长度方向(车辆前进方向,车头到车尾)
- **Y轴**: 宽度方向(车辆侧面,左右两侧)
- **Z轴**: 高度方向(垂直方向)
- **朝向规则**: 车辆沿路径移动时X轴长度方向指向路径前进方向
- **尺寸参数**: `VehicleLength` = X轴尺寸`VehicleWidth` = Y轴尺寸`VehicleHeight` = Z轴尺寸
- **通行空间计算**(路径周围的可通行区域,沿路径延伸的"管道":
- `passageAlongPath`: 沿路径方向的长度 = 路径本身的长度(渲染时使用)
- `passageAcrossPath`: 垂直于路径方向的截面尺寸1
- `passageNormalToPath`: 垂直于路径方向的截面尺寸2
- **水平路径**(地面、空轨)截面:使用车辆的**宽度**和**高度**
- `passageAcrossPath` = 车辆宽度Y轴+ 2×间隙
- `passageNormalToPath` = 车辆高度Z轴+ 间隙
- **垂直路径**(吊装)截面:使用车辆的**宽度**和**长度**
- `passageAcrossPath` = 车辆宽度Y轴+ 2×间隙
- `passageNormalToPath` = 车辆长度X轴+ 2×间隙
- **单位系统**:
- **内部计算**: 统一使用模型单位(避免频繁转换,提高性能)
- **对外输出**: 转换为米(m)单位(用户界面、日志、数据库存储等)
- **单位转换**: 使用 `UnitsConverter.ConvertToMeters()``UnitsConverter.ConvertFromMeters()` 进行转换
- **向后兼容**: 不写回退和向后兼容代码,出错即抛异常
- **代码复用**: 优先使用现有的辅助方法和工具类,避免重复代码。例如:
- 查找物流属性模型时,使用 `CategoryAttributeManager.GetLogisticsItemsByType()` 而不是手动创建 Search 对象
- 提取几何数据时,使用 `GeometryHelper` 中的现有方法

View File

@ -258,14 +258,14 @@ namespace NavisworksTransport.Core
// 🔥 对于虚拟车辆,直接应用缩放比例(不动态读取当前尺寸)
// 原因:虚拟车辆可能被旋转,导致包围盒尺寸不准确
// 单位立方体是 0.01m × 0.01m × 0.01m
// X方向 = 车辆宽度Y方向 = 车辆长度Z方向 = 车辆高度
// X方向 = 车辆长度前进方向Y方向 = 车辆宽度(侧面)Z方向 = 车辆高度
double baseSizeMeters = 0.01;
double scaleX = widthMeters / baseSizeMeters; // X方向 = 车辆宽度
double scaleY = lengthMeters / baseSizeMeters; // Y方向 = 车辆长度
double scaleX = lengthMeters / baseSizeMeters; // X方向 = 车辆长度(前进方向)
double scaleY = widthMeters / baseSizeMeters; // Y方向 = 车辆宽度(侧面)
double scaleZ = heightMeters / baseSizeMeters; // Z方向 = 车辆高度
LogManager.Info($"目标尺寸: {lengthMeters:F2}m × {widthMeters:F2}m × {heightMeters:F2}m");
LogManager.Info($"缩放比例: X={scaleX:F2}, Y={scaleY:F2}, Z={scaleZ:F2}");
LogManager.Info($"目标尺寸: 长度={lengthMeters:F2}m, 宽度={widthMeters:F2}m, 高度={heightMeters:F2}m");
LogManager.Info($"缩放比例: X(长度)={scaleX:F2}, Y(宽度)={scaleY:F2}, Z(高度)={scaleZ:F2}");
// 使用Transform3DComponents进行缩放
// 获取当前模型的变换并分解

View File

@ -2437,32 +2437,32 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (UseVirtualVehicle)
{
// 虚拟车辆的xy定义X方向 = 宽度1.0mY方向 = 长度1.2mZ方向 = 高度2.0m
// 虚拟车辆的xyz定义X方向 = 长度前进方向Y方向 = 宽度侧面Z方向 = 高度
if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径:通行空间四面都加检测间隙
passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // X方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(法线方向)
passageAlongPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向 + 2*间隙(沿路径方向)
LogManager.Info($"[通行空间可视化] 吊装路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, Z方向={VirtualVehicleHeight:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // X方向长度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向宽度+ 2*间隙(法线方向)
passageAlongPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(沿路径方向)
LogManager.Info($"[通行空间可视化] 吊装路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, Z方向(高度)={VirtualVehicleHeight:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径:物体的宽度方向X轴)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸高度上方加间隙下方不需要因为有地面
passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleHeight + safetyMargin; // Z方向 + 间隙(法线方向,只有上方)
passageAlongPath = VirtualVehicleWidth; // X方向沿路径方向)
LogManager.Info($"[通行空间可视化] 地面路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
// 地面路径:物体的长度方向X轴前进方向)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上方加间隙(下方不需要,因为有地面)
passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleHeight + safetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方)
passageAlongPath = VirtualVehicleLength; // X方向长度沿路径方向)
LogManager.Info($"[通行空间可视化] 地面路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
else // Rail
{
// 空轨路径:物体的宽度方向X轴)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸高度上下都加间隙在空中
passageAcrossPath = VirtualVehicleLength + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向 + 2*间隙(法线方向,上下都加)
passageAlongPath = VirtualVehicleWidth; // X方向沿路径方向)
LogManager.Info($"[通行空间可视化] 空轨路径使用虚拟车辆尺寸: X方向={VirtualVehicleWidth:F2}m, Y方向={VirtualVehicleLength:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
// 空轨路径:物体的长度方向X轴前进方向)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上下都加间隙(在空中)
passageAcrossPath = VirtualVehicleWidth + 2 * safetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VirtualVehicleHeight + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(法线方向,上下都加)
passageAlongPath = VirtualVehicleLength; // X方向长度沿路径方向)
LogManager.Info($"[通行空间可视化] 空轨路径使用虚拟车辆尺寸: X方向(长度)={VirtualVehicleLength:F2}m, Y方向(宽度)={VirtualVehicleWidth:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
}
else if (SelectedAnimatedObject != null)
@ -2472,39 +2472,39 @@ namespace NavisworksTransport.UI.WPF.ViewModels
double metersToModelUnits = UnitsConverter.GetMetersToUnitsConversionFactor();
// 将模型单位转换为米
double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits;
double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits;
double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits;
double sizeX = (bbox.Max.X - bbox.Min.X) / metersToModelUnits; // X方向 = 长度(前进方向)
double sizeY = (bbox.Max.Y - bbox.Min.Y) / metersToModelUnits; // Y方向 = 宽度(侧面)
double sizeZ = (bbox.Max.Z - bbox.Min.Z) / metersToModelUnits; // Z方向 = 高度
// 根据路径类型确定通行空间的尺寸
if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Hoisting)
{
// 吊装路径(严格垂直路径):
// 通行空间四面都加检测间隙
passageAcrossPath = sizeX + 2 * safetyMargin; // X方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(法线方向)
passageAlongPath = sizeZ + 2 * safetyMargin; // Z方向 + 2*间隙(沿路径方向)
LogManager.Info($"[通行空间可视化] 吊装路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, Z方向={sizeZ:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
passageAcrossPath = sizeX + 2 * safetyMargin; // X方向(长度)+ 2*间隙(垂直于路径方向)
passageNormalToPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(法线方向)
passageAlongPath = sizeZ + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(沿路径方向)
LogManager.Info($"[通行空间可视化] 吊装路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, Z方向(高度)={sizeZ:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
else if (CurrentPathRoute.PathType == NavisworksTransport.PathType.Ground)
{
// 地面路径(可能有坡度):
// 物体的宽度方向X轴)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸高度上方加间隙下方不需要因为有地面
passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = sizeZ + safetyMargin; // Z方向 + 间隙(法线方向,只有上方)
passageAlongPath = sizeX; // X方向沿路径方向)
LogManager.Info($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
// 物体的长度方向X轴前进方向)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上方加间隙(下方不需要,因为有地面)
passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向)
passageNormalToPath = sizeZ + safetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方)
passageAlongPath = sizeX; // X方向长度,沿路径方向)
LogManager.Info($"[通行空间可视化] 地面路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
else // Rail
{
// 空轨路径(可能有坡度):
// 物体的宽度方向X轴)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸,垂直于路径方向 = Y方向尺寸高度上下都加间隙在空中
passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = sizeZ + 2 * safetyMargin; // Z方向 + 2*间隙(法线方向,上下都加)
passageAlongPath = sizeX; // X方向沿路径方向)
LogManager.Info($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向={sizeX:F2}m, Y方向={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
// 物体的长度方向X轴前进方向)朝向路径方向
// 通行空间沿路径方向 = X方向尺寸(长度),垂直于路径方向 = Y方向尺寸(宽度),高度上下都加间隙(在空中)
passageAcrossPath = sizeY + 2 * safetyMargin; // Y方向(宽度)+ 2*间隙(垂直于路径方向)
passageNormalToPath = sizeZ + 2 * safetyMargin; // Z方向(高度)+ 2*间隙(法线方向,上下都加)
passageAlongPath = sizeX; // X方向长度,沿路径方向)
LogManager.Info($"[通行空间可视化] 空轨路径使用物体尺寸 ({SelectedAnimatedObject.DisplayName}): X方向(长度)={sizeX:F2}m, Y方向(宽度)={sizeY:F2}m, 通行空间沿路径={passageAlongPath:F2}m, 垂直路径={passageAcrossPath:F2}m, 法线={passageNormalToPath:F2}m");
}
}
else

View File

@ -2586,20 +2586,20 @@ namespace NavisworksTransport.UI.WPF.ViewModels
if (pathType == PathType.Hoisting)
{
// 吊装路径:通行空间四面都加检测间隙
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // X方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(法线方向)
passageAcrossPath = VehicleLength + 2 * SafetyMargin; // X方向长度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(法线方向)
}
else if (pathType == PathType.Rail)
{
// 空轨路径:高度上下都加间隙
passageAcrossPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + 2 * SafetyMargin; // Z方向 + 2*间隙(法线方向)
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + 2 * SafetyMargin; // Z方向(高度)+ 2*间隙(法线方向)
}
else // Ground
{
// 地面路径:高度只有上方加间隙
passageAcrossPath = VehicleLength + 2 * SafetyMargin; // Y方向 + 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + SafetyMargin; // Z方向 + 间隙(法线方向,只有上方)
passageAcrossPath = VehicleWidth + 2 * SafetyMargin; // Y方向宽度+ 2*间隙(垂直于路径方向)
passageNormalToPath = VehicleHeight + SafetyMargin; // Z方向(高度)+ 间隙(法线方向,只有上方)
}
// 设置通行空间参数到渲染插件