# 2.1.5 路径点自动贴合功能设计说明

## 2.1.5.1. 模块描述

路径点自动贴合模块是路径规划系统的重要功能，负责确保路径点自动贴合通道模型表面，并使路径点之间通过直线进行联通。该模块解决了用户手动选择路径点时可能无法精确贴合模型表面的问题，确保生成的路径在物理上可行。

该模块使用射线投射和几何计算算法，自动计算路径点与通道表面的最近点，并生成直线路径连接各点。

## 2.1.5.2. 功能

### 核心功能
1. **表面贴合**：自动将路径点投影到通道模型表面
2. **高度调整**：根据通道表面高度调整路径点Z坐标
3. **直线联通**：在路径点之间生成直线连接
4. **碰撞避免**：确保路径点不会位于障碍物内部

### 子功能
| 功能编号 | 功能名称 | 功能描述 |
|---------|---------|---------|
| 2.1.5.F1 | 射线投射贴合 | 使用射线投射找到模型表面交点 |
| 2.1.5.F2 | 最近点计算 | 计算点到模型表面的最近点 |
| 2.1.5.F3 | 高度自适应 | 根据表面高度自动调整路径点 |
| 2.1.5.F4 | 直线生成 | 在路径点之间生成直线路径 |
| 2.1.5.F5 | 碰撞检测 | 检测路径点是否与障碍物碰撞 |
| 2.1.5.F6 | 智能修正 | 自动修正位于障碍物内的点 |

## 2.1.5.3. 性能

### 性能指标
| 指标名称 | 目标值 | 说明 |
|---------|-------|------|
| 贴合计算时间 | < 100ms | 单个路径点的贴合计算时间 |
| 批量贴合时间 | < 500ms | 10个路径点的批量贴合时间 |
| 射线检测精度 | 1mm | 射线投射检测的精度 |
| 支持模型复杂度 | 无限制 | 支持的大型模型复杂度 |

### 性能优化策略
1. 使用空间索引加速射线投射
2. 缓存通道表面几何信息
3. 批量处理路径点贴合

## 2.1.5.4. 输入输出项

### 1. 字段输入输出

#### 输入字段
| 字段名 | 类型 | 必填 | 说明 |
|-------|------|-----|------|
| OriginalPoint | Point3D | 是 | 原始路径点坐标 |
| ChannelItems | List<ModelItem> | 是 | 通道模型元素列表 |
| SearchRadius | double | 否 | 搜索半径（米），默认1.0米 |

#### 输出字段
| 字段名 | 类型 | 说明 |
|-------|------|------|
| SnappedPoint | Point3D | 贴合后的路径点坐标 |
| SurfaceNormal | Vector3D | 表面法向量 |
| Distance | double | 贴合距离 |
| Success | bool | 贴合是否成功 |

### 2. 界面交互输入输出

#### 界面输入
- 启用/禁用自动贴合选项
- 贴合精度参数设置
- 手动触发贴合操作

#### 界面输出
- 贴合结果可视化
- 贴合距离显示
- 贴合失败提示

## 2.1.5.5. 算法

### 表面贴合算法
```
算法：基于射线投射的表面贴合
输入：原始点，通道模型集合
输出：贴合后的点

1. 从原始点向上发射射线
2. 遍历所有通道模型：
   3. 计算射线与模型三角面的交点
   4. 记录最近的交点
5. 如果没有交点：
   6. 从原始点向下发射射线
   7. 重复步骤2-4
8. 返回最近的交点作为贴合点
```

### 最近点计算算法
```
算法：点到模型表面的最近点
输入：点，模型集合
输出：最近点

1. 初始化最小距离为无穷大
2. 初始化最近点为原始点
3. 对于每个模型的每个三角面：
   4. 计算点到三角面的最近点
   5. 计算距离
   6. 如果距离小于最小距离：
      7. 更新最小距离和最近点
8. 返回最近点
```

### 直线联通算法
```
算法：路径点直线连接
输入：路径点列表
输出：直线路径

1. 对于每对相邻的路径点：
   2. 计算起点和终点
   3. 在两点之间进行线性插值
   4. 生成中间路径点
   5. 将中间点加入路径
6. 返回完整路径
```

## 2.1.5.6. 流程逻辑

```
开始
  │
  ▼
┌─────────────────┐
│  创建路径点      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐      否
│  启用自动贴合？  │────────────────┐
└────────┬────────┘                │
         │是                      │
         ▼                        │
┌─────────────────┐               │
│  发射射线检测    │               │
└────────┬────────┘               │
         │                        │
         ▼                        │
┌─────────────────┐      否       │
│  找到表面交点？  │───────────────┤
└────────┬────────┘               │
         │是                     │
         ▼                       │
┌─────────────────┐              │
│  计算贴合点坐标  │              │
└────────┬────────┘              │
         │                       │
         ▼                       │
┌─────────────────┐              │
│  更新路径点位置  │              │
└────────┬────────┘              │
         │                       │
    ┌────┴───────────────────────┘
    │
    ▼
┌─────────────────┐
│  连接相邻点      │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  显示路径        │
└────────┬────────┘
         │
         ▼
        结束
```

## 2.1.5.7. 接口

### 公共接口
```csharp
/// <summary>
/// 路径点贴合器
/// </summary>
public class PathPointSnapper
{
    /// <summary>
    /// 将路径点贴合到通道表面
    /// </summary>
    /// <param name="point">原始路径点</param>
    /// <param name="channelItems">通道模型集合</param>
    /// <returns>贴合结果</returns>
    public SnapResult SnapToSurface(Point3D point, List<ModelItem> channelItems);
    
    /// <summary>
    /// 批量贴合路径点
    /// </summary>
    /// <param name="points">路径点列表</param>
    /// <param name="channelItems">通道模型集合</param>
    /// <returns>贴合结果列表</returns>
    public List<SnapResult> SnapPointsToSurface(List<Point3D> points, List<ModelItem> channelItems);
    
    /// <summary>
    /// 计算点到模型表面的最近点
    /// </summary>
    /// <param name="point">原始点</param>
    /// <param name="modelItem">模型元素</param>
    /// <returns>最近点</returns>
    public Point3D GetNearestPointOnSurface(Point3D point, ModelItem modelItem);
}
```

### 事件接口
```csharp
/// <summary>
/// 路径点贴合完成事件
/// </summary>
public event EventHandler<PointSnappedEventArgs> PointSnapped;

/// <summary>
/// 批量贴合完成事件
/// </summary>
public event EventHandler<BatchSnapCompletedEventArgs> BatchSnapCompleted;
```

## 2.1.5.8. 注释设计

### 代码注释规范
```csharp
/// <summary>
/// 贴合结果
/// </summary>
public class SnapResult
{
    /// <summary>
    /// 原始点坐标
    /// </summary>
    public Point3D OriginalPoint { get; set; }
    
    /// <summary>
    /// 贴合后的点坐标
    /// 如果贴合失败，与OriginalPoint相同
    /// </summary>
    public Point3D SnappedPoint { get; set; }
    
    /// <summary>
    /// 表面法向量
    /// 用于确定表面的朝向
    /// </summary>
    public Vector3D SurfaceNormal { get; set; }
    
    /// <summary>
    /// 贴合是否成功
    /// </summary>
    public bool Success { get; set; }
}
```

## 2.1.5.9. 数据结构

### SnapResult 结构
| 字段名 | 类型 | 说明 |
|-------|------|------|
| OriginalPoint | Point3D | 原始点坐标 |
| SnappedPoint | Point3D | 贴合后的点坐标 |
| SurfaceNormal | Vector3D | 表面法向量 |
| Distance | double | 贴合距离 |
| Success | bool | 贴合是否成功 |
| ErrorMessage | string | 错误消息（如果失败） |

### PointSnappedEventArgs 结构
| 字段名 | 类型 | 说明 |
|-------|------|------|
| OriginalPoint | Point3D | 原始点 |
| SnappedPoint | Point3D | 贴合后的点 |
| Success | bool | 是否成功 |

### BatchSnapCompletedEventArgs 结构
| 字段名 | 类型 | 说明 |
|-------|------|------|
| Results | List<SnapResult> | 所有贴合结果 |
| SuccessCount | int | 成功数量 |
| FailCount | int | 失败数量 |
