"""
数学可视化引擎 — 生成 SVG 图形
学生喜欢画画 → 用 SVG 让他们「看到」数学
"""
import math
def pie_chart(fractions: list, title: str = "", size: int = 200) -> str:
"""分数饼图 — 用于理解分数概念"""
colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7",
"#DDA0DD", "#98D8C8", "#F7DC6F", "#BB8FCE", "#85C1E9"]
total = sum(fractions)
if total == 0:
return ""
cx, cy, r = size // 2, size // 2, size // 2 - 10
paths = []
start_angle = -90 # 从顶部开始
for i, val in enumerate(fractions):
angle = (val / total) * 360
end_angle = start_angle + angle
# 计算弧线坐标
sr = math.radians(start_angle)
er = math.radians(end_angle)
x1 = cx + r * math.cos(sr)
y1 = cy + r * math.sin(sr)
x2 = cx + r * math.cos(er)
y2 = cy + r * math.sin(er)
large_arc = 1 if angle > 180 else 0
path = f''
paths.append(path)
# 标签
mid = math.radians(start_angle + angle / 2)
lx = cx + r * 0.6 * math.cos(mid)
ly = cy + r * 0.6 * math.sin(mid)
label_text = f"{val}/{total}" if total != sum(fractions) else str(val)
paths.append(f'{label_text}')
start_angle = end_angle
return f''''''
def number_line(start: int, end: int, highlights: list = None, size: tuple = (500, 80)) -> str:
"""数轴 — 用于加减法、负数、小数"""
w, h = size
margin = 40
line_y = h // 2
usable_w = w - 2 * margin
n_points = end - start + 1
spacing = usable_w / max(n_points - 1, 1)
elements = [f'']
for i in range(n_points):
val = start + i
x = margin + i * spacing
elements.append(f'')
elements.append(f'{val}')
if highlights:
for hl in highlights:
v = hl.get("value", 0)
label = hl.get("label", "")
x = margin + (v - start) * spacing
elements.append(f'')
if label:
elements.append(f'{label}')
return f''
def grid_array(rows: int, cols: int, highlight_cells: list = None, cell_size: int = 40) -> str:
"""阵列/格子 — 用于乘法、面积"""
w = cols * cell_size + 20
h = rows * cell_size + 20
elements = []
highlight_set = set(highlight_cells or [])
for r in range(rows):
for c in range(cols):
x = 10 + c * cell_size
y = 10 + r * cell_size
idx = r * cols + c
color = "#FF6B6B" if idx in highlight_set else "#4ECDC4"
opacity = "0.6" if idx in highlight_set else "0.3"
elements.append(f'')
return f''
def bar_chart(values: list, labels: list = None, title: str = "", size: tuple = (400, 250)) -> str:
"""柱状图"""
w, h = size
margin_t, margin_b, margin_l, margin_r = 30, 40, 50, 20
chart_w = w - margin_l - margin_r
chart_h = h - margin_t - margin_b
max_val = max(values) if values else 1
bar_w = chart_w / len(values) * 0.6
gap = chart_w / len(values) * 0.4
elements = [
f'',
f''
]
colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7", "#DDA0DD"]
for i, val in enumerate(values):
bar_h = (val / max_val) * chart_h if max_val > 0 else 0
x = margin_l + i * (bar_w + gap) + gap / 2
y = h - margin_b - bar_h
elements.append(f'')
elements.append(f'{val}')
if labels and i < len(labels):
elements.append(f'{labels[i]}')
if title:
elements.append(f'{title}')
return f''
def shapes_library() -> dict:
"""常用几何图形 SVG"""
return {
"square": '',
"rectangle": '',
"triangle": '',
"circle": '',
}