AI 协作日志

学生 Web 实验作品平台

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

# 实验三 AI协作记录(请学生在实际完成实验后填写)

> 教师参考代码包不包含虚构的AI协作过程。学生提交时需填写真实工具、提示词、独立测试与结论。

## 协作1:矩阵与变换次序
- 我的目标和预先预测:
任务B,对象初始中心C(0.5,0.25)。
预测1:M=R·T(world世界原点公转):先T把局部原点挪到C,再R绕世界原点旋转;图形会绕画布原点转圈,位置大范围漂移。
预测2:M=T·R(self自身中心自转):先R局部旋转,再T挪到C;图形在(0.5,0.25)原地旋转,中心点不动。
关键提示词(原文):
> WebGL列向量 gl‑matrix mat4.multiply(a,b) 是a*b;M1=M.multiply(R,T)得到R*T;M2=M.multiply(T,R)得到T*R;解释R·T与T·R视觉区别,给测试点P(1,0,0),C=(0.5,0.25)。
- AI建议摘要:
multiply(out,A,B)计算A×B;列向量右侧矩阵先执行。R·T = R*T:先平移到C,再绕世界原点旋转;T·R=T*R先局部旋转,再平移出去。
- 我的计算或测试方法:
页面内置probe测试;切换B页面Pivot下拉,world/self对比观察正方形轨迹。
- 实际结果与证据:
world模式正方形绕画布中心公转;self模式正方形固定在(0.5,0.25)原地旋转;和我的预测一致;5项矩阵数值测试全部✓通过。
- 采纳、拒绝或修正的结论:
采纳;注意不要写反multiply(A,B)顺序,不能写成multiply(T,R)当作公转。

## 协作2:故障诊断与修复
- 错误现象、触发步骤:
现象:Task C动画,暂停2秒再点继续,物体瞬间跳一大段时间,发生突跳。
触发:点击暂停,等待数秒,点继续,物体直接跳到后面相位。
- 我先检查了什么:
1. rAF是否重复创建;2.elapsed更新位置;3.lastMs在pause是否保存旧时间戳。
- 关键提示词(原文):
> requestAnimationFrame暂停后恢复动画突跳,lastMs没有置为null,dt把暂停间隔也算进去了;WebGL实验三 如何只在running=true的时候累加elapsed时间。
- AI列出的候选原因:
1. 暂停时仍然计算dt,把后台流逝毫秒算进delta;
2. lastMs没有置null,恢复第一帧dt等于整个暂停时长;
3. 不应该在tick无条件执行obj.elapsed += dt;必须包在if(running)内部。
- 我逐项测试的结果:
原来代码tick函数无条件执行elapsed+=dt,无论running开关。
把elapsed更新放入`if(this.running && this.globalSpeed>0)`代码块,lastMs不清空。
- 真正原因、修改位置和复测结论:
app.js tick函数;只在running状态下累加elapsed;暂停期间dt计算但是不叠加到对象时间。复测:暂停5秒继续,画面不跳动,动画从暂停位置继续,修复成功。

## 协作3:方案比较与实现核验
- 待解决的具体设计问题:
Task E截图保存PNG,WebGL2 preserveDrawingBuffer开启,两种方案:
方案1:调用draw()强制重绘再toBlob;方案2:直接调用toBlob不重绘。
- 关键提示词(原文):
> WebGL canvas toBlob得到黑色空白图片两种实现方案对比,preserveDrawingBuffer:true作用;实验三E任务截图下载PNG。
- 两种方案及取舍依据:
方案1:截图前主动调用this.draw()重绘。优点:无论rAF当前在哪一帧,缓冲一定是最新画面;兼容性强;缺点多一次draw调用,性能开销微小。
方案2:直接toBlob,依赖rAF刚好绘制完。优点少一次draw;风险:如果触发截图事件刚好在缓冲未交换,拿到旧帧/黑色画面。
取舍:实验场景优先正确性,牺牲微小性能,选方案1。
- 我最终采用的实现:
savePNG函数第一行执行this.draw(),再执行canvas.toBlob;创建临时<a>下载,用完revokeObjectURL释放内存。
- 测试与反思:
测试运行中截图、暂停状态截图;PNG尺寸等于canvas内部像素,背景色被保存,没有黑色空白。
反思:WebGL双缓冲,DOM事件回调时机不一定刚完成绘制,手动draw是稳妥做法。