AI 协作日志

学生 Web 实验作品平台

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

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

学号:202412211402009 姓名:蒋雨霏 日期:2026-11-09

> 本记录保留我的预测、原始问题、AI建议、自主判断与实际核验。AI(豆包)用于概念复核、故障假设列举与方案对比;代码由我逐项运行、数值验证并解释,无法解释的输出没有直接作为完成结果。

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

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

先写预测再提问:

- 只改V(换视角)时,模型世界坐标不应改变,画面下方“模型世界中心”应始终是(0,0,0);只改P时,茶壶轮廓不变,但近/远立方体的表观尺寸关系会变。
- 预测:正交下两个等尺寸立方体屏幕上一样大;透视下近的明显大;FOV 50°→110°时透视画面中物体占比变小,正交投影不受FOV影响。
- 我预计容易搞错的地方:把“FOV变大”误当成“模型缩小”(前者是P,后者是M)。

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

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

**3. AI建议摘要**

三组控制变量:①固定M、P,只改eye/target,打印模型世界中心`CG5.point(M, center)`与eye;②固定M、V,只改`mode`,比较等尺寸立方体的屏幕高度;③固定M、V、mode,只改FOV,观察画面占比。AI还强调P的宽高比必须等于Canvas实际`width/height`,否则横向拉伸,并指出“世界中心只由M决定”是最直接的判据。

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

三组全部采纳,但补了自己的判据:同时观察V矩阵第4列的平移分量,因为eye一变V的平移必变,而M不变时世界中心必须不变。拒绝AI建议的“用截图工具量像素”,改为直接读`stat-world`/`stat-projection`文本,避免截图缩放误差。

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

- 测试一(只改V):Task B,茶壶固定,M参数全为0/1。front(0,0,8)→side(8,0,0)→top(0,8,0)→iso(6,4,7)→front。四次`stat-world`均为`(0.00, 0.00, 0.00)`,eye与V在变;回到front后画面与最初一致。截图`截图/B1-正面视角.png`、`B2-侧面视角.png`、`B3-顶部视角.png`、`B4-斜上方视角.png`。
- 测试二(只改P):Task C,M、V不变,near=0.1、far=100、FOV=50、正交高度5.5,`compare`打开。透视下近处立方体(z=0)明显大于远处(z=-3);正交下两者屏幕高度完全相同。截图`截图/C1-透视对照.png`、`C2-正交对照.png`。
- 测试三(只改FOV):透视50°→110°,茶壶与立方体占比下降、仍居中;正交下改FOV画面不变(FOV不进入正交矩阵)。截图`截图/C5-透视FOV110.png`;正交高度5.5→11时整幅画面等比缩小且两立方体仍相等,见`C3-正交高度加大.png`。

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

AI结论正确。但我修正了一个认识:我原以为“增大FOV等于缩小模型”,实测FOV只改变投影矩阵的`cot(fov/2)`因子,M、V、世界尺寸都没变,只是成像变小;正交矩阵中没有FOV项,所以改FOV画面不动——这正好证明FOV属于P而不属于M。另外顶部视角我第一次仍用`up=(0,1,0)`,画面出现NaN/黑屏,改成`up=(0,0,-1)`后正常,验证了AI提醒的退化条件。

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

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

按指导书允许的方式,我备份后**故意制造了两处可恢复错误**:

- 故障A(Task C):把投影函数的`aspect`临时写成固定值1.0(模拟“宽高比取错”),茶壶被横向压扁;Console无WebGL报错,只有画面异常。
- 故障B(Task D):Shift+拖动时把像素增量直接加到世界X/Z,没走相机基向量。正视图方向看起来正确,切到侧视图后水平拖动却让模型前后移动。

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

> 我的OBJ能显示,但切换透视投影后形状被拉伸/裁剪或者鼠标拖动方向异常。请从宽高比、裁剪面、矩阵顺序和观察基向量中提出至少三种假设,分别给一项最小测试,先帮助排查,不要直接重写完整程序。

**3. AI建议的至少两个可区分原因及测试**

- 假设1:`aspect`取值不对(固定值/旧尺寸≠当前Canvas的`width/height`)。测试:打印`scene.resize()`返回值,并计算`P[0]`应等于`1/(tan(FOV/2)·aspect)`;若`P[0]`对不上则成立。
- 假设2:FOV单位错误(度未转弧度)。测试:打印`fov*RAD`,FOV=50时应为0.8731;并核对`P[0]≈1/(tan25°·aspect)`。
- 假设3:矩阵顺序/行列向量混用。测试:只把模型平移(1,0,0),打印`P·V·M·[1,0,0,1]`,看是否沿世界X移动。
- 假设4(对应拖动):相机基向量未按当前eye/target重算,或`right=forward×up`顺序反了。测试:eye=(8,0,0)时打印`forward×up`应为(0,0,-1),再拖100px看`tz`是否变化。

**4. 我逐项测试了什么、结果如何**

- 假设1:aspect=1.537时正确`P[0]`应=1.3950,故障版打印`P[0]`=2.1445(横向被压扁约1.54倍)→成立。恢复使用`render()`传入的真实`aspect`后,`P[0]`回到1.3950,拉伸消失。
- 假设2:`fov*RAD`=0.8731,透视`P[0]`=1.3950=1/(tan25°×1.537)→排除。
- 假设3:平移(1,0,0)后NDC沿X移动→排除。
- 假设4:eye=(8,0,0)时`forward`=(-1,0,0),`forward×up`=(0,0,-1);故障版侧视图拖100px得到`T=(1.148,0,-1.148)`(同时混入世界X),与预期`(0,0,-1.148)`不符→成立。

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

- 根因A:Projection的宽高比被写成固定值、与当前Canvas比例不一致;修复在`task-c.js`,统一使用`app.js`传入的`aspect`(`scene.resize()`的`width/height`),并对`aspect<=0`抛出可读错误。
- 根因B:Shift拖动缺少相机基向量;修复在`task-d.js`新增`cameraBasis()`:`forward=target-eye`、`right=forward×up`(右)、`cameraUp=right×forward`,再按“每像素世界长度=可视世界高度/画布CSS高度”换算(透视`2·d·tan(FOV/2)`,正交用正交高度)。
- 修复后:正视图右拖100px→`T=(1.247, 0, 0)`;侧视图右拖100px→`T=(0, 0, -1.148)`,沿画面右方向;截图`截图/D1-鼠标键盘变换.png`。

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

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

“茶壶壶嘴–把手方位观察台”:固定参考点P(1.5,0.6,0),橙色标记绕P转,观察不同方位下壶嘴/把手的相对位置,并区分“绕指定点旋转”与“模型自转”。

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

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

AI给出两个方案:

- 方案甲:**绕点轨道 + 父子继承**。`M_orbit=T(P)·Ry(θ)·T(-P)·T(q)·S`,子部件`M_child=M_orbit·T(offset)·Ry(2θ)·S`;交互参数只有`orbit`角度;验证用标记中心闭式解对表。
- 方案乙:**双画布投影对照**。左右两个canvas共用M/V、只让P不同,拖动同步;矩阵链不变,但要维护两套上下文/缓冲区和同步逻辑,截图只能截一侧。

**3. 两种方案的功能、矩阵链、测试难度对比**

| 项目 | 方案甲:绕点轨道+父子继承 | 方案乙:双画布对照 |
|---|---|---|
| 功能 | `T(P)R T(-P)`、父子继承、轨迹可视化 | 同屏比较正交/透视 |
| 矩阵链 | 多一层`T(P)·Ry·T(-P)`与子矩阵 | 不变,仅复制P |
| 交互参数 | `orbit`一个角度 | 双画布拖动/滚轮同步 |
| 验证难度 | 低:中心坐标有闭式解 | 高:双上下文、双缓冲、同步易漏 |
| 风险 | 需解释“绕点≠自转” | 需改engine单canvas结构,时间不够 |

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

采纳**方案甲**,并加入两处自己的扩展(E3):①24个小方块画出轨迹圆,把旋转平面/半径可视化;②新增自拟相机预设“背面(0,1.2,-8)”与“低角度仰视(-5,-2.5,5)”,Task E面板加第二组按钮。理由:甲能在40分钟内完成、矩阵链可解析、可用坐标数值验证;乙要改engine单canvas结构,风险大于收益。**最终方案由我决定**:我否决了AI提议的“在甲中再加鼠标环绕相机”,因为它与Task D的滚轮语义重复,不增加评分点。

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

- 自拟视角:`ex.eyePreset`新增`back`、`low`(截图`B5-自拟背面视角.png`)。
- 轨迹圆:24个灰色小方块,`T(P)·Ry(i·15°)·T(r,0,0)·S(0.045)`,`r=|q-P|=0.8`。
- 父子继承:蓝色子块`M_child=M_orbit·T(0.95,0,0)·Ry(2θ)·S(0.45)`,位置随父块转、自身再自转,用于与“刚性整体旋转”区分。
- `js/ui.js`仅改Task E面板的按钮组与说明文字,不改渲染管线。

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

预测θ=90°时橙色标记中心`(1.50,0.60,-0.80)`,实测一致;θ=180°预测`(2.30,0.60,0)`,实测一致;θ=0预测`(0.70,0.60,0)`,实测一致;黄色P点恒为`(1.50,0.60,0)`。局限:轨迹圆未做透明/深度排序,极端角度会互相遮挡;自拟视角只加两个,未做任意参数输入。

## 全局诚信声明

- 我提交的代码均已本人运行并核验;A–E共18处TODO全部实现,数值核验见`验证记录.md`。
- AI辅助用于概念复核、故障假设列举、方案对比与代码讨论;矩阵推导、参数选择、故障根因判断与最终方案由我确认。
- 截图为实际运行画面(Chromium + WebGL2),不是示意图。