AI 协作日志
学生 Web 实验作品平台
学号:202312211503020 · 来源:ai-log.md
# 实验二 AI协作记录(请据实际情况填写) ## AI协作1 · Koch算法 ### 我的目标与初步判断 我需要让 Koch 雪花的突起朝外,而不是向内凹。 我的初步判断:初始三角形是逆时针排列,沿边逆时针行走时,向外应该是右转 60°。 但我不确定旋转公式的符号,先预测:如果右转错了会向内凹。 ### 关键提示词(原文) 给定一段从 A 到 B 的线段,P、Q 是三等分点,我要以 PQ 为底构造向外的等边三角形顶点 R。我的初始三角形是逆时针排列,沿边方向行走时向外的凸起应该用 Q-P 向量旋转 +60° 还是 -60°?请给出两种旋转公式,并说明如何用图形验证方向。 ### AI关键建议摘要 - 逆时针旋转 60°:x' = x·cos60 − y·sin60,y' = x·sin60 + y·cos60 - 顺时针旋转 60°:x' = x·cos60 + y·sin60,y' = −x·sin60 + y·cos60 - 建议先只画一条水平线段测试,观察突起在线上方还是下方,再决定符号。 ### 我的测试方法与结果 1. 先只对一条水平线 A=(−0.5,0)→B=(0.5,0) 做 Level 1 替换,打印 A、P、R、Q、B 的坐标。 结果:R 的 y 坐标为正 / 负,即突起朝上 / 下。 2. 把该符号用到完整三角形,观察 Level 1 图案。 结果:朝外,正确 向内凹,错误。 3. 数线段数:Level 1 = 12,Level 3 = 192,与 3×4ⁿ 一致。 ### 采纳情况及修正结论 我采纳了 AI 给出的"顺时针 60°"公式,因为实测 R 在行进方向外侧,Level 1 的 12 段全部朝外。最终 `subdivideSegment` 中 R 的计算为: `r = [p[0]+dx*c+dy*s, p[1]-dx*s+dy*c]`。 ## AI协作2 · 绘图板调试 ### 具体错误现象(如一次成功,可先人为注入并恢复一个小错误) 点击 Canvas 左上角,画出的点却出现在左下角 ### 我的初步排查 1. `getBoundingClientRect()` 没减 `rect.left/top`; 2. Y 轴没有翻转(NDC 与屏幕 Y 方向相反); 3. Canvas 的 CSS 尺寸与 `canvas.width` 不一致,没做比例换算。 ### 关键提示词(原文) 我把鼠标点击位置转成 WebGL NDC 后,图形位置总是上下颠倒。我的转换是 xNDC = 2*clientX/canvas.width - 1,yNDC = 1 - 2*clientY/canvas.height。请列出可能导致 Y 轴偏移的原因,并给出逐步验证方法。不要直接重写我的函数。 ### AI建议与逐项测试 AI 给出的可能原因: 1. 未使用 `getBoundingClientRect()`,clientX/Y 是相对视口而非 Canvas; 2. 未按 `canvas.width/rect.width` 做比例换算; 3. Y 翻转公式对但 `rect.top` 未减。 逐项测试: - 测试 1:四角点击 → 无关 - 测试 2:缩放窗口后点中心 → 无关 - 测试 3:故意去掉 Y 翻转 → 点上下颠倒,恢复后正确 ### 最终原因及修复证据 根本原因是未减 rect.left/top。修复后四角点击位置准确,窗口缩放后点击仍准确。修复代码为: `xCanvas = (clientX - rect.left) * canvas.width / rect.width;` `yNDC = 1 - 2*yCanvas/canvas.height; ## AI协作3 · 主题整合 ### 主题及预期效果 主题:秩序 预期:用外层圆环表示边界秩序,Koch 雪花表示分形秩序,放射线与节点连接内外 ### 两个方案的AI提示词(原文) 我要用基本 WebGL 图元做一个主题为'秩序'的交互图案,复用 Koch 雪花和旋转动画。请给出两种用基本图元表达该主题的方案,分别说明图元数量、交互难度和可解释性。 ### 方案比较、取舍理由 - 方案 A:圆环 + 放射线 + Koch - 方案 B:多层同心多边形 + 螺旋线 + 节点 采用方案 A。理由:图元数量少、易解释、与 Koch 复用自然 ### 实际实现、测试与结果 - 新增几何1:外层圆环 - 新增几何2:12 条放射线 - 新增交互:点击 Canvas 移动作品中心 - 验证:点击后整体平移 ;开始/暂停旋转 ;滑块调层次/尺度 ## 其他AI使用(若有) 工具、提示词及关键修改记录。 **思考题A:** 改变剖分层次与只改变Uniform颜色,为什么可能采用不同的数据更新方式? Level 变化改变的是顶点坐标和数量,属于几何数据本身的变化,必须重新生成 Float32Array 并用 bufferData 重传 GPU;而颜色变化时顶点数据完全不变,只是片元着色器的一个参数,通过 uniform4fv 更新 uColor 即可生效,无需触碰 Buffer。前者是数据更新、开销大,后者是参数更新、几乎零成本,所以采用不同的更新方式。 **思考题B:** 为什么线段数随Level增长为`3×4^n`?Level增加时顶点数据量、计算量大致如何变化? 因为每次细分都把 1 段线段替换成 4 段(A→P→R→Q→B),而初始等边三角形有 3 条边,所以经过 n 次替换后总段数就是 3×4ⁿ。Level 增加时,顶点数据量和计算量都随线段数按 4ⁿ 指数增长:每升 1 级,段数、顶点数、递归调用次数都大约变为原来的 4 倍,因此 Level 不能无限调大(本题限制在 0~4 就是这个原因)。 **思考题C:** 为什么连续旋转可以更新`uTheta`而不更新所有顶点?如果意外重复启动多个rAF循环,可能出现什么现象? 旋转是统一坐标变换,所有顶点共用一个旋转角,在 Shader 里用 uTheta 对每个顶点做旋转即可,顶点数据不用改,只需每帧更新一个 uniform,开销极小。若重复启动多个 rAF 循环,animate 每帧被多次调用,theta 累加变快导致旋转异常加速,还会重复清屏重绘引起闪烁、卡顿,暂停/反向状态也会混乱,所以必须保证同一时刻只有一个 rAF 循环。 **思考题D:** 为什么单次点击不能直接生成矩形?为什么即使GPU已有顶点,JavaScript端仍建议保留`objects`等应用层对象数据? 单次点击只得到一个点,而矩形需要两个对角点才能确定位置和大小,同一个点可对应无数个矩形,所以必须等第二次点击提供另一个角点才能算出四角坐标。GPU 的 Buffer 只存当前要画的顶点,不含对象的结构信息,而清空、重绘、切换工具以及将来做选择/编辑都需要知道有哪些对象、每个对象的类型/颜色/顶点,因此 JavaScript 端的 objects 才是程序的"真相来源",Buffer 只是它在 GPU 上的渲染投影。