// tools/derivative_calculator.dart import 'package:flutter/material.dart'; import 'package:math_expressions/math_expressions.dart'; class DerivativeCalculatorPage extends StatefulWidget { @override _DerivativeCalculatorPageState createState() => _DerivativeCalculatorPageState(); } class _DerivativeCalculatorPageState extends State { final TextEditingController _functionController = TextEditingController(); final TextEditingController _pointController = TextEditingController(); String _result = ''; String _derivative = ''; bool _showPointInput = false; @override void dispose() { _functionController.dispose(); _pointController.dispose(); super.dispose(); } void _calculateDerivative() { final String functionText = _functionController.text.trim(); if (functionText.isEmpty) { setState(() { _result = '请输入函数表达式'; _derivative = ''; }); return; } try { // 解析函数表达式 Parser p = Parser(); Expression exp = p.parse(functionText); // 对x求导 Expression deriv = exp.derive('x'); // 简化导数表达式 Expression simplifiedDeriv = deriv.simplify(); setState(() { _derivative = '导函数: ${simplifiedDeriv.toString()}'; // 如果用户要求计算某点的导数值 if (_showPointInput && _pointController.text.isNotEmpty) { try { double point = double.parse(_pointController.text); ContextModel cm = ContextModel(); cm.bindVariable(Variable('x'), Number(point)); double value = simplifiedDeriv.evaluate(EvaluationType.REAL, cm); _result = '在 x = $point 处的导数值: ${value.toStringAsFixed(4)}'; } catch (e) { _result = '点的格式错误,请输入有效的数字'; } } else { _result = _derivative; } }); } catch (e) { setState(() { _result = '表达式解析错误,请检查格式\n支持的格式示例: x^2 + 3*x + sin(x)'; _derivative = ''; }); } } void _clearAll() { setState(() { _functionController.clear(); _pointController.clear(); _result = ''; _derivative = ''; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('导数计算器', style: TextStyle(color: Colors.black)), backgroundColor: Colors.white, elevation: 1, actions: [ IconButton( icon: Icon(Icons.info_outline), onPressed: () { _showInstructions(); }, ), ], ), body: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '函数表达式 (以x为变量):', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), SizedBox(height: 8), TextField( controller: _functionController, decoration: InputDecoration( hintText: '例如: x^2 + 3*x + sin(x)', border: OutlineInputBorder(), suffixIcon: IconButton( icon: Icon(Icons.info), onPressed: _showExpressionHelp, ), ), ), SizedBox(height: 16), // 计算某点导数值的选项 Row( children: [ Checkbox( value: _showPointInput, onChanged: (value) { setState(() { _showPointInput = value!; if (!value) { _pointController.clear(); } }); }, ), Text('计算某点处的导数值'), ], ), if (_showPointInput) ...[ SizedBox(height: 8), Text( '输入点的x坐标:', style: TextStyle(fontSize: 14), ), SizedBox(height: 8), TextField( controller: _pointController, decoration: InputDecoration( hintText: '例如: 2.5', border: OutlineInputBorder(), ), keyboardType: TextInputType.numberWithOptions(decimal: true), ), ], SizedBox(height: 20), Row( children: [ Expanded( child: ElevatedButton( onPressed: _calculateDerivative, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue, padding: EdgeInsets.symmetric(vertical: 12), ), child: Text('计算导数', style: TextStyle(color: Colors.white)), ), ), SizedBox(width: 10), Expanded( child: ElevatedButton( onPressed: _clearAll, style: ElevatedButton.styleFrom( backgroundColor: Colors.grey, padding: EdgeInsets.symmetric(vertical: 12), ), child: Text('清空', style: TextStyle(color: Colors.white)), ), ), ], ), SizedBox(height: 20), if (_result.isNotEmpty) ...[ Container( width: double.infinity, padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[50], borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.grey[300]!), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (_derivative.isNotEmpty && _showPointInput) ...[ Text( _derivative, style: TextStyle(fontSize: 14, color: Colors.grey[700]), ), SizedBox(height: 8), ], Text( _result, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: Colors.blue[800], ), ), ], ), ), ], Spacer(), _buildExamples(), ], ), ), ); } Widget _buildExamples() { return Container( width: double.infinity, padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.blue[50], borderRadius: BorderRadius.circular(8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '表达式示例:', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.blue[800]), ), SizedBox(height: 8), _buildExampleItem('x^2 + 3*x + 2'), _buildExampleItem('sin(x)'), _buildExampleItem('cos(x)'), _buildExampleItem('ln(x)'), _buildExampleItem('sqrt(x)'), _buildExampleItem('(x+1)/(x-1)'), ], ), ); } Widget _buildExampleItem(String example) { return GestureDetector( onTap: () { setState(() { _functionController.text = example; }); }, child: Padding( padding: EdgeInsets.symmetric(vertical: 4), child: Text( '• $example', style: TextStyle(color: Colors.blue[700], fontSize: 14), ), ), ); } void _showInstructions() { showDialog( context: context, builder: (context) => AlertDialog( title: Text('使用说明'), content: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text('1. 输入以x为自变量的函数表达式'), SizedBox(height: 8), Text('2. 支持的基本函数:'), Text(' • sin(x), cos(x), tan(x)'), Text(' • ln(x) - 自然对数'), Text(' • sqrt(x) - 平方根'), SizedBox(height: 8), Text('3. 支持的操作符:'), Text(' • +, -, *, /'), Text(' • ^ - 幂运算'), Text(' • () - 括号'), SizedBox(height: 8), Text('4. 可选计算某点处的导数值'), ], ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('确定'), ), ], ), ); } void _showExpressionHelp() { showDialog( context: context, builder: (context) => AlertDialog( title: Text('表达式格式帮助'), content: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text('支持的数学表达式:'), SizedBox(height: 8), _buildHelpItem('x^2', 'x的平方'), _buildHelpItem('3*x', '3乘以x'), _buildHelpItem('sin(x)', '正弦函数'), _buildHelpItem('cos(x)', '余弦函数'), _buildHelpItem('ln(x)', '自然对数'), _buildHelpItem('sqrt(x)', '平方根'), _buildHelpItem('(x+1)/(x-1)', '分式'), ], ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('确定'), ), ], ), ); } Widget _buildHelpItem(String expression, String description) { return Padding( padding: EdgeInsets.symmetric(vertical: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 80, child: Text( expression, style: TextStyle(fontFamily: 'Monospace', fontWeight: FontWeight.bold), ), ), SizedBox(width: 10), Expanded(child: Text(description)), ], ), ); } }