AI 协作日志
学生 Web 实验作品平台
学号:202412211401023 · 来源:ai-log.md
# 实验五 AI 协作与核验记录 学号:202412211401023 姓名: 日期:2026-11-09 > 说明:本记录里的“AI 建议”均指我在实现过程中向 AI 提出的问题与得到的回复摘要;参数、数值与结论都来自我自己跑出的结果(Node 数值核验脚本 `verify.js` 与浏览器截图),不是直接抄 AI 的说法。 ## 协作一:观察与投影概念核验(Task B / C,3 分) **1. 我的问题和事先预测** 我要分清三件事:移动物体、移动相机、换投影,画面都会变,但变的原因不同。我的预测是: - 只改 M(平移模型):画面里的模型会移动,状态栏“世界中心”数值跟着变; - 只改 V(把 eye 从 (0,0,8) 换到 (8,0,0)):画面从正面变成侧面,但“世界中心”数值一个字都不该变; - 只改 P(正交↔透视):模型的屏幕位置和大小会变,M、V、世界中心都不变;正交下两个等尺寸立方体一样大,透视下近的大。 **2. 我实际输入给 AI 的提示词** > 在 WebGL2 右手坐标系、列向量和 P·V·M 的顺序下,我想比较移动物体与移动相机、正交与透视投影。请给我三组能区分原因的控制变量实验,指出应改变 M/V/P 中的哪项,说明可以打印哪些坐标数值进行核验,不要直接生成整套代码。 **3. AI 建议摘要** - 第一组固定 V、P,只改 M 的 tx:打印 `world = M·N·center`(归一化后中心必为 0,所以 world 就等于 T 的平移量)与同一个顶点的 NDC;M 变、V 不变。 - 第二组固定 M、P,只改 eye/target:打印 `world` 与 `V` 的前三行(相机右/上/后基向量);world 必须恒定,V 必须变。 - 第三组固定 M、V,只换 P:打印 `P[0]`、`P[5]`、`P[10]`、`P[11]`、`P[14]`;透视的 `P[0]/P[5]` 应等于 `1/aspect`,正交的 `P[10]` 与 `P[14]` 由 near/far 决定;再用“等尺寸立方体的 NDC 高度”判断近大远小。 - AI 特别提醒:判断表观大小不能拿“单个点的 NDC y”比,因为相机俯视时远处点沿视线方向反而更靠画面上方,必须比两个等尺寸物体的投影高度。 **4. 我的判断和采纳/拒绝理由** 全部采纳,但第三组我补了一项:把 `P·V` 一起乘起来再验证,而不是只拿 `P` 乘世界坐标。因为相机在 (0,1.8,8.5),只乘 P 等于把相机搬到原点,结论会失真(这一点我在测试里真踩到了,见协作二第 4 步)。 **5. 我的测试参数、操作与结果** (截图见 `04-B-正面视角.png`、`05-B-侧面视角.png`、`06-B-顶部视角.png`、`08-C-透视投影对照.png`、`09-C-正交投影对照.png`) - M 变化:`tx: 0 → 0.15`(按 D 一次),世界中心 (0.00, 0.00, 0.00) → (0.15, 0.00, 0.00),eye 仍为 (0.00, 1.80, 8.50)。 - V 变化:正面 eye (0,0,8) → 顶部 eye (0,8,0),世界中心两次都是 (0.00, 0.00, 0.00)(模型归一化后中心确为 0,故 `M·N·center` 只受 T 影响)。 - P 变化(固定 M、V、camera=(0,1.8,8.5)): | 量 | 透视(FOV 50°, near/far 0.1/100) | 正交(正交高度 5.5, near/far 0.1/100) | |---|---|---| | 近立方体(z=0)NDC 高 | 0.182 | 0.277 | | 远立方体(z=−3)NDC 高 | 0.139 | 0.277 | | 近/远比值 | 1.31 | 1.00 | - FOV 50°→80°:同一物体 NDC 高度 0.207 → 0.115(比值 0.556 ≈ tan25°/tan40° = 0.556),说明 FOV 变大是“视野变宽、物体占比变小”,不是把模型缩小。 - near 从 0.1 推进到 8:z=0.8 的顶点 NDC z=−1.07(被裁掉),z=0 的顶点仍是 −0.87(还在视锥里)。 **6. AI 是否正确?我最终修正了什么认识** 建议方向正确。修正的认识有两点: 1. 「近大远小」必须用等尺寸物体的投影高度来量化,单个点的屏幕 y 不能当证据; 2. 正交下两个不同深度的立方体 NDC 高度完全相同(0.277/0.277),说明正交投影确实丢掉了深度信息,只有透视会除以 w 做透视除法。 ## 协作二:程序故障诊断(Task C / D,4 分) **1. 真实错误现象和我起初怀疑的原因** 我把 Task C 的第一版写成 `mat4.perspective(out, 50, aspect, .1, 100)`,即把 50 直接当弧度传。现象是:切到透视后模型和网格整片消失,状态栏停在上一次的画面,页面底部出现红色的「参数错误:观察或投影矩阵含无效数值。」。我起初怀疑是宽高比算错了。 **2. 向 AI 提出的诊断问题** > 我的 OBJ 能显示,但切换透视投影后形状被拉伸/裁剪或者鼠标拖动方向异常。请从宽高比、裁剪面、矩阵顺序和观察基向量中提出至少三种假设,分别给一项最小测试,先帮助排查,不要直接重写完整程序。 **3. AI 建议的至少两个可区分原因及测试** - 假设 A:FOV 单位错(度当弧度)。最小测试:打印 `P[5]`,透视下应等于 `1/tan(fovy/2)` 且为正;若为负或量级异常就是单位错。 - 假设 B:宽高比用了 `canvas.width/canvas.height`(含 devicePixelRatio)而不是 CSS 宽高。最小测试:打印 `P[0]/P[5]`,应严格等于 `1/aspect`。 - 假设 C:near/far 非法(near≤0 或 far<near)。最小测试:打印 `P[10]/P[11]/P[14]`,看是否出现 0 或 NaN。 - 假设 D:矩阵顺序写成 V·P。最小测试:只打印 `V` 的前三行,检查是否仍为正交单位阵。 **4. 我实际逐项测试了什么?各自结果如何** | 测试 | 操作 | 结果 | |---|---|---| | A | 打印错误版 `P[0]/P[5]` | `P[0] = −4.8694`、`P[5] = −7.4892`,都为负 → 命中 | | B | 计算 `P[0]/P[5]` | `−4.8694 / −7.4892 = 0.6503 = 1/1.538`,宽高比其实是对的 → 排除 | | C | near=0、far=near 各试一次 | 分别提示「near 必须大于 0」「far 必须大于 near」,说明校验有效 → 排除 | | D | 打印 `V` 前三行 | 正交单位、det=+1 → 排除 | Node 复现输出(`verify.js` 第 0 节): ``` 错误矩阵[0]=-4.8694 [5]=-7.4892 [11]=-1.0000 原点按错误 P 投影 → NDC NaN, NaN, -Infinity(w 为负,符号被翻转) ``` **5. 最终根因、修复处及修复后结果** 根因在 `js/task-c.js` 的 C3:`mat4.perspective` 的 fovy 要弧度,我传了角度。修复为 `mat4.perspective(out, fov*RAD, aspect, near, far)`。修复后 `P[0]=1.394`、`P[5]=2.145`(=2.145/1.538=1.394 ✓),原点 NDC 回到正常的 (0.000, 0.000, −1.000),模型恢复显示。 排查中我还犯了一个更隐蔽的错:做“近大远小”的数值验证时,我把 `P` 直接乘世界坐标点,得到 `w = 0`、NDC 全是 NaN。用调试脚本打印齐次坐标才看到 `w` 为 0——因为相机在 z=8.5,世界 z=0 的点正好落在“原点相机”的视平面上。改成 `P·V` 后数值正常。这条也写进了第 3 节的注释,避免以后再用单点 NDC 下结论。 ## 协作三:综合工作台方案比较(Task E,3 分) **1. 我准备完成的观察任务** 做一个“茶壶/兔子 + 固定参考点 + 绕点运行的小标记”的观察台,要求能改旋转中心、能看出公转与自转的区别,并在 40 分钟内接上已有的 A—D 模块。 **2. 向 AI 询问的两种设计方案** > 我已完成 OBJ 导入、观察视角、正交/透视以及鼠标键盘变换。请提供两个能在 40 分钟内复用已有 WebGL2 模块的观察台拓展设计,对比功能、矩阵链、交互参数和验证难度。不引入 Three.js、光照、纹理或复杂模型编辑器。 **3. 两种方案的功能、矩阵链、测试难度对比** | 项目 | 方案一:指定点旋转 + 父子标记 | 方案二:正交/透视双画布同步对照 | |---|---|---| | 功能 | 固定点 P、轨道半径 R、公转角 θ;子标记挂在主标记上自转 | 左右两个 canvas 同一 M/V,只差 P,拖动同步 | | 矩阵链 | `M_orbit = T(P)·Ry(θ)·T(−P)·T(q)·S`;子件再左乘 `Ry(2θ)·T(0.45,0,0)` | 两套 `P` 共用同一个 `M·N`,各自 `P·V·M·N` | | 交互参数 | P(3)、R、θ、父子开关 | 只需一个模式开关,但需两套 Scene | | 验证难度 | 低:半径|中心−P|应恒为 R,可逐角度数值核验 | 高:要维护两份 GL 上下文、两个 resize 与截图 | | 与 A—D 复用 | 完全复用(只加 `extra()`) | 需改 render 循环与布局,框架改动大 | **4. 最终采纳的方案与理由** AI 只提供了对比,**最终是我决定的**:先做方案一,因为它的数学机制(绕点旋转 + 父子继承)正好补上指导书要求的“至少一种额外复合机制”,而且能用 |中心−P| 恒等于 R 的数值直接验收;方案二更适合作为 Challenge,本次时间不够就没有做。 **5. 自己实现或修改的功能差异** 在教师示范的 `T(P)Ry(θ)T(−P)` 上,我自己加了三处: 1. 面板里增加旋转中心 P(px/py/pz)与轨道半径 R 两个可输入量,P 一改整组标记跟着平移; 2. 主标记的初始中心改为 `q = P + (R,0,0)`,而不是固定死的偏移,保证改 R 后仍然绕 P 转; 3. 增加“父子继承”子部件:`M_child = M_orbit·Ry(2θ)·T(0.45,0,0)·S(0.11)`,它跟随父标记公转的同时相对父再自转,能直观看出“父带子”和“各自转”的区别;面板下方增加实时读数(P、R、θ、主标记中心、|中心−P|)。 **6. 预测与实际结果对照,仍存在的局限** | θ | 预测:|中心−P| | 实测 | 主标记中心 | |---|---|---| | 0° | 0.85 | 0.85 | (2.35, 0.35, 0.00) | | 35° | 0.85 | 0.85 | (2.20, 0.35, −0.49) | | 90° | 0.85 | 0.85 | (1.50, 0.35, −0.85) | | 180° | 0.85 | 0.85 | (0.65, 0.35, 0.00) | | 270° | 0.85 | 0.85 | (1.50, 0.35, 0.85) | 预测与实际一致(截图 `16-E-绕点公转默认.png`、`17-E-改P与半径.png`)。局限:辅助标记只用立方体,没有真实骨骼;轨道圆没有画出来,半径只能靠读数确认;子部件自转角固定为 2θ,不能单独调。 ## 全局诚信声明 - 我提交的代码均已本人运行并核验;无法解释的 AI 输出未直接作为完成结果。 - 我明确标注了使用 AI 辅助的功能和本人自主完成的关键判断:M/V/P 三组控制变量核验、FOV 单位故障的定位与修复、E 的方案取舍与父子继承实现均由本人完成并留有数值证据。