AI 协作日志

学生 Web 实验作品平台

学号:202412211401001 · 来源:ai-log.md

# 实验五 AI 协作与核验记录

学号:202412211401001  姓名:    日期:2026-11-09

> 记录原则:先写自己的预测,再向 AI 提问;AI 只给思路与排查方向,最终由我运行工程、
> 比对数值与截图后决定采纳或否。全部数值可在浏览器状态栏、Console 与
> `screenshots/` 中复查,汇总见 `验证记录.md`。

## 协作一:观察与投影概念核验(Task B / C,3分)

**1. 我的问题和事先预测**

- 移动物体(改 M)时,模型世界中心数值会变;移动相机(改 V)时,世界中心数值不应变。
- 正交投影下,两个同样大小、深度不同的立方体应显示为同样大;透视投影应近大远小。
- 把 FOV 从 50° 调到 80°,透视画面里物体占比应减小。
- 把 near 从 0.1 推到 9,近处立方体应从画面中消失,但对象本身仍在场景里。

**2. 实际输入给 AI 的提示词**

> 在 WebGL2 右手坐标系、列向量和 P·V·M 的顺序下,我想比较移动物体与移动相机、正交与透视投影。请给我三组能区分原因的控制变量实验,指出应改变 M/V/P 中的哪项,说明可以打印哪些坐标数值进行核验,不要直接生成整套代码。

**3. AI 建议摘要**

1. 只改 V:`front(0,0,8) → side(8,0,0) → front`,每次打印 `V·eye`、`V·target` 与状态栏“模型世界中心”,看中心是否恒定、V 是否把 eye 送到原点。
2. 只改 P:固定 M、V,切 `ortho/persp` 与 `fov 50/80`,打印两个立方体的 NDC 宽度和 ndcZ。
3. 只改裁剪面:固定 M、V、P,near 0.1→9、far 100→5,打印同一点的 ndcZ 判断越界。
   AI 强调:三组实验必须一次只动一项,否则无法归因。

**4. 我的判断和采纳/拒绝理由**

- 采纳三组控制变量法,但拒绝“用 scale 缩放模拟 FOV 变化”这一条:那会改 M,
  画面虽然也变小,却无法证明是 P 的作用,属于混淆变量。
- 采纳“打印 ndcZ”做法,因为它能区分“看不见”与“被裁掉”。

**5. 我的测试参数、操作与结果**

| 测试 | 参数 | 实测结果 |
|---|---|---|
| 只改 V | front → side → front | eye 在相机系恒为 (0,0,0),target 恒为 (0,0,-8);正面→侧面→正面矩阵完全复原;“模型世界中心”始终 (0.00,0.00,0.00) |
| 顶部视角 up | eye=(0,8,0) | up 自动取 (0,0,-1),矩阵有限,无黑屏/NaN,`V·eye=(0,0,0)` |
| 只改 P(正交) | orthoH=5.5, aspect≈1.54 | z 深度 −8 与 −14 的等尺寸立方体 NDC 宽都是 0.2364,比值 1.000 |
| 只改 P(透视) | FOV 50°, near .1, far 100 | 同一对立方体 NDC 宽 0.1742 / 0.0996,比值 1.750(近者更大) |
| 改 FOV | 50°→80° | 同一深度物体 NDC 宽 0.1742→0.0968(占屏 17.4%→9.7%) |
| 改 near | near=9(> 深度 8) | 近立方体 ndcZ=−1.2747(<−1 被近平面裁);远立方体仍为 −0.2151 |
| 改 far | far=5 | 深度 14 的立方体 ndcZ=1.0262(>1 被远平面裁) |

截图:`screenshots/C-透视-近大远小.png`、`C-正交-等尺寸.png`、`B-正面/侧面/顶部/斜上方视角.png`。

**6. AI 是否正确?我修正了什么认识**

基本正确。修正之处:一开始我以为“透视近大远小”是矩阵把远处物体缩小了;
打印 NDC 宽度后发现透视矩阵对 x/y 的缩放系数完全相同,差异来自顶点变换后
除以 w(w=−z_cam),即透视除法。因此“看起来小”不等于“被缩放”,
FOV 变化也不能等同于 Model 缩放。

## 协作二:程序故障诊断(Task C / D,4分)

**1. 真实错误现象和起初怀疑的原因**

现象:Task B 调试顶部视角附近的相机(eye=(0.5, 8, 0),视线与 Y 轴夹角约 3.6°)时,
画面里的网格与模型朝向突然翻转 90°,Console 无报错、矩阵中也没有 NaN。
起初怀疑两点:①Projection 的 aspect 取错(用了 CSS 尺寸或写死 1000/650)导致拉伸;
②P·V·M 相乘顺序写反。

**2. 向 AI 提出的诊断问题**

> 我的页面能显示模型,但在顶部视角附近,画面朝向会突然翻转,Console 没有报错。
> 请从 up 向量、宽高比、裁剪面和矩阵顺序中提出至少三种假设,各给一项最小测试,
> 先帮定位,不要直接重写完整程序。

**3. AI 建议的可区分原因及测试**

| 假设 | 最小测试 | 判别标准 |
|---|---|---|
| up 与视线近平行,lookAt 的 cross 退化 | 打印 `forward`、`cross(forward,up)` 长度、`V` 前三行与 `right/up` 的点积 | cross 长度趋近 0 而方向乱跳即成立 |
| aspect 用了错误值 → 画面横向拉伸 | 打印 `scene.resize()` 返回的 w/h 与 canvas 的 `width/height`、并比较球体在屏幕上的横纵像素 | 两者不一致即成立 |
| near/far 或矩阵顺序错 | 只投一个已知点,打印 ndcZ;再单独检查 `V·eye` | ndcZ 越界或 `V·eye≠0` 即成立 |

**4. 我实际逐项测试了什么**

- 用 Node 直接调用 `CG5Exercises.view()` 打印:aspect 正常(984×615≈1.60,与 CSS 一致);
  `V·eye=(0,0,0)`、`V·target=(0,0,-8)`,说明顺序与 lookAt 都对。
- 打印 `forward=(−0.062,−0.998,0)`,`cross(forward,(0,1,0))` 长度只有 0.062,
  归一化后 right≈(0,0,−1),而把 eye 移到 (0,8,0) 时 right=(1,0,0):**方向发生了跳变**。
- 由此排除宽高比与矩阵顺序,锁定 up 向量。

(顺带记一个真实的数值坑:`gl-matrix` 默认 `Float32Array`,2/6 存成 0.33333334,
我最初按 1e-9 容差断言“缩放=1/3”,误报失败;改成 1e-6 后通过。
结论:核验容差必须按 float32 精度设置。)

**5. 最终根因、修复处及修复后结果**

根因:原实现在 `horizontal < 0.02*dist` 才切换 up,阈值只覆盖约 1.1°,
在 3.6° 这类“近顶部”视线下仍用 (0,1,0),cross 向量长度只剩 0.06,
方向被浮点误差主导,导致相机右方向翻转、画面朝向跳变。

修复:`js/task-b.js` 把阈值改为 `horizontal < 0.1*dist`(约 5.7°),并新增
`cameraBasis()` 让 `lookAt` 与 Shift 拖动的 right/up 共用同一组基向量,
避免“画面朝向”和“拖动方向”两套算法不一致。

修复后:顶部 eye=(0,8,0)、近顶部 (0.5,8,0) 的 up 均为 (0,0,-1),14° 斜视仍为 (0,1,0);
五页 `gl.getError()=0`,Console 无异常,顶部视角截图见 `screenshots/B-顶部视角.png`。

## 协作三:综合工作台方案比较(Task E,3分)

**1. 我准备完成的观察任务**

用茶壶/兔子观察“绕指定参考点 P 公转”与“部件继承父变换”:
回答“绕点旋转与自转在画面上差在哪里”,并能用数值证明半径守恒。

**2. 向 AI 询问的两种设计方案**

> 我已完成OBJ导入、观察视角、正交/透视以及鼠标键盘变换。请提供两个能在40分钟内复用已有WebGL2模块的观察台拓展设计,对比功能、矩阵链、交互参数和验证难度。不引入Three.js、光照、纹理或复杂模型编辑器。

**3. 两种方案对比**

| 项目 | 方案1:双画布正交/透视同步对照(Challenge 1) | 方案2:可调参考点绕点旋转+父子继承部件 |
|---|---|---|
| 功能 | 左右两画布同一 M/V、仅 P 不同,拖动时同步 | 参考点 P、轨道半径、标记角度、部件局部坐标可调 |
| 矩阵链 | 两套 `P_ortho/P_persp`,共享 `V·M`,需第二个 Scene 与视口 | `M_orbit=T(P)·Ry(θ)·T(-P)·T(q)·S`;部件 `M_parent·T(p)·S` |
| 交互参数 | 需同步两画布 resize、事件、截图 | 复用 `ex.extra()` 与现有控件面板 |
| 验证难度 | 高:需证明两画布状态一致、截图对齐 | 低:可直接算点到 P 的距离与部件世界坐标 |

**4. 最终采纳的方案与理由**

采纳方案 2。理由:40 分钟内可完成且不改动 `engine.js` 的渲染主循环;
它的矩阵链与指导书公式逐项对应,能用“距离是否恒为 1.25”这种数值直接判定正确性;
双画布对照的同步与截图验证成本高,留作 Challenge 选做。
方案取舍由我决定:AI 提供了两套方案与验证口径,但没有替我选择。

**5. 自己实现或修改的功能差异**

- 在 `js/task-e.js` 的 `extra()` 中给出:黄色固定参考点、灰色轨道环(36 段)、
  橙色绕点标记、绿色父子继承部件;并新增参考点高度、轨道半径、部件 X/Y/Z 五个可调参数
  (`js/app.js` 增加默认值,`js/ui.js` 面板 05 增加输入框)。
- 部件使用与主模型同源的 `T·Ry·Rx·S` 作为父矩阵,再叠加局部 `T(p)·S(.1)`,
  因此父级旋转/平移/缩放时部件位置、朝向、尺寸一起变化——这是实验四父子变换的复用。

**6. 预测与实际结果对照,仍存在的局限**

| 预测 | 实测 |
|---|---|
| 绕点标记到 P 的距离恒定,不随 θ 变化 | θ=0/35/90/180/270° 时距离恒为 1.2500;浏览器把 θ 改为 120° 得 (−0.625,1.15,−1.083),距离 1.24999 |
| 标记不是自转:立方体自身只平移不旋转 | 轨迹为半径 1.25 的圆,圆心为 P;θ 变化时只有中心位置改变 |
| 部件随父级 ry=90° 一起转,且到原点距离不变 | 部件 (1.05,1,0.45)→(0.45,1,−1.05),距原点 1.5182 不变 |
| 父级 scale=2、tx=0.5 时部件位置与尺寸同倍变化 | 位置 (2.6,2,0.9),边长 0.05→0.10 |

局限:部件坐标定义在“归一化后最大边=2”的模型空间里,换用兔子/球体时需要手动
调部件 XYZ 才能贴到表面;轨道环是 36 个小立方体,增加约 36 次 draw call,
教学场景可接受但不适合大规模复用。

## 全局诚信声明

- 代码由 AI 辅助给出思路与初版实现,本人逐项运行、对照数值与截图后保留;
  `ai-log.md` 与 `验证记录.md` 中的数值均由工程实际运行得到,未手填估计值。
- 无法用数值或截图解释的结论未写入本记录;顶部 up 阈值、交互灵敏度、
  部件定位空间等参数选择属于本人判断,并已说明理由与局限。