# GeometryHelper 使用指南

## 文件位置

`src/Utils/GeometryHelper.cs`

## 用途

3D 几何计算工具类，提供距离、角度、向量等常用几何计算。**禁止自己实现几何计算**，必须复用此类。

## 核心方法

### 距离计算

```csharp
// 两点间距离
Point3D a = new Point3D(0, 0, 0);
Point3D b = new Point3D(3, 4, 0);
double distance = GeometryHelper.Distance(a, b);  // 5.0

// 2D距离（忽略Z坐标）
double distance2D = GeometryHelper.Distance2D(a, b);

// 距离的平方（性能优化，避免开方）
double distanceSq = GeometryHelper.DistanceSquared(a, b);
```

### 向量运算

```csharp
// 向量减法（b - a）
Vector3D vector = GeometryHelper.Subtract(b, a);

// 向量长度
double length = GeometryHelper.VectorLength(vector);

// 单位向量
Vector3D normalized = GeometryHelper.Normalize(vector);

// 点积
double dot = GeometryHelper.DotProduct(v1, v2);

// 叉积
Vector3D cross = GeometryHelper.CrossProduct(v1, v2);
```

### 角度计算

```csharp
// 向量夹角（弧度）
double angle = GeometryHelper.AngleBetween(v1, v2);

// 向量夹角（角度）
double angleDegrees = GeometryHelper.AngleBetweenDegrees(v1, v2);

// 三点形成的角度（以b为顶点）
double angle = GeometryHelper.AngleAtVertex(a, b, c);
```

### 点与线的关系

```csharp
// 点到线段的最近点
Point3D closestPoint = GeometryHelper.ProjectPointOnLineSegment(
    point, lineStart, lineEnd);

// 点到线段的距离
double distance = GeometryHelper.DistancePointToLineSegment(
    point, lineStart, lineEnd);

// 点是否在线段上（含容差）
bool isOnLine = GeometryHelper.IsPointOnLineSegment(
    point, lineStart, lineEnd, tolerance: 0.001);
```

## 使用示例

### 示例1：计算路径总长度

```csharp
// ❌ 错误：自己实现距离计算
double dx = p2.X - p1.X;
double dy = p2.Y - p1.Y;
double dz = p2.Z - p1.Z;
double distance = Math.Sqrt(dx*dx + dy*dy + dz*dz);

// ✅ 正确：使用 GeometryHelper
double distance = GeometryHelper.Distance(p1, p2);
```

### 示例2：检查三点是否共线

```csharp
public bool AreCollinear(Point3D a, Point3D b, Point3D c, double tolerance = 0.001)
{
    // 计算叉积，如果为0则共线
    Vector3D ab = GeometryHelper.Subtract(b, a);
    Vector3D ac = GeometryHelper.Subtract(c, a);
    Vector3D cross = GeometryHelper.CrossProduct(ab, ac);
    
    return GeometryHelper.VectorLength(cross) < tolerance;
}
```

### 示例3：计算转弯角度

```csharp
public double CalculateTurnAngle(Point3D prev, Point3D current, Point3D next)
{
    // 入向量（从prev到current）
    Vector3D v1 = GeometryHelper.Subtract(current, prev);
    
    // 出向量（从current到next）
    Vector3D v2 = GeometryHelper.Subtract(next, current);
    
    // 计算夹角
    double angle = GeometryHelper.AngleBetweenDegrees(v1, v2);
    
    return angle;  // 0-180度
}
```

## 性能提示

```csharp
// 大量距离比较时，使用距离的平方避免开方
// ✅ 更快
double distSq = GeometryHelper.DistanceSquared(a, b);
if (distSq < threshold * threshold)

// ❌ 更慢（需要开方）
double dist = GeometryHelper.Distance(a, b);
if (dist < threshold)
```
