Files
mcm-26-b/docs/figures/README.md
T
2026-09-13 18:05:59 +08:00

75 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# docs/figures —— 论文插图
每张图只输出 PNG。正文插图统一由 scripts/plot_paper_figures.py 使用 matplotlib 生成,
数据直接读取 docs/paper/data/practice-results.json(演练局复算)、
practice-geometry.json(问题一交会算例)、正式统计快照与第四问覆盖计划;
manifest.json 记录图片生成命令与来源。
本目录的 15 张 PNG 进入论文:`docs/paper/main.tex` 用
`\graphicspath{{../figures/}}` 直接引用,不在论文里重绘,也不手抄图内数字。
正文使用演练局数据生成的插图(问题一至四的算例、路径、时间分布与耗时构成),
正式测试的两张图(`formal-*.png`)只出现在附录 A 的效果验证中。
论文图注均为中文,并标注数据来源是演练局还是正式测试。
```
python scripts/plot_paper_figures.py # 生成正文全部 matplotlib 插图
```
MATLAB 内手动出图:`cd scripts/matlab` 后执行 `run_all_figures`(每张图单独一个会话,
本机图形子系统连续渲染多张会崩)。
依赖:`numpy` 与 `matplotlib`。
## 约定
- **除回放画布(点运动图 `replay-webui-*`)外,全部使用 MATLAB 默认图形样式**:
默认配色(`defaultAxesColorOrder`)、默认字体与字号、默认坐标轴与图例;
不引入自定义调色板,不手绘图例色块。
- 图内不放标题、图注与解释性文字,只保留坐标轴、图例与必要的元素标注;
图的含义由文件名与下表承担,解释写在论文正文。
- 图例一律用 MATLAB `legend` 放在坐标区外(`southoutside`),不压数据;
散点标签按候选方位自动避让,保证互不重叠。
- 输出 PNG(`exportgraphics`,300 dpi、白底),导出前关闭坐标轴工具条。
## 图清单
| 文件 | 内容 | 数据来源 | 论文位置 |
| --- | --- | --- | --- |
| `flow-overall-architecture.png` | 四层主线:题面抽象(L0)、在线三层(L1)、四问主线(L2)、三条闭环(L3) | `src/mcm26b/config.py`、`docs/B题建模分析与实施计划.md` | 图 1(问题分析) |
| `steps-state-machine.png` | 会话状态机(IDLE / 倒计时 / OPEN / CLOSED) | `docs/协议规则表与状态机.md`、`src/mcm26b/protocol/client.py` | 图 2(计时模型) |
| `timing-attachment-example-105-111-194-199.png` | 附件计时示例:逐动作耗时构成与单步合计 | `docs/协议规则表与状态机.md` | 图 3(计时模型) |
| `timing-measured-q3-10-sources.png` | 实测一局:累计虚拟时间按动作类型的堆叠构成 | `referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl` | 图 11(时间分解,演练局) |
| `geo-q1-convex-intersection-zoom.png` | 问题一:角域交会总览 + 定位区域放大(直径圆与最小包围圆) | `output/q1/practice/U5ZW-P9KN-TCAG-R7ST_observations.json` | 图 4(a)(问题一,演练观测) |
| `geo-q1-diameter-circle-counterexample.png` | 问题一:直径圆不覆盖定位区域的反例(等边三角形布站) | `examples/q1/triangle.json` | 图 4(b)(问题一解析反例) |
| `geo-q2-guaranteed-reception-disk.png` | 问题二:截断角域外接圆 `B(c, a)` 与安全候选盘 `B(c, 1000 − a)`,右侧为半径分解 | `src/mcm26b/config.py`、`docs/algo-2.md` | 图 5(问题二) |
| `geo-q3-seven-point-coverage.png` | 问题三:七个 1000 m 接收盘覆盖 Ω,标出最差点 | `src/mcm26b/planner/seven.py`、`docs/algo-3.md` | 图 6(问题三) |
| `geo-q4-minimum-cover-31-points.png` | 问题四:31 点最小命中集与 ±90° 前向半盘语义 | `src/mcm26b/guarantee/plans/q4_mincover_v2.json` | 图 8(问题四) |
| `replay-webui-q3-omnidirectional.png` | 回放画布(点运动图,全向局):世界视图 + 事件流水 + 虚拟时间轴 | `referee-data/sessions/BBM9-HZG2-77N5-NKKC/log.jsonl` | 图 7(问题三,演练局) |
| `replay-webui-q4-directional.png` | 回放画布(点运动图,定向源局):世界视图(含定向源 ±90° 前向半盘)+ 事件流水 + 虚拟时间轴 | `referee-data/sessions/GHSN-M38E-74GD-YLUD/log.jsonl` | 图 9(问题四,演练局) |
后两张是唯一保留自定义画布的图:把回放器画布上的 Ω 与真值源、移动轨迹、
检测示向度射线、定向源朝向与清除标记,连同右侧事件流水与底部虚拟时间轴一起导出;
定向源局额外画出每个定向源的 **±90° 前向半盘**(半径取该源 `r_eff_m`,朝向箭头即半盘半径)。
q4 回放固定用演练局 `GHSN-M38E-74GD-YLUD`(`build_figure_data.py::Q4_REPLAY_CASE`);
本机没有该局留档时回退到自动挑选,因此 `examples/replay/` 里归档了这一局。
## 数据来源与复现
- `timing-measured-*`、`replay-webui-*` 读评测机行为日志(JSONL,含真值)。
`referee-data/` 被 `.gitignore` 忽略,因此另归档两局到 `examples/replay/`;
没有评测机数据时脚本自动改读归档,图一致。
```bash
uv run python scripts/archive_replay_logs.py --list # 本机有哪些局
uv run python scripts/archive_replay_logs.py <案例编码> # 追加归档
```
- `geo-q1-convex-intersection-zoom.png` 读官方演练留档
`output/q1/practice/*_observations.json`(同样被忽略)。文件缺失时改读
`examples/q1/triangle.json` 反例算例,图仍可用,只是案例不同。
- 问题一的几何量由生产求解器 `mcm26b.geometry.solve` 现算;
问题三、问题四直接读覆盖计划与证书,不手抄数字。