AI 协作日志

学生 Web 实验作品平台

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

# 实验二 AI协作记录(请据实际情况填写)

## AI协作1 · Koch算法
### 我的目标与初步判断
目标:实现 Koch 雪花分形算法,根据输入的剖分层次 n 生成对应的雪花图案。
初步判断:已知每条线段在每次迭代中会被分成三段,中间一段向外凸起形成等边三角形。需要递归地对每条边进行细分。基础三角形有3条边,每次迭代后边数变为原来的4倍,因此 level n 时总线段数为 3×4ⁿ。我计划从线段的两个端点 A、B 出发,计算三等分点 P 和 Q,再计算向外凸起的顶点 R,然后递归处理 AP、PR、RQ、QB 四段。

### 关键提示词(原文)
"帮我解释一下 Koch 雪花曲线的递归生成原理,以及如何计算向外凸起的等边三角形顶点坐标。已知线段两端点 A 和 B,三等分点 P 和 Q,怎么求外侧的顶点 R?三角形顶点是逆时针排列的,边沿逆时针方向行走时外凸应该左转还是右转?"

"WebGL 中用 LINE_LOOP 绘制 Koch 雪花,顶点数组应该怎么组织?递归函数应该 push 哪些点?为什么最后一个点不用 push,LINE_LOOP 会自动闭合吗?"

### AI关键建议摘要
1. 顶点 R 的计算方法:将向量 PQ 绕 P 点旋转 -60°(顺时针/右转60°)即可得到向外的等边三角形顶点。旋转公式为:
   - dx = Q.x - P.x, dy = Q.y - P.y
   - R.x = P.x + dx·cos(-60°) - dy·sin(-60°)
   - R.y = P.y + dx·sin(-60°) + dy·cos(-60°)
   - 其中 cos(-60°)=0.5,sin(-60°)=-√3/2

2. 为什么是右转(顺时针):因为三角形顶点按逆时针排列,沿边行走时图形内部在左侧,向外凸起就需要向右侧(顺时针方向)旋转60°。

3. LINE_LOOP 顶点组织:递归函数每次只 push 起点 A,不 push 终点 B。因为下一段的起点就是上一段的终点,这样可以避免重复顶点。最后 LINE_LOOP 会自动将最后一个顶点连接回第一个顶点,形成闭合曲线。

4. 递归顺序:按 A→P→R→Q→B 的顺序递归,即递归处理 AP、PR、RQ、QB 四段。

### 我的测试方法与结果
测试方法:
- Level 0:应为一个完整三角形,3条边,3个顶点
- Level 1:每条边变成4条边,共 3×4=12 条边
- Level 2:共 3×16=48 条边
- 手动计算 Level 0 和 Level 1 的顶点坐标,与程序输出对比
- 观察图形是否对称,是否有缺口或重叠

测试结果:
- Level 0 输出3个顶点,形成正确的等边三角形 ✓
- Level 1 输出12个顶点,每个边中间有向外的凸起 ✓
- Level 2 输出48个顶点,雪花形状正确 ✓
- 各层次切换正常,图形无畸变 ✓
- 线段数量公式 3×4ⁿ 与实际顶点数一致 ✓

### 采纳情况及修正结论
全部采纳AI的建议。在实现过程中曾犯过两个错误:
1. 最初把旋转方向搞反了(用了+60°),导致凸起向三角形内部凹陷,雪花变成了"反雪花"。根据AI提示确认是右转-60°后修正。
2. 递归函数中同时 push 了起点和终点,导致顶点重复,LINE_LOOP 绘制时有重影。按照AI建议只 push 起点后解决。

最终结论:Koch 算法核心是线段三等分 + 旋转向量构造等边三角形 + 递归细分,理解旋转方向是关键。

---

## AI协作2 · 绘图板调试
### 具体错误现象(如一次成功,可先人为注入并恢复一个小错误)
在实现 Task D 交互绘图板时,遇到了两个问题:
1. 坐标偏移问题:点击画布绘制点时,点的位置和鼠标实际点击位置有偏差,越靠近边缘偏差越大,而且Y轴方向是反的(点击上方,点出现在下方)。
2. 矩形绘制不全问题:绘制矩形时,有时只显示三条边,有一条边缺失。

### 我的初步排查
1. 坐标偏移问题:
   - 怀疑是 clientX/clientY 没有减去 canvas 元素的偏移位置
   - 也可能是 canvas 的 CSS 尺寸和实际像素尺寸不一致(width/height 属性 vs CSS 宽高)
   - Y轴翻转问题应该是 WebGL 坐标原点在左下角,而屏幕坐标原点在左上角

2. 矩形问题:
   - 检查了四个顶点的顺序,怀疑是顶点顺序不对导致 LINE_LOOP 连接错误
   - 检查了对角点的 min/max 计算逻辑

### 关键提示词(原文)
"WebGL 鼠标点击坐标转换问题:我用 event.clientX 和 clientY 获取鼠标位置,画出来的点位置不对,有偏移而且Y轴反了。canvas 元素的 getBoundingClientRect() 返回的 rect 和 canvas.width / canvas.height 是什么关系?怎么把屏幕像素坐标正确转换成 WebGL 的 NDC 坐标(-1到1)?"

"用 LINE_LOOP 画矩形,四个顶点按 [左下, 右下, 右上, 左上] 的顺序排列对吗?为什么有时候会少一条边?对角点生成矩形顶点时,如果用户从右上往左下拖动,min/max 处理后顶点顺序还是正确的吗?"

### AI建议与逐项测试
问题1 - 坐标转换建议:
1. 先计算 canvas 内的像素坐标:
   - xCanvas = (event.clientX - rect.left) * canvas.width / rect.width
   - yCanvas = (event.clientY - rect.top) * canvas.height / rect.height
   - 乘以 canvas.width/height 是为了处理 CSS 缩放
2. 再转换为 NDC 坐标:
   - xNDC = 2 * xCanvas / canvas.width - 1  (范围从 [-1, 1])
   - yNDC = 1 - 2 * yCanvas / canvas.height  (Y轴翻转,从上到下变为从下到上)

测试结果:
- 加入 rect.left/top 偏移后,水平方向对齐了 ✓
- 乘以 canvas.width/rect.width 比例后,缩放偏差消除 ✓
- Y轴用 1-2y 公式后,上下方向正确 ✓

问题2 - 矩形绘制建议:
1. LINE_LOOP 会自动将最后一个顶点连接回第一个顶点,所以4个顶点应该能画出4条边
2. 顶点顺序按顺时针或逆时针都可以,但要保证是连续的环绕顺序
3. 从对角点生成矩形的正确顺序:[左下, 右下, 右上, 左上] 或逆时针顺序均可
4. 检查是否是 upload 函数或 drawArrays 的 count 参数有问题

逐项测试后发现:矩形顶点顺序是正确的,问题出在之前调试时不小心把模式写成了 gl.LINES 而不是 gl.LINE_LOOP,导致只有两个线段(4个点用LINES模式只能画2条线)。

### 最终原因及修复证据
问题1原因: 缺少 canvas 元素偏移量和 CSS 缩放比例的校正,以及 Y 轴未翻转。
修复代码(pointerToNDC 函数):
```
const rect = canvas.getBoundingClientRect();
const xCanvas = (event.clientX - rect.left) * canvas.width / rect.width;
const yCanvas = (event.clientY - rect.top) * canvas.height / rect.height;
const xNDC = 2 * xCanvas / canvas.width - 1;
const yNDC = 1 - 2 * yCanvas / canvas.height;
```
验证:在画布四个角点击,点都正确出现在角落位置。

问题2原因: 绘制模式误用 gl.LINES 而非 gl.LINE_LOOP。
修复:将矩形绘制模式改为 gl.LINE_LOOP。
验证:4个顶点正确画出4条边,形成完整矩形。

---

## AI协作3 · 主题整合
### 主题及预期效果
主题:"星轨" —— 以夜空中星体运行的轨道为灵感,将 Koch 雪花作为中心星体,周围环绕多层轨道和闪烁的星辰,营造出宇宙星空的动态效果。

预期效果:
- 中心:旋转的 Koch 雪花(代表中心星体/星云)
- 内环:细密的圆点轨道(代表小行星带)
- 外环:虚线形式的大轨道(代表行星轨道)
- 背景:随机分布的闪烁星点
- 交互:点击改变中心位置、滑块调节轨道层数和旋转速度、悬停显示星体信息

### 两个方案的AI提示词(原文)
方案A提示词:
"帮我设计一个以'星轨'为主题的 WebGL 创意作品,基于 Koch 雪花算法。要求:
1. 中心是旋转的 Koch 雪花,作为星云核心
2. 外面有2-3层不同样式的轨道环
3. 轨道上有运动的光点(行星)
4. 背景有随机分布的星星
5. 点击画布可以移动星云中心
6. 至少两个新增几何组成部分和一条新交互规则
请给出具体的几何构造思路和交互设计。"

方案B提示词:
"另一个方案:以'绽放的烟花'为主题,基于 Koch 雪花。要求:
1. 中心 Koch 雪花作为烟花内核
2. 向外放射的线条作为烟花绽放的轨迹
3. 轨迹末端有亮点,模拟火星
4. 有多层不同颜色的绽放效果
5. 点击画布触发一次绽放动画
6. 比较一下这个方案和'星轨'方案哪个更容易实现、视觉效果更好?"

### 方案比较、取舍理由
| 对比维度 | 方案A:星轨 | 方案B:烟花绽放 |
|---------|-----------|---------------|
| 几何复杂度 | 中等:圆环 + 轨道点 + 背景星 | 较高:放射线 + 粒子动画 + 多层绽放 |
| 动画实现 | 简单:匀速旋转 + 轨道运动 | 复杂:需要粒子生命周期、爆炸动画时序 |
| 交互设计 | 直观:点击移动中心、滑块调层数 | 较复杂:点击触发动画、需要状态管理 |
| 视觉效果 | 沉静、持续动态、适合长时间观看 | 惊艳但短暂、需要反复触发 |
| 实现难度 | 较低,与现有代码结构契合度高 | 较高,需要额外的粒子系统 |

取舍理由:选择方案A(星轨),原因:
1. 与现有 Task E 的"绽放"框架结构更接近,改造成本低
2. 几何元素(圆环、点阵、放射线)都可以用基础图元实现,不需要粒子系统
3. 持续旋转的动态效果更适合作为展示作品
4. 有充足的时间对细节进行打磨

### 实际实现、测试与结果
实际实现的几何组成:
1. 中心星云:Koch 雪花,蓝色调,持续旋转
2. 内轨道光环:由 60 个点组成的圆点轨道,金黄色,反向缓慢旋转(模拟小行星带)
3. 外轨道虚线环:由 24 段短线段组成的虚线大圆环,浅蓝灰色,与内核同向旋转但更慢(模拟行星轨道)
4. 背景星点:80 个随机分布的静态星点,白色,大小不一(模拟星空背景)
5. 轨道节点:12 个较大的亮点均匀分布在外轨道上(模拟行星位置)

新增交互规则:
1. 点击画布移动星云中心
2. 新增"轨道层数"滑块:调节内轨道的点数量
3. 新增"速度"滑块:调节整体旋转速度
4. 新增"星空"开关按钮:切换背景星点的显示/隐藏

测试结果:
- 各几何元素渲染正确,层次分明 
- 旋转动画流畅,不同层速度差异营造出纵深感 
- 滑块调节实时生效,无卡顿 
- 点击移动中心功能正常 
- 星空开关切换正常 
- 整体视觉效果符合"星轨"主题预期 

---

## 其他AI使用(若有)
1. Task A Sierpinski 三角形参数化:
   - 提示词:"Sierpinski 三角形的递归剖分原理是什么?每次递归把一个大三角形分成几个小三角形,分别是哪几个顶点组成的?"
   - 用途:确认递归细分的正确方式,验证中点连接法的正确性

2. Task C 旋转动画:
   - 提示词:"requestAnimationFrame 的回调参数 time 单位是毫秒吗?怎么用它来计算每帧的时间差 dt,从而实现与帧率无关的匀速旋转动画?"
   - 用途:正确实现基于时间差的动画更新,确保不同设备上旋转速度一致

3. WebGL uniform 变量使用:
   - 提示词:"WebGL 中 uniform 变量在每次 drawArrays 之前都需要重新设置吗?还是设置一次后会一直保留那个值?"
   - 用途:理解 uniform 变量的状态保持特性,优化绘制代码结构

4. 颜色转换函数:
   - 提示词:"JavaScript 中怎么把十六进制颜色值转换成 WebGL 需要的 0-1 范围的 RGBA 数组?"
   - 用途:实现 rgba() 工具函数,将 HTML 颜色选择器的值转换为 WebGL 可用格式