返回赛题列表
万花尺工坊
挑战网页版万花尺(Spirograph)绘图工具,从静态曲线到参数化动画再到拟真齿轮拖拽,四个独立阶段递进考察 hypotrochoid 数学正确性、Canvas 动画能力与齿轮滚动几何约束。
规则说明▼
phase1:静态绘制一条完整闭合曲线,考察模型对 hypotrochoid 公式、闭合周期和采样平滑度的基础理解
phase2:制作参数化动画绘图工具,考察交互设计、动画循环和参数变化后的重新计算
phase3:模拟真实塑料万花尺玩具,考察可见齿轮、拖拽滚动、无打滑自转和笔触质感
phase4:制作超级万花尺工具,强制加入形状孔 / 槽孔与外旋轮线(epitrochoid)
Prompt▼
phase1:▼
实现一个网页版「万花尺(Spirograph)」静态绘图页面,以 **单个 HTML 文件** 提交,可使用任意第三方库(通过 CDN 引入)。
数学基础:万花尺曲线可由 hypotrochoid 参数方程描述:
- `x(t) = (R - r) * cos(t) + d * cos(((R - r) / r) * t)`
- `y(t) = (R - r) * sin(t) - d * sin(((R - r) / r) * t)`
其中 `R` 为外圈固定圆半径,`r` 为内圈滚动圆半径,`d` 为笔尖到内圈圆心的距离。曲线闭合周期与 `gcd(R, r)` 相关,需要正确处理以保证一笔画完整。
````
### 核心要求
1. 选用一组合理的默认参数,在画布中央渲染出一条**完整闭合**的万花尺曲线。
2. 不需要任何交互,**页面打开即看到完整图样**。
3. 曲线必须平滑(采样步长足够小,不能出现明显折线)。
4. 画布需有合理的居中、留白与背景色,曲线颜色不得与背景同色。
5. Canvas 或 SVG 任选其一实现。
6. 在页面上显示一行小字,标注当前所用的 `R / r / d` 值。
7. 曲线必须真正基于 hypotrochoid 公式计算,不允许写死路径或贴图。
### 技术约束
- 不允许提交本地依赖文件(图片 / 字体 / 音频可以 base64 内联,或使用公共 CDN)
- 不允许使用后端服务
- 不允许使用预渲染图片或 SVG 路径冒充曲线
````
phase2:▼
实现一个网页版「万花尺(Spirograph)」参数化绘图工具,以 **单个 HTML 文件** 提交,可使用任意第三方库(通过 CDN 引入)。
数学基础:万花尺曲线可由 hypotrochoid 参数方程描述:
- `x(t) = (R - r) * cos(t) + d * cos(((R - r) / r) * t)`
- `y(t) = (R - r) * sin(t) - d * sin(((R - r) / r) * t)`
其中 `R` 为外圈固定圆半径,`r` 为内圈滚动圆半径,`d` 为笔尖到内圈圆心的距离。曲线闭合周期与 `gcd(R, r)` 相关,需要正确处理以保证一笔画完整。
````
### 基础绘制要求
1. 选用一组合理的默认参数,在画布中央渲染出一条**完整闭合**的万花尺曲线。
2. 页面打开时即可看到默认图样,曲线平滑、居中、有合理留白。
3. 显示当前所用的 `R / r / d` 值。
4. 曲线必须真正基于 hypotrochoid 公式计算,不允许写死路径或贴图。
### 参数化与动画
1. **参数控制面板**:
- 三个滑块(或数字输入)分别控制 `R`、`r`、`d`,范围合理。
- 一个色板或颜色选择器控制笔触颜色。
- 一个「绘制速度」控件(慢/中/快 三档或滑块)。
2. **预设形状**:
- 提供至少 **5 个预设按钮**(例:玫瑰花、五角星、花瓣环、密集网纹、近圆环),点击后自动加载对应参数并立即开始绘制。
3. **动态绘制动画**:
- 点击「开始」后,从 `t=0` 起按时间逐点描绘曲线,画面上能看到笔尖位置标记(一个小圆点或十字)。
- 提供「暂停 / 继续 / 清除」按钮。
- 任意参数变更后,按「重新绘制」可以从头开始。
4. **采样与性能**:
- 步长需根据 `R/r` 自适应,保证曲线平滑且不会卡顿。
- 每帧使用 `requestAnimationFrame`,禁止使用 `setInterval` 做主循环。
5. 控制面板需有清晰标签与单位/范围提示。
6. 至少一种预设的曲线形态需要明显有别于 Phase 1 默认值。
### 技术约束
- 不允许提交本地依赖文件(图片 / 字体 / 音频可以 base64 内联,或使用公共 CDN)
- 不允许使用后端服务
- 任意 CDN 第三方库(Pixi.js、Two.js、PaperJS、p5.js、d3、gsap 等任选)
- Web Audio、ResizeObserver、PointerEvent、requestAnimationFrame 等现代 API
- 不允许使用预渲染图片或 SVG 路径冒充曲线
- 不允许使用 `<canvas>` 截图作为静态绘制的伪造结果
- `r >= R` 时应做参数夹逼或友好提示,不能崩溃
- `d=0` 时应能画出正圆(基础 hypotrochoid 性质)
- `gcd(R, r) = 1` 时曲线周期最长,需要保证步进完整闭合,且性能不退化
````
phase3:▼
实现一个网页版「拟真万花尺(Spirograph)」绘图工具,以 **单个 HTML 文件** 提交,可使用任意第三方库(通过 CDN 引入)。
数学基础:万花尺曲线可由 hypotrochoid 参数方程描述:
- `x(t) = (R - r) * cos(t) + d * cos(((R - r) / r) * t)`
- `y(t) = (R - r) * sin(t) - d * sin(((R - r) / r) * t)`
其中 `R` 为外圈固定圆半径,`r` 为内圈滚动圆半径,`d` 为笔尖到内圈圆心的距离。曲线闭合周期与 `gcd(R, r)` 相关,需要正确处理以保证一笔画完整。
````
### 拟真万花尺
1. **可见齿轮系统**:
- 画布上同时渲染**外圈大齿轮(环齿,齿朝内)**与**内圈小齿轮(齿朝外)**,齿数与 `R / r` 相符且**齿在视觉上互相咬合**(不需要严格 1:1 物理仿真,但放大后齿数与位置应能对应得上)。
- 小齿轮上至少有 3 个可选笔孔,距离圆心不同(对应不同 `d`)。
- 大齿轮可显示中心销钉与刻度。
2. **拖拽驱动**:
- 用户可用鼠标 / 触控**直接拖拽小齿轮**,小齿轮沿大齿轮内壁滚动,同时笔尖在纸面上留下真实的曲线轨迹。
- 拖拽必须沿大齿轮内壁约束,不能脱离。
- 小齿轮的自转角度必须与沿大齿轮滚过的弧长一致(`无打滑`),否则视为不通过。
3. **笔触与质感**:
- 至少提供 3 种笔触色(如红、蓝、绿),切换后下一段轨迹使用新颜色。
- 笔触应有轻微的不均匀感(线宽抖动 / 透明度抖动 / 类墨水扩散)以模仿圆珠笔。
- 背景为可见的纸张质感(米色 / 网格 / 轻微噪声)。
4. **完整工具栏**:
- 切换笔孔(不同 `d`)。
- 切换内齿轮规格(不同 `r`,至少 3 种)。
- 「清除纸面」「保存为 PNG」「保存为 SVG」按钮。
- 「自动滚动」按钮:松手后小齿轮自动匀速绕完一整圈,便于预览。
5. **细节加分项(可选)**:
- 拖拽时齿轮咬合的「咔哒」音效。
- 已绘制轨迹在切换参数面板、工具栏选项或视图状态时不丢失。
### 技术约束
- 不允许提交本地依赖文件(图片 / 字体 / 音频可以 base64 内联,或使用公共 CDN)
- 不允许使用后端服务
- 任意 CDN 第三方库(Pixi.js、Two.js、PaperJS、p5.js、d3、gsap 等任选)
- Web Audio、ResizeObserver、PointerEvent、requestAnimationFrame 等现代 API
- 不允许使用预渲染图片或 SVG 路径冒充曲线
- 不允许使用 `<canvas>` 截图作为静态绘制的伪造结果
- 不允许拖拽时使用「跳跃式」吸附(必须连续滚动)
- `r >= R` 时应做友好提示
- `d=0` 时应能画出正圆
- `gcd(R, r) = 1` 时曲线周期最长,需要保证步进完整闭合
- 触控与鼠标都应能工作
````
phase4:▼
实现一个网页版「超级万花尺(Super Spirograph)」绘图工具,以 **单个 HTML 文件** 提交,可使用任意第三方库(通过 CDN 引入)。
要求如下:
````
### 拟真万花尺基础能力
1. **可见齿轮系统**:
- 画布上同时渲染外圈大齿轮与内圈小齿轮。
- 外圈大齿轮应表现为环齿,齿朝内;内圈小齿轮齿朝外。
- 齿数与 `R / r` 大致相符,视觉上必须能看出齿轮互相咬合。
- 小齿轮上至少有 3 个固定圆形笔孔,距离圆心不同,对应不同 `d`。
- 大齿轮可显示中心销钉、刻度、半透明塑料质感。
2. **拖拽驱动**:
- 用户可用鼠标 / 触控直接拖拽小齿轮。
- 小齿轮必须沿大齿轮内壁滚动,不能脱离轨道。
- 小齿轮的自转角度必须与沿大齿轮滚过的弧长一致(无打滑)。
- 拖拽时笔尖应在纸面上留下连续轨迹。
3. **笔触与纸张质感**:
- 至少提供 3 种笔触色,切换后下一段轨迹使用新颜色。
- 笔触应有轻微不均匀感(线宽抖动 / 透明度抖动 / 类墨水扩散)。
- 背景为纸张质感(米色 / 网格 / 轻微噪声)。
4. **基础工具栏**:
- 切换固定圆形笔孔。
- 切换内齿轮规格(不同 `r`,至少 3 种)。
- 「清除纸面」「保存为 PNG」「保存为 SVG」按钮。
- 「自动滚动」按钮:松手后小齿轮自动匀速绕完一整圈,便于预览。
### 形状孔 / 槽孔
真实万花尺不只有圆形笔孔,也会有长槽、椭圆槽、星形槽、花瓣槽等形状孔。你需要实现:
1. 除固定圆孔外,至少提供 **3 种形状孔 / 槽孔**(例如长槽、椭圆槽、星形槽、花瓣槽)。
2. 形状孔必须画在小齿轮上,并跟随小齿轮一起公转和自转。
3. 笔尖在形状孔内的位置不是固定点,而是小齿轮局部坐标系中的可变点 `localPoint`。
4. 用户拖拽笔尖时,笔尖必须被约束在当前形状孔边界内,不能穿出孔洞。
5. 最终轨迹应由「小齿轮圆心运动 + 小齿轮自转 + 笔尖局部位置」共同决定:
- `pen(t) = gearCenter(t) + rotate(gearRotation(t)) * localPoint`
6. 切换形状孔时,应能明显看到轨迹形态发生变化,不能只把形状孔当作装饰图案。
### 内旋 / 外旋统一
必须同时支持小齿轮在大圆内部滚动的 hypotrochoid,以及小齿轮沿大圆外侧滚动的 epitrochoid。
内旋轮线(hypotrochoid)参数方程:
- `x(t) = (R - r) * cos(t) + d * cos(((R - r) / r) * t)`
- `y(t) = (R - r) * sin(t) - d * sin(((R - r) / r) * t)`
外旋轮线可由以下参数方程描述:
- `x(t) = (R + r) * cos(t) - d * cos(((R + r) / r) * t)`
- `y(t) = (R + r) * sin(t) - d * sin(((R + r) / r) * t)`
要求:
1. 提供「内旋 / 外旋」模式切换:
- 内旋:小齿轮在大圆内壁滚动,对应 hypotrochoid
- 外旋:小齿轮沿大圆外侧滚动,对应 epitrochoid
2. 外旋模式下,齿轮位置、齿轮自转方向、笔尖轨迹都必须随模式改变,不能只套用同一条公式改个符号。
3. 内旋和外旋都要支持固定圆孔与形状孔 / 槽孔。
4. 内旋和外旋都要处理闭合周期,不能出现未闭合、断线或无限绘制。
5. 至少提供 3 个外旋预设(如太阳花、外摆玫瑰、密集星芒),并能和内旋预设明显区分。
### 工具与展示
1. 工具栏需包含:内旋 / 外旋切换、固定孔 / 形状孔切换、形状孔类型选择、笔触颜色、齿轮规格、清除、导出 PNG、导出 SVG。
2. 画布上要能清楚看出当前是内滚还是外滚:外旋时小齿轮应位于大圆外侧,并沿外壁滚动。
3. 笔尖、齿轮中心、当前孔洞位置应有清晰视觉标记,方便观察几何关系。
4. 已绘制轨迹在切换工具栏选项或视图状态时不丢失,除非用户明确点击「清除」。
### 技术约束
- 不允许提交本地依赖文件(图片 / 字体 / 音频可以 base64 内联,或使用公共 CDN)
- 不允许使用后端服务
- 任意 CDN 第三方库(Pixi.js、Two.js、PaperJS、p5.js、d3、gsap 等任选)
- Web Audio、ResizeObserver、PointerEvent、requestAnimationFrame 等现代 API
- 不允许使用预渲染图片或 SVG 路径冒充曲线
- 不允许把形状孔简化成几个固定点按钮,必须体现笔尖在孔洞边界内连续移动的约束
- 不允许外旋模式只复用内旋视觉而不改变齿轮相对位置和自转关系
- 内旋与外旋都需要处理 `gcd(R, r)` 相关的闭合周期
- 触控与鼠标都应能工作
````