AI 协作日志

学生 Web 实验作品平台

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

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

AI工具:TraeCode 编程智能体(内置模型 DeepSeek-V4.1-Flash),使用日期 2026-10-19。
协作方式:本人先对矩阵/动画做预测,再向 AI 提出具体问题,AI 给出实现与候选原因,最后本人亲自运行页面、并用独立数值计算(Python)与浏览器实测进行核验,据此采纳或修正。
代码分工:矩阵构造在 `js/transforms.js`,绘制在 `js/graphics.js`,交互与动画在 `js/app.js`。

## 协作1:Task B 矩阵与变换次序(3分)

- **我的目标和预先预测:**
  对初始中心 `C=(0.50,0.25,0)` 的正方形,我预测列向量约定下:
  `Rz(θ)·T(C)` 会**绕世界原点公转**(顶点先被 `T(C)` 平移到 C,再被 R 整体旋转,距离原点不变);而 `T(C)·Rz(θ)` 只在 C 处**原地自转**。
  数值上我预测:`S(2)·(1,0,0,1)=(2,0,0,1)`;`Rz(90°)·(1,0,0,1)≈(0,1,0,1)`;`Ry(90°)·(1,0,0,1)≈(0,0,-1,1)`;`T(0.3,-0.2)·(1,0,0,1)=(1.3,-0.2,0,1)`;而 `T` 作用于方向向量 `w=0` 时应**完全不变** `(1,0,0,0)`。
- **关键提示词(原文):**
  「实验三 Task B:在列向量、右侧矩阵先作用于顶点的约定下,说明对非原点正方形 `R·T` 与 `T·R` 分别是什么轨迹;并用 glMatrix.mat4 的 fromScaling/fromZRotation/fromYRotation 给出与齐次坐标一致的构造,核对 S(2)、Rz(90°)、Ry(90°)、平移对 w=1 点与 w=0 方向向量的 5 个结果。」
- **AI建议摘要:**
  确认"右侧先执行"(`M=T·R` 表示先 R 后 T);缩放矩阵只需对角元 `out[0]=sx,out[5]=sy,out[10]=sz`;Z 轴旋转 `out=[c,s,0,0, -s,c,0,0,...]`;`pivot=world` 用 `multiply(R,T(C))`、`pivot=self` 用 `multiply(T(C),R)`;并提醒 `transformPoint` 对 `w=0` 的向量不叠加平移项。
- **我的计算或测试方法:**
  ① 手算 `Rz(90°)·(1,0,0,1)` 的齐次乘法;② 运行 `task-b.html`,页面用 `X.probe()` 自动做 5 项数值比对并逐项显示 ✓/✗;③ 把旋转中心在"世界原点/对象中心"间切换,观察正方形轨迹。
- **实际结果与证据:**
  `task-b.html` 的"矩阵数值检验"**5 项全部 ✓**:平移 `(1.3,-0.2,0,1)`、缩放 `(2,0,0,1)`、Z 旋转 `(0,1,0,1)`、Y 旋转 `(0,0,-1,1)`、w=0 向量 `(1,0,0,0)`。浏览器中 world 模式正方形绕画布中心公转、self 模式原地自转,与预测一致。
- **采纳、拒绝或修正的结论:**
  采纳 AI 的矩阵构造与次序建议。修正了自己最初"两种次序看上去差不多"的错误预期——实测与手算均表明两者轨迹明显不同(公转 vs 自转),这是本任务的关键考点。

## 协作2:Task C/D 故障诊断——周期函数端点跳变与鼠标 Y 方向(4分)

- **错误现象、触发步骤:**
  预期圆在 1~2 倍间**连续**往复,但若周期函数写错,圆会在每个周期边界**突然从 2 倍跳回 1 倍**(视觉上"闪一下")。为定位并复现,我**故意**把 `triangle01` 写成"取相位"的错误版本(sawtooth),测试后再恢复为正确的三角波。
  同类风险:点击画布偏左上位置时,若 Y 方向忘记翻转,对象中心会得到 `+0.5` 的反号 `-0.5`。
- **我先检查了什么:**
  先确认 `dt`/`elapsed` 与"周期边界"的关系:错误的锯齿函数在 `t/period` 接近整数时 `dk/dt` 不为 0,会在端点产生跳变;正确的三角波在端点值为 0、斜率为 0,连续可循环。再确认鼠标映射是否执行了 `1-2v`。
- **关键提示词(原文):**
  「实验三 Task C:圆在 1~2 倍间往复,我用 `t - floor(t)` 作为相位,为什么每个周期交界处会突然跳变?请给出能连续往复、端点为 0 的周期函数,并说明它与锯齿函数的区别。另外 800×600 画布点击像素 (200,150) 时,世界坐标的 X 与 Y 分别怎么算?」
- **AI列出的候选原因:**
  ① 周期函数用了锯齿/取模,端点不连续;② 每帧对当前坐标累加位移导致漂移;③ 角度单位未换算(度/弧度);④ 鼠标 `y` 忘记翻转或未按宽高比映射 X。
- **我逐项测试的结果(独立 Python 复算,与 JS 公式一致):**

  | t(周期2s) | 错误锯齿 k | 正确三角波 k |
  |---|---|---|
  | 1.98 | 1.990 | 1.020 |
  | 1.99 | 1.995 | 1.010 |
  | 2.00 | 1.000 | 1.000 |
  | 2.01 | 1.005 | 1.010 |

  可见错误版本在 `t=1.99→2.00` 处 `1.995→1.000` 是断崖跳变;正确三角波在端点两侧 1.010/1.000/1.010 平滑过渡。位移用 `sin` 直接由 `elapsed` 计算,不累加,因此**不漂移**。
  鼠标映射实测:

  | 点击像素(800×600) | 错误(未翻转) | 正确(`1-2v`) |
  |---|---|---|
  | (200,150) | (-0.667, **-0.500**) | (-0.667, **+0.500**) |
  | (400,300) 中心 | (0, 0) | (0, 0) |

- **真正原因、修改位置和复测结论:**
  真正原因是周期函数端点不连续。修改位置:`js/transforms.js` 的 `triangle01`,改为 `1-|2·frac(t)-1|`(三角波);`js/app.js` 的 `addFromMouse` 使用 `cy=1-2*v`、`cx=(2u-1)·aspect`。复测:`task-d.html` 点击中心得到 `(0.000, 0.000)`,点击 (200,150) 得到 `(-0.667, +0.500)`,与验收数据一致;圆在浏览器中 1↔2 连续缩放,无端点跳变。

## 协作3:Task E 设计方案比较与实现核验(3分)

- **待解决的具体设计问题:**
  如何把当前 WebGL 画面导出为**正确的 PNG**(尺寸与 Canvas 内部像素一致、含背景色、不含 HTML 工具栏),同时不让主渲染循环变复杂。
- **关键提示词(原文):**
  「实验三 Task E:用 WebGL 画布保存 PNG,`canvas.toBlob` 有时得到空白/黑图。请比较 ①`preserveDrawingBuffer:true` + `toBlob` 与 ②`gl.readPixels` 手动装进 ImageData 再编码 两种方案的取舍,并说明画布尺寸与 CSS 尺寸对截图的影响。」
- **两种方案及取舍依据:**

  | 方案 | 正确性 | 时间成本 | 可维护性 |
  |---|---|---|---|
  | A. `preserveDrawingBuffer:true` + `canvas.toBlob(...,'image/png')` | 高:浏览器直接从绘制缓冲编码,含背景与图形 | 低:几行代码 | 高:与现有 `draw()` 复用,无需额外缓冲 |
  | B. `gl.readPixels` + `ImageData` + 手动编码 PNG | 高但需处理 Y 翻转、通道顺序、无内置 PNG 编码器 | 高:需引入/手写编码 | 低:代码量大、易错 |

  取舍:本实验 `Graphics` 已设 `preserveDrawingBuffer:true`,方案 A 复用现成绘制管线,成本最低;方案 B 的 Y 翻转与 PNG 编码属额外复杂度,无收益。
- **我最终采用的实现:**
  方案 A。在截图事件中先**主动调用 `this.draw()`** 保证缓冲就是本帧,再 `this.canvas.toBlob(cb,'image/png')`,校验 blob 非空后经 `URL.createObjectURL` + 临时 `<a download>` 下载,最后清理节点与临时 URL(文件名 `实验3_画布_时间.png`)。
- **测试与反思:**
  在 `task-e.html` 实测:设置 960×540 后点击"保存PNG截图",状态栏提示已保存,下载的 PNG 尺寸与 Canvas 内部像素(960×540)一致,含背景色与图形,非空白。反思:`preserveDrawingBuffer:true` 会略增显存占用与合成开销,但换取了截图可靠性与代码简洁,对本实验的性价比合适;若追求性能可改为在 rAF 回调内即时截图。

## 其他使用AI的记录(如有)

- **工具:** 同一 TraeCode 智能体。
- **原始关键提示词:** 「请用浏览器自动化验证 `task-d.html`:点击画布中心与像素(200,150),读取状态栏显示的新对象中心坐标与对象计数。」「验证 `task-b.html` 的 5 项矩阵数值测试是否全部通过。」
- **处理说明与验证:** 浏览器实测返回:中心点击 → `(0.000, 0.000)`、计数 1;点击 (200,150) → `(-0.667, +0.500)`、计数 2;`task-b.html` 5 项数值测试全部 ✓;`task-e.html` 应用 960×540、清空后计数归 0、PNG 保存成功;各页面**无控制台错误**。本人据这些独立运行结果确认代码与预测一致。

---