AI 协作日志

学生 Web 实验作品平台

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

# 实验二 AI协作记录

## AI协作1 · Koch算法

### 我的目标与初步判断
目标:实现 Koch 雪花递归算法
初步判断:每条边三等分得P、Q,Q−P 绕原点旋转60°加P得R
方向由初始三角形绕行方向决定。先猜逆时针多边形外侧在行进方向右边,用右转60

### 关键提示词
初始三角形顶点逆时针排列 [[-0.82,-0.43],[0.82,-0.43],[0,0.99]],Koch细分要左还是右转60才能让突起朝外

### AI关键建议摘要
AI 指出:逆时针多边形每条边的外侧在行进方向右侧,所以应把 Q−P 右转60°,即r = [p.x + dx·cos60 + dy·sin60, p.y − dx·sin60 + dy·cos60]。
建议先用一条水平线段单独测试替换结果再扩展到三条边。

### 我的测试方法与结果
先用 A=(-0.5,0)、B=(0.5,0) 单段测试,打印 P、Q、R 坐标:
P=(-0.1667,0),Q=(0.1667,0),R=(0, 0.2887),突起在 y 正方向。
再把 baseTriangle 三条边按 0→1→2→0 递归,Level 1 得到 12 段,
Level 2 得到 48 段,与 3×4^n 一致。图形轮廓封闭,突起朝外。

### 采纳情况及修正结论
采纳右转 60° 方案。初版曾误用左转,导致 Level 1 突起朝内、轮廓自交,
把 r 的两处符号反过来后恢复正常。最终算法:
P=A+(B−A)/3,Q=A+2(B−A)/3,R=P+rotate(Q−P, −60°),
递归 A→P→R→Q→B 四段。

---

## AI协作2 · 绘图板调试

### 具体错误现象
人为注入错误:把 pointerToNDC 里的 Y 翻转去掉,yNDC = 2*yCanvas/canvas.height − 1,
结果点击 Canvas 上半部分时点画在下半部分,图形上下颠倒。

### 我的初步排查
怀疑是 clientY 与 Canvas 像素坐标、NDC 之间的换算问题。检查 getBoundingClientRect 与 canvas.width/height 是否一致,
确认 rect 取值正确,问题在 Y 方向。

### 关键提示词(原文)
点转 NDC,clientY 向下增大,NDC 的 y 向上增大,换算写成 yNDC = 2*yCanvas/canvas.height − 1,
点出来上下颠倒,怎么改

### AI建议与逐项测试
AI 指出 Canvas 像素 y 向下增长,NDC 的 y 向上增长,
所以应改为 yNDC = 1 − 2*yCanvas/canvas.height。
逐项验证:
1) 点击 Canvas 正中心,应得 (0,0);
2) 点击左上角,应得接近 (−1, 1);
3) 点击右下角,应得接近 (1, −1)。
逐项测试后,四点位置全部正确。

### 最终原因及修复证据
原因是遗漏了 Y 轴翻转。修复后:
点击左上角得到约 (−1, 1),右下角约 (1, −1),
画点、线、矩形位置全部正确。
并用 CSS 缩放页面后再次点击 Canvas 中心,仍落在 (0,0) 附近,
说明乘 canvas.width/rect.width 的换算也正确。

---

## AI协作3 · 主题整合

### 主题及预期效果
主题词:绽放。
预期:中心 Koch 雪花 + 外层花瓣形边框 + 暖橙辐条 + 菱形节点,
整体可旋转、可点击移动中心、可调层数与尺度。

### 两个方案的AI提示词(原文)
"用 WebGL 基本图元表现'绽放'主题,给出两个方案:
方案一偏向对称几何,方案二偏向动态生长;
分别说明图元类型、数量级、交互难度与可解释性。"

### 方案比较、取舍理由
方案一:双层同心圆环 + 12 条直线辐条 + 点状节点。
优点:实现简单;缺点:视觉平、辐条用 LINES 有缝、无主题感。
方案二:花瓣形外框(半径随角度周期起伏)+ 逐条 LINE_STRIP 辐条 + 菱形节点。
优点:轮廓呼应主题、辐条无缝、层次分明;
缺点:每条辐条单独上传,绘制调用变多,但 Level 2 规模下可接受。
选择方案二。理由:更贴合“绽放”的视觉含义,
且解决了 LINES 分段画导致的断线问题。

### 实际实现、测试与结果
实现:makePetalRing 生成花瓣外框,makeDiamond 生成菱形节点,
辐条在 render 内逐条 LINE_STRIP 绘制,Koch 雪花最后画压在最上层。
测试:
1) 初始状态显示光晕、花瓣框、辐条、节点、雪花;
2) 点开始按钮整体旋转;
3) 点 Canvas 不同位置图案整体平移;
4) 拖层数滑块 Koch 复杂度变化;
5) 拖尺度滑块整体缩放。
截图对比交互前后,几何与位置均符合预期。

---



**思考题A:** 改变剖分层次与只改变Uniform颜色,为什么可能采用不同的数据更新方式?
改 Level 是改几何,必须重建数据并上传 GPU;改颜色是改 Shader 参数,只更新 uniform 再重绘

**思考题B:** 为什么线段数随Level增长为`3×4^n`?Level增加时顶点数据量、计算量大致如何变化?
一条线段变四条,三边独立递归,所以是 3×4^n;数据量和计算量都正比于线段数,同样按 4 倍逐层增长

**思考题C:** 为什么连续旋转可以更新`uTheta`而不更新所有顶点?如果意外重复启动多个rAF循环,可能出现什么现象?
旋转是全体顶点共享的同一变换,所以用 uniform 传 θ 就够,不必改 Buffer;rAF 靠自我调度延续,多启动一次就多一条并行循环,会导致速度翻倍、暂停错乱、性能下降,所以只应在初始化时启动一次。

**思考题D:** 为什么单次点击不能直接生成矩形?为什么即使GPU已有顶点,JavaScript端仍建议保留`objects`等应用层对象数据?
 矩形需要两个对角点才能确定,
 GPU Buffer 只是无结构的浮点数组,丢失了对象边界、类型、颜色、顺序等逻辑信息。JS 端的 objects 保存的是数据的“真相”,渲染时从中生成 Buffer。编辑、撤销、改色这些操作都必须在应用层做