平面几何 → 交互教学网页
这个技能产出什么
一个可直接用浏览器打开的单页 HTML(三栏):
- 左栏:题面 + 动态控制台 —— 一个可变参数滑块(如边长比、角度、位置参数)驱动实时
重算的几何量(边长、面积、角度…),以及"恒等式指示"或"范围条"。
- 中栏:分步解析(公式用 KaTeX),可一键收起把空间让给画板。
- 右栏:浅色 2D Canvas 动态几何画板(多边形填充 + 线段 + 点标注 +
直角记号/等长标记/角弧),叠加画笔涂鸦工具栏。无坐标轴网格,还原课本纯几何风格。
依赖
无外部依赖。模板引擎 template/board-geo.html 是自包含的单页 HTML。
只要能用 Python 3(标准库即可)做字符串替换就行,或者直接用 JSON 手动注入。
与 edu-analytic-geometry 的区别
- edu-plane-geometry:纯平面几何,画板无坐标轴/网格(浅色背景),点可通过几何构造语法定义
- edu-analytic-geometry:解析几何,画板带坐标轴/网格,涉及圆锥曲线
工作流程
第 1 步:确定题目规约
明确:
- 几何元素:三角形(直角/等腰/等边/一般)、四边形(梯形/平行四边形/矩形/正方形)、圆等
- 变量参数:哪条边可变、角度范围、比例系数
- 要展示的定理/关系:勾股定理 a²+b²=c²、面积等式、全等条件、相似比等
- 语言:输出语言跟随提示词语言(中文/英文)
第 2 步:设计几何系统
选取方便的坐标系(内部仍需坐标,但画板不显示坐标轴/网格)。
坐标放置技巧:
- 直角顶点放在原点,两直角边沿坐标轴
- 对称图形利用对称性减少变量数
- 固定
a+b 为常量使梯形等图形高度不变
- 确保滑块在全部范围内几何结构有效(不退化)
几何构造语法(点支持对象语法替代坐标):
"points": {
// 传统坐标语法(仍然支持)
"A": [0, 0],
"B": ["a", 0],
// 几何构造语法(推荐)
"C": { "type": "midpoint", "a": "A", "b": "B" },
"D": { "type": "foot", "from": "C", "to": ["A", "B"] },
"E": { "type": "intersection", "l1": ["A", "B"], "l2": ["C", "D"] },
"F": { "type": "on_ray", "from": "A", "dir": "B", "distance": "t" },
"G": { "type": "reflect", "point": "C", "line": ["A", "B"] },
"H": { "type": "rotate", "point": "C", "center": "A", "angle": 90 }
}
第 3 步:组装数据并注入模板
📍 输出位置 & 唯一产物:交付给用户的只有一个 .html,写到当前工作目录
(Path.cwd())。cwd 里不要留任何别的文件——构建脚本(.py)、__pycache__、截图等
临时文件一律放 /tmp 或用完即删。也绝不要写进技能自身目录。
数据格式(三段式 JSON,schema 见 template/board-geo.html 数据岛 __LESSON_DATA__):
{
"lesson": {
"language": "zh-CN",
"title": "页面标题",
"problem": "<p>题面 HTML,公式用 $…$ / $$…$$</p>",
"answer": "$a^2+b^2=c^2$"
},
"steps": [
{ "title": "步骤一", "content": "<p>解析内容...</p>" },
],
"board": {
"view": { "xRange": [-1, 7], "yRange": [-1, 7] },
"points": {
"P": [0, 0],
"Q": ["a", 0],
"R": [0, "b"]
},
"param": {
"name": "t",
"label": "边长 $a$",
"min": 1, "max": 5, "step": 0.1,
"value": 3, "standard": 3
},
"scalars": [
{ "name": "a", "expr": "t" },
{ "name": "b", "expr": "4" }, // 另一直角边 b 固定
{ "name": "c", "expr": "sqrt(a*a+b*b)" }, // 斜边
{ "name": "chk", "expr": "a*a+b*b-c*c" } // 勾股恒等式左侧,应恒为 0
],
"derived": [
{ "type": "polygon", "pts": ["P", "Q", "R"],
"color": "rgba(248,113,113,0.25)", "stroke": "#f87171" },
{ "type": "segment", "name": "PQ", "a": "P", "b": "Q", "color": "aux" },
],
"annotations": [
{ "type": "right_angle", "vertex": "R", "arms": ["P", "Q"] },
{ "type": "tick", "segment": ["P", "Q"], "count": 1 },
{ "type": "angle_arc", "vertex": "P", "arms": ["Q", "R"], "label": "$\\theta$" },
],
"readouts": [
{ "id": "a", "label": "边长 $a$", "type": "expr", "expr": "a" },
{ "id": "angleP", "label": "$\\angle P$", "type": "angle",
"vertex": "P", "arms": ["Q", "R"], "digits": 1 },
{ "id": "area", "label": "面积", "type": "area_triangle",
"pts": ["P", "Q", "R"] },
// 勾股恒等式验证:a²+b²-c² 应恒等于 0,供 constant 指示器引用
{ "id": "chk", "label": "$a^2+b^2-c^2$", "type": "expr", "expr": "chk", "digits": 3 },
],
"constant": { "of": "chk", "label": "$a^2+b^2-c^2 \\equiv 0$" },
"legend": [
{ "color": "#f87171", "text": "△PQR" },
]
}
}
构建脚本方法(Python,推荐):
将构建脚本放 /tmp,直接做字符串替换:
#!/usr/bin/env python3
import json, sys
from pathlib import Path
sys.dont_write_bytecode = True
SKILL_DIR = Path(".claude/skills/edu-plane-geometry")
TEMPLATE = SKILL_DIR / "template" / "board-geo.html"
PLACEHOLDER = "__LESSON_DATA__"
data = {
"lesson": { ... },
"steps": [ ... ],
"board": { ... }
}
template = TEMPLATE.read_text(encoding="utf-8")
out_path = Path.cwd() / "solution-xxx.html"
out_path.write_text(
template.replace(PLACEHOLDER, json.dumps(data, ensure_ascii=False)),
encoding="utf-8"
)
print("written:", out_path)
python3 -B /tmp/build.py && rm -f /tmp/build.py
注意:模板路径改为 board-geo.html,非原来的 board.html。
第 4 步:自检与交付
- 数值正确性:手动验证面积/长度值符号预期
- 几何正确性:直角记号、等长标记、角弧标注位置正确
- 浏览器预览:起本地静态服务,检查无控制台报错、KaTeX 正常、滑块交互流畅
- 关闭端口:预览结束立即停掉本地服务
- 清理:删除
/tmp 中的临时脚本,确认 cwd 只有 .html
数据格式参考(核心字段)
board 关键字段说明
| 字段 |
类型 |
说明 |
view |
{xRange, yRange, showGrid?, showAxes?} |
数学坐标视窗(网格/轴默认 false) |
points |
{name: [x,y] 或 {xy,...} 或 {type,...}} |
顶点坐标或几何构造对象 |
param |
{name, min, max, step, value, label, ticks} |
滑块定义 |
scalars |
[{name, expr}] |
由 param 派生的命名常量 |
derived |
构造序列 |
polygon / segment / midpoint / foot_perp 等 |
annotations |
[{type, ...}] |
几何标注(直角/等长标记/角弧/平行标记) |
readouts |
[{id, label, type, ...}] |
实时数值 |
constant |
{of, label} |
定值指示器 |
legend |
[{color, text}] |
图例 |
点几何构造类型
| type |
字段 |
说明 |
midpoint |
a, b |
AB 的中点 |
foot |
from, to: [p1,p2] |
从点 to 线的垂足 |
intersection |
l1: [p1,p2], l2: [p1,p2] |
两线交点 |
on_ray |
from, dir, distance |
射线上一点(from→dir方向,给定距离) |
on_circle |
center, radius, angle |
圆上一点(角度°) |
rotate |
point, center, angle |
绕中心旋转(°) |
reflect |
point, line: [p1,p2] |
关于直线反射 |
标注类型
| type |
字段 |
说明 |
right_angle |
vertex, arms: [p1,p2] |
直角记号 ∟ |
tick |
segment: [p1,p2], count |
等长标记 ||(count 条数) |
parallel_mark |
segment: [p1,p2], count |
平行标记 ►(count 条数) |
angle_arc |
vertex, arms: [p1,p2], label?, radius? |
角弧标注(可选标签) |
readouts 新增几何类型
| type |
字段 |
显示内容 |
angle |
vertex, arms: [p,q] |
角度值(度) |
ratio |
a,b, c,d |
线段 AB 与 CD 长度之比 |
area |
pts: [p,q,r,...] |
多边形面积 |
其余已有类型:expr / distance / coord / area_triangle / length / status
derived 常用 type
| type |
字段 |
效果 |
polygon |
pts, color, stroke |
半透明填充多边形 |
segment |
a, b, color, dashed |
线段 |
midpoint |
name, a, b |
中点 |
foot_perp |
name, point, line |
垂足 |
vector |
from, to, color, label |
矢量箭头 |
表达式引擎
坐标值/scalars 中的 expr 支持:+ - * / ^ sqrt cbrt abs sin cos tan asin acos atan atan2 exp log pow min max sign floor ceil hypot PI
三角函数使用弧度(角度需先转换:theta*PI/180)。
参数名须是合法 JS 标识符(如 t/k/a/ratio,不能用 θ 等非标识符)。
目录
template/board-geo.html — 平面几何模板(浅色画板、无坐标轴、几何构造 + 标注系统)
template/board.html — 通用 2D 模板(带坐标轴网格,兼容旧页面)
references/conventions.md — 几何构造模式、自检清单
examples/ — 范例参考
1---2name: edu-plane-geometry3description: 把一道平面几何定理/问题做成交互教学网页:左栏题面 + 动态控制台(滑块驱动的边长/角度/面积 实时数值 + 定值/等式恒成立指示),中栏 KaTeX 分步解析,右栏 2D Canvas 动态几何画板 (三角形、四边形、多边形的点/线段/填充区域 + 直角记号/等长标记/角弧标注 + 画笔涂鸦)。 无需 sympy,画板为浅色背景、无坐标轴网格,还原课本纯几何风格。点支持几何构造语法 (中点/垂足/交点/旋转/反射),标注系统独立声明。形态与 edu-analytic-geometry 区分, 处理纯平面几何问题(无圆锥曲线、无解析坐标轴)。 触发词:平面几何, 三角形, 四边形, 梯形, 勾股定理, 面积, 全等, 相似, 角度, 几何证明, 交互教学网页; plane geometry, Euclidean geometry, triangle, quadrilateral, trapezoid, Pythagorean theorem, area, congruence, similarity, geometric proof, interactive geometry page.4---56# 平面几何 → 交互教学网页78## 这个技能产出什么9一个可直接用浏览器打开的单页 HTML(三栏):10- **左栏**:题面 + 动态控制台 —— 一个可变参数滑块(如边长比、角度、位置参数)驱动实时11 重算的几何量(边长、面积、角度…),以及"恒等式指示"或"范围条"。12- **中栏**:分步解析(公式用 **KaTeX**),可一键收起把空间让给画板。13- **右栏**:浅色 2D Canvas 动态几何画板(多边形填充 + 线段 + 点标注 + 14 直角记号/等长标记/角弧),叠加画笔涂鸦工具栏。无坐标轴网格,还原课本纯几何风格。1516## 依赖17**无外部依赖**。模板引擎 `template/board-geo.html` 是自包含的单页 HTML。18只要能用 Python 3(标准库即可)做字符串替换就行,或者直接用 JSON 手动注入。1920## 与 edu-analytic-geometry 的区别21- edu-plane-geometry:纯平面几何,画板**无坐标轴/网格**(浅色背景),点可通过**几何构造语法**定义22- edu-analytic-geometry:解析几何,画板带坐标轴/网格,涉及圆锥曲线2324## 工作流程2526### 第 1 步:确定题目规约27明确:28- **几何元素**:三角形(直角/等腰/等边/一般)、四边形(梯形/平行四边形/矩形/正方形)、圆等29- **变量参数**:哪条边可变、角度范围、比例系数30- **要展示的定理/关系**:勾股定理 a²+b²=c²、面积等式、全等条件、相似比等31- **语言**:输出语言跟随提示词语言(中文/英文)3233### 第 2 步:设计几何系统34选取方便的坐标系(内部仍需坐标,但画板**不显示坐标轴**/网格)。3536**坐标放置技巧**:37- 直角顶点放在原点,两直角边沿坐标轴38- 对称图形利用对称性减少变量数39- 固定 `a+b` 为常量使梯形等图形高度不变40- 确保滑块在全部范围内几何结构有效(不退化)4142**几何构造语法**(点支持对象语法替代坐标):43```jsonc44"points": {45 // 传统坐标语法(仍然支持)46 "A": [0, 0],47 "B": ["a", 0],48 // 几何构造语法(推荐)49 "C": { "type": "midpoint", "a": "A", "b": "B" },50 "D": { "type": "foot", "from": "C", "to": ["A", "B"] },51 "E": { "type": "intersection", "l1": ["A", "B"], "l2": ["C", "D"] },52 "F": { "type": "on_ray", "from": "A", "dir": "B", "distance": "t" },53 "G": { "type": "reflect", "point": "C", "line": ["A", "B"] },54 "H": { "type": "rotate", "point": "C", "center": "A", "angle": 90 }55}56```5758### 第 3 步:组装数据并注入模板5960> 📍 **输出位置 & 唯一产物**:交付给用户的**只有一个 `.html`**,写到**当前工作目录61> (`Path.cwd()`)**。cwd 里不要留任何别的文件——构建脚本(`.py`)、`__pycache__`、截图等62> 临时文件一律放 `/tmp` 或用完即删。也绝不要写进技能自身目录。6364**数据格式**(三段式 JSON,schema 见 `template/board-geo.html` 数据岛 `__LESSON_DATA__`):6566```jsonc67{68 "lesson": {69 "language": "zh-CN",70 "title": "页面标题",71 "problem": "<p>题面 HTML,公式用 $…$ / $$…$$</p>",72 "answer": "$a^2+b^2=c^2$"73 },74 "steps": [75 { "title": "步骤一", "content": "<p>解析内容...</p>" },76 ],77 "board": {78 "view": { "xRange": [-1, 7], "yRange": [-1, 7] },79 "points": {80 "P": [0, 0],81 "Q": ["a", 0],82 "R": [0, "b"]83 },84 "param": {85 "name": "t",86 "label": "边长 $a$",87 "min": 1, "max": 5, "step": 0.1,88 "value": 3, "standard": 389 },90 "scalars": [91 { "name": "a", "expr": "t" },92 { "name": "b", "expr": "4" }, // 另一直角边 b 固定93 { "name": "c", "expr": "sqrt(a*a+b*b)" }, // 斜边94 { "name": "chk", "expr": "a*a+b*b-c*c" } // 勾股恒等式左侧,应恒为 095 ],96 "derived": [97 { "type": "polygon", "pts": ["P", "Q", "R"],98 "color": "rgba(248,113,113,0.25)", "stroke": "#f87171" },99 { "type": "segment", "name": "PQ", "a": "P", "b": "Q", "color": "aux" },100 ],101 "annotations": [102 { "type": "right_angle", "vertex": "R", "arms": ["P", "Q"] },103 { "type": "tick", "segment": ["P", "Q"], "count": 1 },104 { "type": "angle_arc", "vertex": "P", "arms": ["Q", "R"], "label": "$\\theta$" },105 ],106 "readouts": [107 { "id": "a", "label": "边长 $a$", "type": "expr", "expr": "a" },108 { "id": "angleP", "label": "$\\angle P$", "type": "angle",109 "vertex": "P", "arms": ["Q", "R"], "digits": 1 },110 { "id": "area", "label": "面积", "type": "area_triangle",111 "pts": ["P", "Q", "R"] },112 // 勾股恒等式验证:a²+b²-c² 应恒等于 0,供 constant 指示器引用113 { "id": "chk", "label": "$a^2+b^2-c^2$", "type": "expr", "expr": "chk", "digits": 3 },114 ],115 "constant": { "of": "chk", "label": "$a^2+b^2-c^2 \\equiv 0$" },116 "legend": [117 { "color": "#f87171", "text": "△PQR" },118 ]119 }120}121```122123**构建脚本方法**(Python,推荐):124将构建脚本放 `/tmp`,直接做字符串替换:125126```python127#!/usr/bin/env python3128import json, sys129from pathlib import Path130sys.dont_write_bytecode = True131132SKILL_DIR = Path(".claude/skills/edu-plane-geometry")133TEMPLATE = SKILL_DIR / "template" / "board-geo.html"134PLACEHOLDER = "__LESSON_DATA__"135136data = {137 "lesson": { ... },138 "steps": [ ... ],139 "board": { ... }140}141142template = TEMPLATE.read_text(encoding="utf-8")143out_path = Path.cwd() / "solution-xxx.html"144out_path.write_text(145 template.replace(PLACEHOLDER, json.dumps(data, ensure_ascii=False)),146 encoding="utf-8"147)148print("written:", out_path)149```150151```bash152python3 -B /tmp/build.py && rm -f /tmp/build.py153```154155> 注意:模板路径改为 `board-geo.html`,非原来的 `board.html`。156157### 第 4 步:自检与交付158- **数值正确性**:手动验证面积/长度值符号预期159- **几何正确性**:直角记号、等长标记、角弧标注位置正确160- **浏览器预览**:起本地静态服务,检查无控制台报错、KaTeX 正常、滑块交互流畅161- **关闭端口**:预览结束立即停掉本地服务162- **清理**:删除 `/tmp` 中的临时脚本,确认 cwd 只有 `.html`163164## 数据格式参考(核心字段)165166### board 关键字段说明167168| 字段 | 类型 | 说明 |169|------|------|------|170| `view` | `{xRange, yRange, showGrid?, showAxes?}` | 数学坐标视窗(网格/轴默认 false) |171| `points` | `{name: [x,y] 或 {xy,...} 或 {type,...}}` | 顶点坐标或几何构造对象 |172| `param` | `{name, min, max, step, value, label, ticks}` | 滑块定义 |173| `scalars` | `[{name, expr}]` | 由 param 派生的命名常量 |174| `derived` | 构造序列 | polygon / segment / midpoint / foot_perp 等 |175| `annotations` | `[{type, ...}]` | 几何标注(直角/等长标记/角弧/平行标记) |176| `readouts` | `[{id, label, type, ...}]` | 实时数值 |177| `constant` | `{of, label}` | 定值指示器 |178| `legend` | `[{color, text}]` | 图例 |179180### 点几何构造类型181182| type | 字段 | 说明 |183|------|------|------|184| `midpoint` | `a, b` | AB 的中点 |185| `foot` | `from, to: [p1,p2]` | 从点 to 线的垂足 |186| `intersection` | `l1: [p1,p2], l2: [p1,p2]` | 两线交点 |187| `on_ray` | `from, dir, distance` | 射线上一点(from→dir方向,给定距离) |188| `on_circle` | `center, radius, angle` | 圆上一点(角度°) |189| `rotate` | `point, center, angle` | 绕中心旋转(°) |190| `reflect` | `point, line: [p1,p2]` | 关于直线反射 |191192### 标注类型193194| type | 字段 | 说明 |195|------|------|------|196| `right_angle` | `vertex, arms: [p1,p2]` | 直角记号 ∟ |197| `tick` | `segment: [p1,p2], count` | 等长标记 `\|\|`(count 条数) |198| `parallel_mark` | `segment: [p1,p2], count` | 平行标记 `►`(count 条数) |199| `angle_arc` | `vertex, arms: [p1,p2], label?, radius?` | 角弧标注(可选标签) |200201### readouts 新增几何类型202203| type | 字段 | 显示内容 |204|------|------|---------|205| `angle` | `vertex, arms: [p,q]` | 角度值(度) |206| `ratio` | `a,b, c,d` | 线段 AB 与 CD 长度之比 |207| `area` | `pts: [p,q,r,...]` | 多边形面积 |208209其余已有类型:`expr` / `distance` / `coord` / `area_triangle` / `length` / `status`210211### derived 常用 type212213| type | 字段 | 效果 |214|------|------|------|215| `polygon` | `pts, color, stroke` | 半透明填充多边形 |216| `segment` | `a, b, color, dashed` | 线段 |217| `midpoint` | `name, a, b` | 中点 |218| `foot_perp` | `name, point, line` | 垂足 |219| `vector` | `from, to, color, label` | 矢量箭头 |220221### 表达式引擎222坐标值/`scalars` 中的 `expr` 支持:`+ - * / ^ sqrt cbrt abs sin cos tan asin acos atan atan2223exp log pow min max sign floor ceil hypot PI`224三角函数使用**弧度**(角度需先转换:`theta*PI/180`)。225参数名须是合法 JS 标识符(如 `t`/`k`/`a`/`ratio`,不能用 `θ` 等非标识符)。226227## 目录228- `template/board-geo.html` — 平面几何模板(浅色画板、无坐标轴、几何构造 + 标注系统)229- `template/board.html` — 通用 2D 模板(带坐标轴网格,兼容旧页面)230- `references/conventions.md` — 几何构造模式、自检清单231- `examples/` — 范例参考