# 二维图线条归一化与合并流程

本文档描述 AutoCAD DWG 线条与 SolidWorks 工程图线条匹配前的归一化流程。目标是把 AutoCAD 中被拆碎、重复、部分重叠的线条整理成稳定的二维几何基元，避免因为 DWG 表达方式不同导致匹配率失真。

## 目标

二维图匹配不直接依赖 AutoCAD 原始实体数量，而是依赖归一化后的几何覆盖情况。

主要判定依据包括：

- 图元类型
- 尺寸数值
- 方向信息
- 几何位置
- 覆盖长度
- 匹配到 SolidWorks 工程图线条的数量和比例

## 输入

AutoCAD 提取器输出的原始实体，包括：

- `Line`
- `Polyline`
- `Circle`
- `Arc`
- `Spline`
- `Hatch`
- `Dimension`
- `Text`
- `BlockReference`

每个实体需要尽量保留：

- `handle`
- `object_name`
- `layer`
- `linetype`
- `color`
- `lineweight`
- 几何坐标
- 尺寸/文字内容

## 输出

输出统一二维图元，例如：

```json
{
  "kind": "line",
  "start": [10.0, 20.0],
  "end": [80.0, 20.0],
  "length": 70.0,
  "angleDeg": 0.0,
  "layer": "0",
  "linetype": "Continuous",
  "color": 256,
  "lineweight": -1,
  "sourceHandles": ["1A2", "1A3", "1A4"],
  "mergeCount": 3,
  "mergeType": "collinear_interval_union"
}
```

如果存在几何重叠但不能合并，则输出重叠关系：

```json
{
  "overlapGroupId": "overlap-0001",
  "handles": ["1A2", "2B7"],
  "overlapLength": 20.5,
  "reason": "same_geometry_different_style"
}
```

## 总流程

1. 读取 AutoCAD 原始实体。
2. 按实体类型转换成统一二维图元。
3. 对 `Polyline` 展开成线段/圆弧片段。
4. 对 `Line` 执行强合并。
5. 对样式不同但几何重叠的线段记录重叠关系。
6. 对 `Arc` / `Circle` 执行后续归一化和必要合并。
7. 生成用于匹配的标准图元集。
8. 和 SolidWorks 工程图显示线条进行匹配评分。

## 统一图元转换

### Line

转换为：

- `kind = line`
- `start`
- `end`
- `length`
- `angleDeg`
- `sourceHandles`

方向角需要把反向线视为同一方向，例如 `0°` 和 `180°` 归为同一方向组。

### Polyline

不能把 `Polyline` 当作普通 `Line` 处理。

需要读取：

- 顶点坐标
- bulge
- closed
- elevation

处理规则：

- bulge 为 `0` 的相邻顶点段转换成 `line`
- bulge 非 `0` 的相邻顶点段转换成 `arc`
- closed polyline 需要补最后一个点到第一个点的片段

### Circle

转换为：

- `kind = circle`
- `center`
- `radius`
- `diameter`

### Arc

转换为：

- `kind = arc`
- `center`
- `radius`
- `startAngle`
- `endAngle`
- `start`
- `end`

### Spline

先保留为 `spline`，同时生成采样点串，用于后续几何匹配。

### Hatch

默认不参与轮廓线强匹配。

剖面线、填充线可以作为剖视区域辅助证据，但不能和普通模型轮廓线混合计数。

## Line 强合并规则

只做强合并，不做弱合并。

只有同时满足以下条件的线段才合并：

- 类型相同，都是 `line`
- 方向一致或反向一致
- 共线
- 端点相接、间隙很小、完全重叠或部分重叠
- 图层一致
- 线型一致
- 颜色一致或都为默认
- 线宽一致或都为默认

如果几何上重叠，但图层、线型、颜色、线宽不同，则不合并，只记录 overlap 关系。

## 共线分组

### 方向分组

先按方向角分组。方向角需要忽略正反方向：

```text
normalizedAngle = angle % 180
```

建议初始容差：

```text
angleToleranceDeg = 0.5 ~ 1.0
```

### 共线判断

在同一方向组内，判断线段是否落在同一条无限直线上。

判断条件：

- 两个端点到基准线的垂直距离都小于容差
- 两条线的法向偏移小于容差

建议初始容差：

```text
collinearDistanceTolerance = 0.01mm ~ 0.05mm
```

具体容差应根据图纸单位、DWG 精度、导出质量调整。

## 区间合并

对每个“样式一致 + 共线”的线段组，执行一维区间合并。

步骤：

1. 选定该组方向向量 `u`。
2. 把每条线段两个端点投影到 `u` 上。
3. 得到一维区间 `[tMin, tMax]`。
4. 按 `tMin` 排序。
5. 合并重叠、包含、部分重叠、小间隙区间。
6. 把合并后的区间端点反投影回二维坐标。

示例：

```text
line A: [0, 50]
line B: [20, 80]
line C: [80.01, 120]
```

如果间隙容差允许：

```text
[0, 50] + [20, 80] + [80.01, 120] -> [0, 120]
```

建议初始容差：

```text
gapTolerance = 0.01mm ~ 0.05mm
```

## 重叠但不合并

如果两条线几何上共线且区间重叠，但样式不同，则不合并。

需要记录：

- 重叠组 ID
- 涉及的 handle
- 重叠长度
- 样式差异
- 是否可能重复计数

原因是不同样式可能表达不同语义：

- 轮廓线
- 中心线
- 隐藏线
- 剖面线
- 辅助线

这些线即使几何重合，也不能简单合并成一个实体。

## 匹配评分建议

匹配时不要只看原始 AutoCAD 实体数量。

建议统计：

- `rawEntityCount`
- `normalizedPrimitiveCount`
- `mergedLineCount`
- `sourceLineCount`
- `matchedPrimitiveCount`
- `matchedCoveredLength`
- `expectedCoveredLength`
- `overlapDuplicateLength`
- `lineDirectionHistogram`
- `dimensionValueMatchRate`

核心指标：

```text
coveredLengthMatchRate = matchedCoveredLength / expectedCoveredLength
primitiveMatchRate = matchedPrimitiveCount / expectedPrimitiveCount
```

其中 `expected` 通常来自 SolidWorks 工程图显示线条。

## 当前不做的事情

当前阶段不做弱合并。

也就是说：

- 样式不同的重叠线不合并
- 图层不同的重叠线不合并
- 线型不同的重叠线不合并
- 颜色/线宽明显不同的重叠线不合并

这些情况只记录 overlap 关系，匹配时用于避免重复计数或辅助解释。
