AI 协作日志

学生 Web 实验作品平台

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

# 实验二 AI协作记录

> 使用工具:豆包(Doubao)办公模式
> 说明:以下记录均为实际协作过程整理,保留了关键提示词原文和个人验证结论。

## AI协作1 · Koch算法
### 我的目标与初步判断
**目标:** 实现 Koch 雪花的线段递归替换,特别是确认"向外凸起"的旋转方向。
**初步判断:** 我知道需要把 PQ 向量旋转 60° 得到 R 点,但不确定应该顺时针还是逆时针旋转。初始三角形是逆时针排列的,我猜测应该向三角形的外侧(即边的右侧)凸起,也就是右转 60°(顺时针旋转)。

### 关键提示词(原文)
> "WebGL 中实现 Koch 雪花,初始是一个逆时针排列的等边三角形。对于每条从 A 到 B 的有向边,三等分得到 P 和 Q,然后以 PQ 为底向外做等边三角形。请问向量 PQ 应该旋转 +60° 还是 -60° 才能保证凸起朝向三角形外部?怎么用数学公式表达?"

### AI关键建议摘要
1. 三角形逆时针排列时,沿边行走方向,三角形内部在左侧,外部在右侧。
2. 要向外侧凸起,需要把 PQ 向量**顺时针旋转 60°**(即角度 -60°)加到 P 点上得到 R。
3. 旋转矩阵公式:
   - x' = dx * cos(-60°) - dy * sin(-60°) = dx * 0.5 + dy * (√3/2)
   - y' = dx * sin(-60°) + dy * cos(-60°) = -dx * (√3/2) + dy * 0.5
4. 建议先单独测试一条水平边:从左到右的水平线,向外凸起应该在下方。

### 我的测试方法与结果
**测试1:** 取底边 A=(-0.82, -0.43), B=(0.82, -0.43),按顺时针旋转 60° 计算 R 点。
- 计算结果:P≈(-0.273, -0.43), Q≈(0.273, -0.43), R≈(0, -0.903)
- R 在底边下方,也就是三角形外部 ✓

**测试2:** 故意改用逆时针旋转 60°,观察 R 点位置。
- 结果:R≈(0, 0.043),在底边上方,也就是三角形内部,图形会向内凹。
- 验证了 AI 建议正确:逆时针旋转会导致雪花向内凹陷。

**测试3:** 统计 Level 0/1/2 的线段数。
- Level 0:3 条边 ✓
- Level 1:3×4=12 条边 ✓
- Level 2:3×16=48 条边 ✓
- 公式 3×4^n 成立。

### 采纳情况及修正结论
完全采纳 AI 的旋转方向建议。
**修正后的结论:** 对于逆时针排列的初始三角形,每条边的 PQ 向量应顺时针旋转 60°(即角度取负),再与 P 点相加得到外向凸起顶点 R。递归终止条件为 level=0,此时输出线段起点。由于使用 LINE_LOOP 绘制,顶点数等于线段数(闭合回路)。

---

## AI协作2 · 绘图板调试
### 具体错误现象
**人为注入的错误:** 我故意把 yNDC 的翻转去掉了(即 `yNDC = 2*yCanvas/canvas.height - 1`),测试坐标偏移问题。
**现象:** 在 Canvas 上方点击,图形出现在下方;在下方点击,图形出现在上方。Y 轴完全颠倒。

### 我的初步排查
1. 先检查了 `getBoundingClientRect()` 是否正确获取——看起来没问题。
2. 检查了 clientX/clientY 的使用——也是按课堂公式来的。
3. 怀疑是 Canvas 像素尺寸和 CSS 尺寸不一致导致的缩放问题,但窗口没缩放,应该不是。
4. 最后想到可能是 Y 轴方向:Canvas 坐标系原点在左上角,Y 向下为正;而 WebGL NDC 原点在中心,Y 向上为正。

### 关键提示词(原文)
> "WebGL 绘图板鼠标点击位置 Y 轴方向反了,我点击画布上方但图形出现在下方。坐标转换代码我写的是 xNDC = 2*xCanvas/width - 1; yNDC = 2*yCanvas/height - 1; 请问哪里错了?"

### AI建议与逐项测试
**AI建议1:Y轴翻转符号写反了。**
- 正确公式应该是 `yNDC = 1 - 2*yCanvas/canvas.height`,因为 Canvas 的 y=0 在顶部,NDC 的 y=+1 也在顶部,需要翻转。
- 测试:改成 `1 - 2*yCanvas/height` 后,上方点击的点确实出现在上方了 ✓

**AI建议2:确认是否考虑了 CSS 缩放。**
- 正确的做法是 `xCanvas = (event.clientX - rect.left) * canvas.width / rect.width`,而不是直接用 clientX。
- 测试:我当前代码已经做了这一步,窗口缩放后点击仍然准确 ✓

**AI建议3:矩形构建时要注意任意对角点顺序。**
- 应该取 min/max 得到 loX/hiX/loY/hiY,再按顺时针或逆时针顺序输出四个角。
- 测试:从右下角往左上角拖点矩形,和从左上角往右下角拖,图形都正确 ✓

### 最终原因及修复证据
**原因:** Y 轴翻转符号写反了。Canvas 坐标系原点在左上角(Y 向下为正),而 WebGL NDC 原点在中心(Y 向上为正),必须做翻转:`yNDC = 1 - 2 * yCanvas / canvas.height`。

**修复证据:**
1. 在画布四角附近分别画点,左上/右上/左下/右下位置都正确对应。
2. 先画一个点、一条线、一个矩形,切换工具后再画,旧图形不消失。
3. 第一次点击线段后切换为矩形,再点击一次,状态正确重置,不会残留旧的第一点。

---

## AI协作3 · 主题整合
### 主题及预期效果
**主题:** 绽放
**预期效果:** 以 Koch 雪花为核心花朵,外围增加花瓣环和花蕊连线,整体缓慢旋转,点击画布可以移动花朵中心。视觉上像一朵正在旋转绽放的花。

### 两个方案的AI提示词(原文)
> "我要用 WebGL 基本图元(点、线、线环)做一个主题叫'绽放'的交互作品,需要复用 Koch 雪花算法和旋转动画。请给我两种不同的几何构成方案,比较一下图元数量、交互难度和可解释性。"

### 方案比较、取舍理由
| 方案 | 几何构成 | 图元数量 | 交互难度 | 可解释性 | 取舍 |
|---|---|---|---|---|---|
| **方案A:花朵结构** | 外层圆环 + 中间Koch花瓣 + 中心辐射线 + 端点节点 | 约 150 个顶点 | 低:旋转 + 点击移动中心 | 高:每一层对应花的一部分,直观 | **采用** |
| **方案B:烟花轨迹** | 中心爆炸点 + 多条抛物线轨迹线 + 尾迹点 | 约 200+ 顶点 | 中:需要动画时间积分轨迹 | 中:轨迹参数化较抽象 | 拒绝 |

**取舍理由:**
1. 方案A的几何层次清晰,和"绽放"主题直接对应——外环是花瓣边缘,Koch是花瓣纹理,辐射线是花蕊连接,节点是点缀。
2. 方案B需要额外的物理时间积分和尾迹管理,代码复杂度高,而且和复用的Koch算法关系不大。
3. 方案A的两种交互(旋转动画 + 点击移动中心)都是前面任务的能力复用,符合实验要求"不要求重新编写一套底层绘制系统"。

### 实际实现、测试与结果
**实际实现:**
- 核心:Koch 雪花(复用 Task B 算法),作为花朵主体
- 新增几何1:双层外环(外层 36 点圆环 + 内层 24 点圆环,内层反向缓慢旋转)—— 对应花瓣边缘
- 新增几何2:12 条花蕊辐射线 + 12 个端点节点 —— 对应花蕊与花萼连接
- 交互1:开始/暂停旋转(复用 Task C 的 rAF 动画机制)
- 交互2:点击画布移动图案中心(复用 Task D 的鼠标坐标转换)
- 交互3:滑块调整展开尺度(几何缩放)

**测试结果:**
1. 初始状态:双层外环 + Koch 核心 + 辐射线 + 节点,整体居中。
2. 点击"开始/暂停旋转":Koch 核心和内层环开始旋转,速度均匀。
3. 点击画布任意位置:整个花朵平移到该位置。
4. 调整"展开尺度"滑块:花朵整体放大缩小,比例正确。
5. 调整"装饰图案层数"滑块:Koch 雪花的递归层数变化,顶点数相应变化。

---

## 其他AI使用
- **Task A:** 咨询了"改变 Level 和改变颜色为什么需要不同的数据更新方式"。AI 解释:改变 Level 需要重新生成顶点数据并重新上传 Buffer(几何数据变化);改变颜色只需要更新 uniform(绘制状态变化),不需要重新上传顶点。验证:在代码中确实 Level 变化调用了 upload(),颜色变化只调用了 setupDraw() 更新 uniform。
- **排错:** 页面空白时,咨询了 WebGL2 Shader 版本号问题。AI 提醒必须在 Shader 第一行写 `#version 300 es`,且不能有任何前导空格或注释。检查后确认 HTML 中 Shader 标签内容正确。