AI 协作日志

学生 Web 实验作品平台

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

# 实验四 AI协作记录

> 学号:202412211402001
> 姓名:董卜文
> AI工具与使用版本(如适用):Trae CN IDE 内置 AI 助手(Kimi-K3),用于概念核验、调试诊断与方案协商。  
> 请用真实过程填充,保留关键提示词原文;不要只贴整段AI代码或聊天截图。

## 协作1:变换次序核验(Task B)

### 我的目标与先验预测

目标:在列向量约定下,对同一单位立方体、同一组参数 tx=2、θ=90°、s=1,比较 M1=T·Ry·S 与 M2=Ry·T·S 作用于局部原点 (0,0,0) 后的世界坐标。

先验预测(动手算,再看画面):

- M1:原点经 S、Ry 都不动,最后 T(2,0,0) 平移 → 中心应为 **(2,0,0)**。
- M2:原点先被 T 移到 (2,0,0),再被 Ry(90°) 整体旋转。右手系绕 Y 轴:x'=x·cosθ+z·sinθ,z'=-x·sinθ+z·cosθ,代入 θ=90° 得 x'=0、z'=-2 → 中心应为 **(0,0,-2)**。

### 关键提示词

> 在WebGL2的列向量约定下,局部原点为(0,0,0),平移(2,0,0),绕Y轴旋转90°。请分别分析T·R与R·T的世界中心位置和计算步骤,并建议我要打印哪些数值进行核验;不要直接重写完整程序。

### AI建议摘要

- 列向量约定下矩阵从右向左作用:T·R 中 R 先作用于顶点,T 后作用;R·T 相反。
- T·R:平移在最左、最后执行,平移方向就是世界 X 方向,中心落在 (2,0,0)。
- R·T:平移先发生,产生的位移向量 (2,0,0) 随后被 Ry(90°) 旋转到世界 -Z 方向,中心落在 (0,0,-2)。
- 建议不要只凭画面判断,应打印 `CG4.point(model,0,0,0)` 的数值,并至少测 θ=0°、90°、180° 三组角度。

### 我的判断与手算

AI 的数学分析与我的预测一致。我另外手算了 θ=180° 的情况:M2 中心 = Ry(180°)·(2,0,0) = (-2,0,0),而 M1 中心仍是 (2,0,0);θ=0° 时 Ry 是恒等矩阵,两种次序结果必然相同——这只是特例,不能用来推断矩阵乘法可交换。

### 我实际测试的参数与坐标

在 task-b.html 中实际运行三组参数(tx=2、s=1 固定):

| θ | M1=T·Ry·S 中心(预测) | M1 实测 | M2=Ry·T·S 中心(预测) | M2 实测 |
|---|---|---|---|---|
| 0° | (2,0,0) | (2.00, 0.00, 0.00) | (2,0,0) | (2.00, 0.00, 0.00) |
| 90°(一键测试按钮) | (2,0,0) | (2.00, 0.00, 0.00) | (0,0,-2) | (0.00, 0.00, -2.00) |
| 180° | (2,0,0) | (2.00, 0.00, 0.00) | (-2,0,0) | (-2.00, 0.00, -0.00) |

### 运行现象/数值结果

状态栏数值与手算完全一致(180° 的 -0.00 是 sin180°≈1.2e-16 的浮点显示,可视为 0)。画面上暖色立方体(T·R·S)始终位于 +X 侧,青色立方体(R·T·S)随 θ 绕世界原点转动;θ=90° 时位于 -Z 方向,与预测位置吻合。

### 修正结论

预测全部命中,无需修正。结论:T 与 R 不可交换——T·R·S 中平移最后执行、方向固定为世界 X;R·T·S 中平移向量先产生、再被旋转带走,因此同一组参数得到不同世界中心。θ=0° 两者相同只是恒等旋转的特例,不构成"矩阵乘法可交换"的证据。

## 协作2:程序调试(Task C或D)

### 错误现象与自己的初步分析

按指导书许可,我在 Task C 中主动制造了一处可恢复的矩阵错误:把绕点旋转矩阵写成 `M = T(P)·Ry(θ)·T(q)·S`,**漏写了 T(-P)**。

初步测试 P=(0,0,0)、θ=90°:绕点旋转中心显示 (0.00, 0.00, -2.00),与正确结果一致——**错误被掩盖了**。把 P 改为 (1,0,0) 后问题暴露:θ=90° 时绕点旋转中心实测为 (1.00, 0.00, -2.00),而正确值应为 (1,0,-1)。我的初步假设:P 没有真正"移回原位",即 T(P)·Ry·T(-P) 的括号结构不完整。

### 提示词

> 我的三维对象能显示,但修改父关节角度后探头位置异常。请提出三个最有可能的矩阵顺序或局部坐标错误,每个错误给出一项能区分原因的测试,不要直接替我重写整份代码。

(实际提问时把现象替换为:绕指定点 P 旋转时,P 不在原点则物体中心位置不对。)

### AI提出的可能原因

1. **漏写 T(-P)**:旋转实际围绕"世界原点平移 P"之后的轴进行,P 越偏离原点误差越大。区分测试:把 P 从 (0,0,0) 改为 (1,0,0),若结果变化量不符合 T(P)·R·T(-P) 的手算值,即可定位。
2. **T(-P) 与 T(P) 写反**:变成先移回再移出,误差方向相反。区分测试:同上设 P=(1,0,0),比较实测偏差方向。
3. **把初始中心 q 当成了 P 系下的坐标**(q 与 P 不属于同一坐标系)。区分测试:令 P=q=(2,0,0)、θ=90°,正确结果应仍为 (2,0,0)(绕自身中心),若结果偏移则坐标系混用。

### 我逐项完成的测试

| 测试 | 参数 | 实测 | 手算正确值 | 结论 |
|---|---|---|---|---|
| ① P 在原点 | P=(0,0,0), θ=90° | (0.00, 0.00, -2.00) | (0,0,-2) | 通过(假象) |
| ② P 非原点 | P=(1,0,0), θ=90° | (1.00, 0.00, -2.00) | (1,0,-1) | 暴露:z 分量多了 -1,正好是 P 没有被 T(-P) 先移到原点的表现 |

逐项注释矩阵因子后确认:chain 中缺少 `c.T(-pivot[0],-pivot[1],-pivot[2])`,即原因①。原因②③经同一组测试排除(偏差方向与数量级不符)。

### 真实原因与修复

真实原因:`M_orbit` 漏写 T(-P),导致旋转轴不是"过 P 且平行 Y 的轴"。修复为 `M_orbit = T(P)·Ry(θ)·T(-P)·T(q)·S`(见 js/task-c.js TODO C2)。修复后复测:P=(1,0,0)、θ=90° 时绕点旋转中心 = **(1.00, 0.00, -1.00)**,与手算一致;P=(0,0,0) 及转满 360° 回到初始位置均正常;暂停 2 秒再继续,角度无突跳。

### AI建议是否采纳及理由

采纳了原因①及其区分测试,因为它一次性解释了所有观测。教训:**只在 P=原点 时测试不足以暴露绕点旋转的错误**(此时 T(P)、T(-P) 都是恒等矩阵,错误不可见);验证绕点旋转必须选取非原点的参考点,并用 `CG4.point()` 数值对照,而不是只看画面"像在转"。

## 协作3:主题场景协商(Task E)

### 我希望实现的对象关系

希望一个场景同时覆盖本实验的两类核心机制:一组真实的多级父子继承(父动子随、子动父不动),外加一组"自转 vs 绕点公转"的对照,并且所有关键点都能用世界坐标数值验证,而不是只凭画面。

### 关键提示词

> 我已实现T·R·S、绕指定点旋转和两级父子变换。请提出两个可在40分钟内用简单立方体完成的三维联动场景,并比较部件关系、矩阵链、交互参数、验证难度。请复用现有WebGL2框架,不引入相机拾取、光照或外部库,也不要直接生成整套代码。

### AI提供的两个方案与比较

- **方案一:行星—卫星系统。** 太阳自转(T·Ry·S),行星绕太阳公转(T(P)·Ry·T(-P) 类结构),卫星作为行星的子对象再叠加一层局部轨道。优点:自转/公转对照直观;缺点:层次只有"行星→卫星"一级,且全部围绕同一中心,验证点单一。
- **方案二:定位装置+旋转样本台。** 左侧"基座→机械臂→探头"为两级父子(yaw 偏航 + pitch 俯仰两个独立关节),右侧样本台自转、标记绕样本中心公转。优点:同时包含父子继承与绕点公转两种机制,两个独立关节参数可直接用状态栏末端坐标做数值验证;缺点:矩阵链稍长。

### 我的选择理由

选择方案二(保留教师主题并做实质修改):它强制我把"位姿矩阵"和"绘制矩阵"分开(非均匀缩放不能下传),这是 Task D 的核心考点;同时样本台的自转与标记的公转提供了第二套独立机制。相对教师示例,我的修改为:样本自转与标记公转采用不同角速度(65°/s 与 42°/s),公转标记带径向偏移 1.16 与高度差 0.28,使其轨迹明确为圆周而非"同步转动";基座置于 (-2,-1.3,0) 与样本台 (2,-0.48,0) 分离,避免两组机制互相遮挡。

### 实际矩阵链与交互参数

- 基座位姿 `Mbase = T(-2,-1.3,0)·Ry(yaw)`;肩部 `Mshoulder = Mbase·T(0,0.55,0)·Rz(pitch)`;末端 `Mtip = Mshoulder·T(0,2.2,0)`;探头绘制 `Mprobe = Mtip·T(0,0.32,0)·S(0.73,0.65,0.73)`(缩放只在绘制矩阵局部)。
- 样本自转 `M = T(2,-0.48,0)·Ry(65t)·S(0.7,0.78,0.7)`;标记公转 `M = T(2,-0.48,0)·Ry(42t)·T(1.16,0.28,0)·S(0.22)`。
- 独立参数:yaw、pitch(关节)+速度倍率(0—3×);暂停/继续、重置、PNG 截图均保留。

### 两组对照测试

| 状态 | 预测(手算) | 实测 | 结论 |
|---|---|---|---|
| ① yaw=25°、pitch=-20° | 末端 = (-2-2.2·sin20°·cos25°, -0.75+2.2·cos20°, -2.2·sin20°·sin25°) ≈ (-1.32, 1.32, -0.32) | (-1.32, 1.32, -0.32) | 一致 |
| ② pitch=0°,yaw 由 0° 改 60° | 末端在基座 Y 轴线上,yaw 不改变其世界坐标,恒为 (-2, -0.75+2.2, 0) = (-2.00, 1.45, 0.00);仅臂与探头朝向整体偏航 | yaw=0° 与 yaw=60° 时均为 (-2.00, 1.45, 0.00) | 一致 |

动画验收:暂停后"已运行秒数"停在 3.2 秒且画面保持;继续后从 3.2 秒无突跳增长;速度改 2× 后转动明显加快;保存的 PNG 可打开、非空白,尺寸与画布一致。

### 最终结果和反思

场景满足全部硬性条件:6 个可区分部件(基座、臂、探头、转台、样本、标记)>3;父子关系基座→臂→探头真实存在(改 yaw 全随、改 pitch 基座不动);复合机制两种以上(父子关节、自转、绕点公转);独立参数两个以上。反思:把"关节位姿"与"部件绘制矩阵"分开是本场景最关键的设计——若把臂段的 S(0.38,2.2,0.45) 传入末端,探头会被一起拉长且位置偏移,Task D 的归零验证立即能暴露该问题;数值对照(point 打印)比肉眼观察可靠得多。

## 附:Task A 与 Task D 数值核验记录

**Task A(对应 TODO A2 预测核验)**:预测局部原点经 S、Ry 均不动,中心恒为 (tx,ty,tz)。实测:默认参数 tx=1.2、ty=0.3、tz=0、θ=35°、s=1.2 时中心 (1.20, 0.30, 0.00);验收参数 tx=1、ty=0、tz=0、θ=90°、s=1 时中心 (1.00, 0.00, 0.00);仅把 s 改为 2,中心仍 (1.00, 0.00, 0.00)——缩放不改变中心,预测成立。

**Task D(对应 TODO D5 控制变量验证)**:

| 测试 | 实测 | 说明 |
|---|---|---|
| yaw=0°、pitch=0°(归零) | 肩部 (0.00, -0.75, 0.00);末端 (0.00, 1.45, 0.00) | 正常装配 |
| 固定 yaw=0°,pitch=-30° | 末端 (1.10, 1.16, 0.00);肩部不变 | 手算 x=2.2·sin30°=1.10,y=-0.75+2.2·cos30°≈1.16,一致;子动父不动 |
| pitch=0°,yaw=40° | 肩部 (0.00, -0.75, 0.00)、末端 (0.00, 1.45, 0.00) 均不变,臂与探头朝向整体偏航 | 两关节都在 Y 轴线上,坐标不变但朝向随基座——父动子随 |