AI 协作日志
学生 Web 实验作品平台
学号:202412211401007 · 来源:ai-log.md
# ai-log.md · 实验四 AI 协作记录 > 实验四:三维对象的复合变换与层次运动。 > 列向量约定:顶点按 `uProjection · uView · uModel · position` 变换;`c.chain(A,B,C) = A×B×C`, > 对列向量而言**右边矩阵先作用**,故 `M = T·R·S` 的执行顺序为:先缩放 S → 再旋转 R → 最后平移 T。 ## 协作点 1:变换次序核验(Task B) **我的目标与预测** 固定 `tx=2`、绕 Y 轴旋转 `θ=90°`、缩放 `s=1`,局部原点为 `(0,0,0)`。独立预测: - `M1 = T·R·S`:R、S 作用在原点上不改变原点,T 最后沿世界 X 轴平移 → 中心 `(2, 0, 0)`。 - `M2 = R·T·S`:先 S、再 T 得到 `(2,0,0)`,最后 Ry(90°) 把该平移向量旋转;右手系下 X 轴正向转到 Z 轴负向 → 中心 `(0, 0, -2)`。 **提示词** > 在 WebGL2 的列向量约定下,局部原点为 (0,0,0),平移 (2,0,0),绕 Y 轴旋转 90°。请分别分析 T·R 与 R·T 的世界中心位置和计算步骤,并建议我要打印哪些数值进行核验;不要直接重写完整程序。 **AI 建议摘要** 1. 列向量 `M·v`,`chain(A,B,C)=A×B×C`,越靠右的矩阵越先作用于顶点。 2. `T·R`:R 先作用于原点,原点保持不变;T 再平移到 `(2,0,0)`。 3. `R·T`:先 T 得到 `(2,0,0)`,Ry(90°) 将该点旋到 `(0,0,-2)`。 4. 核验手段:分别打印 `c.point(modelTRS,0,0,0)` 与 `c.point(modelRTS,0,0,0)`,与状态栏坐标对照;再取 θ=0°、180° 复核。 **我的判断**:矩阵乘法不可交换的核心在于平移向量是否被旋转矩阵后处理;AI 给出的矩阵顺序与坐标方向判断正确。 **测试或修改**:页面加载后点击“一键设置 90°测试”,读取状态栏两组中心坐标;另将 θ 分别置为 0°、180° 对照。 **结果**: - θ=90°:`T·R·S` 中心 `(2.00, 0.00, 0.00)`;`R·T·S` 中心 `(0.00, 0.00, -2.00)`,与预测一致。 - θ=0°:两者中心都为 `(2,0,0)`;θ=180°:`T·R·S` 为 `(2,0,0)`,`R·T·S` 为 `(-2,0,0)`。 **修正结论**:T 在最左(最后执行平移)时平移沿世界坐标轴;T 在中间(先平移后旋转)时平移方向被旋转带动。θ=0° 两式恰好相同只是角度特例,**不能**据此证明矩阵乘法可交换;任意非零旋转角下结果即出现差异。 --- ## 协作点 2:程序调试(Task C / Task D) **我的目标与预测**:先按正确公式实现,再主动制造一处可恢复的典型顺序错误,定位原因后修复,验证绕点旋转与父子继承。 **提示词** > 我的三维对象能显示,但修改父关节角度后探头位置异常;绕点旋转时物体也偏离了指定中心 P。请提出三个最有可能的矩阵顺序或局部坐标错误,每个错误给出一项能区分原因的测试,不要直接替我重写整份代码。 **AI 建议摘要** 1. **绕点旋转 `T(P)` 与 `T(-P)` 写反**:正确形式为 `T(P)·R·T(-P)·T(q)·S`;把两者颠倒后物体将围绕错误的镜像中心运动。测试:令 P=(0,0,2),转 90° 观察物体是否远离 P。 2. **父子位姿混入非均匀缩放**:若把臂段的拉长缩放传给下一层关节,子部件会被父缩放矩阵异常拉伸变形。测试:改动缩放参数,观察探头是否随之被拉长。 3. **误用行向量思维颠倒 chain 顺序**:应让父位姿位于 `chain` 最左侧。测试:打印肩部、末端关节局部原点的世界坐标,与理论装配位置比对。 **我的判断**:三点均为本实验高频坑点,分别对应绕点旋转、层次变换、矩阵约定三类错误,测试方法可互相区分。 **测试或修改** - 错误 1:将 `task-c.js` 的绕点链临时写成 `T(-P)·R·T(P)·T(q)·S`,运行后物体轨道中心偏离 P;P=(0,0,0)、θ=90° 时中心与预期 `(0,0,-2)` 不符。改回正确链 `T(P)·R·T(-P)·T(q)·S` 后恢复。 - 错误 2(D):曾把 `armDraw` 的 `S(.38,2.2,.45)` 直接作为 `tipPose` 传给探头,探头被纵向拉伸;改为“父位姿只含平移旋转、绘制缩放放在末端局部链最右”后恢复。 - 错误 3(D):肩部位姿未继承 `basePose`,而以世界原点重建;打印坐标后发现 yaw 旋转不带动肩部;把 `shoulderPose = chain(basePose, …)` 修复后继承关系成立。 **结果**: - C:P=(0,0,0)、θ=90°,自转中心 `(2.00,0.00,0.00)`,绕 P 中心 `(0.00,0.00,-2.00)`;动画满 360° 回到初始位置,P 标记固定不动,暂停期间角度不增长,继续后无突跳。 - D:yaw=0°、pitch=0° 时肩部 `(0,-0.75,0)`、末端 `(0,1.45,0)`,臂与探头保持连接;拖动 yaw 时肩部、探头整体跟随,基座自身装配关系不变;拖动 pitch 时基座不动,仅臂段与探头摆动。 **修正结论** - 绕指定世界点 P 旋转必须先把 P 平移到原点、旋转后再移回世界 P,即 `T(P)·R·T(-P)`,P 与 q 同属世界坐标系。 - 父关节位姿矩阵只记录位置与旋转;非均匀缩放属于部件局部绘制矩阵,必须放在该部件自身链的最右端,不能跨层传递。 --- ## 协作点 3:设计协商(Task E) **我的目标与预测**:已实现 `T·R·S`、绕指定点旋转和两级父子变换,需要在 40 分钟内用简单立方体整合出一个至少 3 部件、含父子关系、两种复合机制、两个独立参数的联动场景。 **提示词** > 我已实现 T·R·S、绕指定点旋转和两级父子变换。请提出两个可在 40 分钟内用简单立方体完成的三维联动场景,并比较部件关系、矩阵链、交互参数、验证难度。请复用现有 WebGL2 框架,不引入相机拾取、光照或外部库,也不要直接生成整套代码。 **AI 建议摘要** *方案 A:医学设备定位装置 + 旋转样本台(教师参考方向)* - 部件:基座、机械臂、探头;样本台、样本、环绕标记。 - 父子关系:基座 → 肩部 → 探头;样本与标记相互独立,标记绕样本中心公转。 - 矩阵链: - 基座位姿 `basePose = T(-2,-1.3,0)·Ry(yaw)` - 肩部位姿 `shoulderPose = basePose·T(0,.55,0)·Rz(pitch)` - 末端位姿 `tipPose = shoulderPose·T(0,2.2,0)` - 样本自转 `specimen = T(pivot)·Ry(spinAngle)·S` - 标记公转 `orbitMarker = T(pivot)·Ry(orbitAngle)·T(radius,.28,0)·S` - 参数:基座 yaw、肩部 pitch;样本动画速度 speed;暂停/继续、重置、截图。 - 验证难度:中等,直接读取关节世界坐标即可核对父子关系。 *方案 B:行星—卫星系统* - 部件:恒星、行星、卫星;行星绕恒星公转,卫星父子绑定行星。 - 参数:公转角速度、自转速度;暂停与重置。 - 验证难度:较高,需要区分公转角度与自转角度两套角度累计,且易与“相同角速度伪装跟随”混淆。 **我的判断**:选用方案 A。它可直接复用 Task D 的两级父子结构,改造工作量可控;左侧机械臂提供明确父子继承,右侧样本自转与标记公转提供两种独立复合变换机制,参数与坐标核验都直观。 **测试或修改** - 实现全部矩阵链后逐项验证:调基座 yaw,探头整体跟随;调 pitch,基座静止、探头随臂摆动;speed 改变样本自转与标记公转快慢;暂停 2 秒画面保持,继续后无角度跳变;保存 PNG 非空白。 - 与教师参考示例相比,本场景的功能性调整:机械臂整体偏置到样本台左侧以留出独立旋转区域;标记半径偏移与样本自转采用不同角速度(自转 65°/s、标记公转 42°/s 倍率),形成可区分的两条轨迹。 **结果(两个参数状态对照)** | 状态 | yaw | pitch | 预期末端行为 | 实际末端世界坐标 / 现象 | |---|---:|---:|---|---| | 初始 | 25° | -20° | 探头随基座偏置、肩部下沉,父子链一致 | 末端坐标随 `basePose·shoulderPose·tipPose` 计算,探头与臂端保持连接 | | 仅调基座 | 90° | -20° | 肩部与探头整体绕基座偏航,基座装配关系不变 | 肩部、探头位置同步绕 Y 轴转动,基座静止 | | 仅调肩部 | 25° | +20° | 基座不动,臂段与探头绕肩部局部 Z 轴抬起 | 基座世界位姿不变,探头随臂端摆动 | | 暂停 2 秒 | — | — | elapsed/angle 不增长,画面冻结 | 继续后无突跳;speed 调大后动画明显加快 | **修正结论**:父子继承通过父位姿放在 `chain` 左侧实现;绕点公转标记的矩阵顺序为“中心平移 → 旋转 → 半径偏移平移 → 缩放”,顺序不可颠倒;每帧由当前参数重新构造矩阵,不对旧矩阵无限累乘,避免动画漂移。 --- ## 附:Task A–E 矩阵链速查 | 任务 | 矩阵链 | |---|---| | A | `model = T(tx,ty,tz) · Ry(θ) · S(s)`,世界中心 = 平移量 `(tx,ty,tz)` | | B | `M1 = T·Ry·S`;`M2 = Ry·T·S`(其余几何、Shader 共用,仅上传不同 Model) | | C 自转 | `Mself = T(q) · Ry(θ) · S` | | C 绕 P | `Morbit = T(P) · Ry(θ) · T(-P) · T(q) · S` | | D 基座 | `basePose = T(0,-1.3,0) · Ry(yaw)` | | D 肩部 | `shoulderPose = basePose · T(0,.55,0) · Rz(pitch)` | | D 末端 | `tipPose = shoulderPose · T(0,2.2,0)`;绘制缩放仅在部件局部链末端 | | E 左侧 | 同 D 两级父子;右侧样本 `T(pivot)·Ry(spin)·S`,标记 `T(pivot)·Ry(orbit)·T(radius,.28,0)·S` |