""" 数学可视化引擎 — 生成 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''' {''.join(paths)} {"" + title + "" if title else ""} ''' 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'{"".join(elements)}' 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'{"".join(elements)}' 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'{"".join(elements)}' def shapes_library() -> dict: """常用几何图形 SVG""" return { "square": '', "rectangle": '', "triangle": '', "circle": '', }