AI 协作日志

学生 Web 实验作品平台

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

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

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

## AI协作1:矩阵和变换次序
- 我自己的预测:正方形初始中心设在非原点位置。我预测 Rz(θ)·T(C) 是先平移到 C 再旋转,所以正方形会绕世界原点公转;T(C)·Rz(θ) 是先旋转再平移,正方形应该原地自转、中心保持不动。我也猜到两种写法结果肯定不同(矩阵没有交换律),但具体差多少、哪个转得对,我没有把握。
- AI工具与原始提示词:豆包(电脑端网页版)。提示词原文:"列向量约定下矩阵乘法是不是右边的先作用?正方形中心不在原点,R*T(C) 和 T(C)*R 分别是什么效果,哪个是绕世界原点转,哪个是绕自身中心转?角度直接传度还是转弧度?"
- AI的建议:AI 确认列向量下"右侧矩阵先作用":R·T(C) 中顶点先被平移到 C 再被 R 绕世界原点旋转,效果是公转;T(C)·R 中顶点先局部旋转再平移到 C,是自转。还提醒了两点:gl-matrix 是列主序,uniformMatrix4fv 传 false 不要转置;三角函数前必须把度换算成弧度(我一开始确实差点直接拿度去算)。
- 本人计算、运行与证据:我按指导书表格把平移、缩放、Z 轴旋转、Y 轴旋转、平移作用于方向向量这几项矩阵测试逐项核对,预期结果与运行输出一致,task-b 页面矩阵测试面板全部显示 ✓。运行验证:B 页把正方形中心设在非原点、角度调成 90°,旋转中心选"世界原点"时正方形绕画布中心转圈,选"对象自身中心"时原地自转,与我的预测一致。
- 采纳或修正结论:采纳 AI 关于矩阵次序和列主序的结论。修正了一处:AI 顺带建议动画缩放用正弦函数实现,但那是 Task C 的内容,B 任务里我坚持用固定角度做静态旋转,先把矩阵本身验证对再进入动画。最终矩阵函数 R(axis,rad) 内部统一用弧度,由页面角度控件负责转弧度。

## AI协作2:实际故障排查
- 错误现象与重现步骤:动画暂停后点"继续",图形会突然跳一大截;运行中把浏览器切到别的标签页再切回来,图形位置也会猛地变化。重现:C 任务页面点"暂停动画"等几秒再点"继续",正方形角度瞬间变大;或运行中切后台标签页一段时间再切回来观察。
- 我先检查了什么:先在 Console 里打印每次 tick 的 dt 和 obj.elapsed。发现切后台回来那一次 dt 异常偏大;暂停时 running=false,elapsed 没有累加。所以先排除了"暂停没生效"和"rAF 循环重复启动"(构造函数里只有一处 requestAnimationFrame)。
- AI工具与原始提示词:豆包。提示词原文:"requestAnimationFrame 回调的时间戳是毫秒,我 dt=(now-last)/1000,暂停恢复和切标签页回来图形会突跳,可能是什么原因?应该怎么修?"
- AI建议的候选原因与测试:AI 列出 4 个候选:(1) 切后台时浏览器暂停 rAF,回来后时间戳跳变使 dt 异常大,应给 dt 设上限或重置 lastMs;(2) 暂停期间 lastMs 没同步更新,恢复后第一次 dt 把暂停时间也算进去;(3) 存在多个 rAF 循环同时跑;(4) 角度按"每帧固定增量"累加而不是按 elapsed 累加。让我分别测试:打印 dt 数值、全代码搜 requestAnimationFrame 调用次数、暂停时同步 lastMs。
- 实测结果、修复与复测:实测只有一个 rAF 循环,暂停逻辑也正常,问题确认在 dt。修复:给 dt 加上限保护,并且只在运行且全局速度>0 时累加 obj.elapsed。复测:暂停一段时间再继续,画面保持原样、继续后从原位置接着动;切后台较长时间回来也不突跳。修复后我在 C/D/E 三个页面都重跑了一遍确认。

## AI协作3:设计方案比较
- 我考虑的两种实现:方案一:每帧重新生成对象的局部顶点数组再 gl.bufferData 上传 GPU,动画效果直接改顶点坐标;方案二:几何数据只上传一次(Buffer/VAO),每帧只重算每个对象的 4×4 Model 矩阵,用 uniformMatrix4fv 传给 Shader。截图也对比过 canvas.toBlob 和 gl.readPixels 自编码 PNG 两条路。
- AI工具与原始提示词:豆包。提示词原文:"对象动画每帧都在变,是每帧重新算顶点上传 Buffer 好,还是顶点只上传一次、每帧只改 Model 矩阵?多对象场景下哪个更合适?截图用 canvas.toBlob 还是 gl.readPixels 编码 PNG?"
- 对比、取舍与原因:方案一代码直观但每帧要把全部顶点乘一遍再上传,对象一多就浪费带宽,而且基于"当前坐标"累加容易累积浮点误差导致漂移;方案二把几何和运动分开,局部顶点只上传一次,每帧只算一个矩阵,矩阵正确性还能用数值测试验证,多对象时明显更划算。截图:toBlob 需要 preserveDrawingBuffer:true 并先主动重绘,但代码短、浏览器原生支持;readPixels 不依赖 preserveDrawingBuffer,却要自己处理像素顺序翻转和 PNG 编码,工作量大还容易错。综合考虑选了方案二 + toBlob,时间成本低、好维护。
- 实际实现及核验:geometry.js 四种形状顶点只在初始化生成一次,graphics.js 构造时上传成静态 Buffer/VAO;每帧 draw() 遍历 objects,用 modelFor(obj) 算出各自 Model 矩阵再绘制。savePNG() 先主动 draw() 一次再 toBlob 下载。核验:B 页矩阵数值测试全 ✓;C 页跑多个周期圆一直保持往复缩放、三角形往复不漂移;E 页按验收流程添加 6 个对象(含全部四种形状)各自按参数运动、暂停/速度正常;保存的 PNG 打开后背景和图形都在、尺寸与 Canvas 一致;改画布尺寸后圆仍是圆。