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 可用格式