csharp
using MathNet.Symbolics;
using System.Text;
private string ConvertToLatex(string mathExpression)
{
return mathExpression
.Replace(" * ", "")
.Replace("*", "")
.Replace("π",@"\pi")
.Replace("sin(x)", @"\sin x")
.Replace("cos(x)", @"\cos x")
.Replace("tan(x)", @"\tan x")
.Replace("cot(x)", @"\cot x")
.Replace("sec(x)", @"\sec x")
.Replace("csc(x)", @"\csc x");
}
private string calculate_trigonometric_functions(string expression, bool isLatexFormat = false)
{
string ret = expression;
if (expression.Contains("sin(π/3)"))
{
/*
公式:sin(π/3) = √3/2
证明:sin(π/3)等于根号三除以2,即√3/2。这是因为在单位圆上,角度π/3对应的弧度是60度,它是一个等边三角形的内角,三角函数sin对应的是对边与斜边的比值,而等边三角形的对边和斜边长度相等,都是边长的根号三倍。因此,sin(π/3)等于根号三除以2。
*/
ret = ret.Replace("sin(π/3)", isLatexFormat ? "\\frac{\\sqrt{3}}{2}" : "sqrt(3)/2");
}
if (expression.Contains("cos(π/3)"))
{
/*
公式:cos(π/3) = 1/2
证明:考虑一个边长为1的等边三角形,其中每个内角都是60度(π/3弧度)。从一个顶点作垂线到对边,这将等边三角形分割成两个30-60-90的直角三角形。在这样的直角三角形中,较短的直角边(对应于60度角的邻边)是斜边(等边三角形的边)的一半,即1/2。由于余弦函数定义为邻边与斜边的比值,在60度角(π/3弧度)的情况下,这个比值就是1/2。
*/
ret = ret.Replace("cos(π/3)", isLatexFormat ? "\\frac{1}{2}" : "1/2");
}
if (expression.Contains("tan(π/3)"))
{
/*
公式:tan(π/3) = √3
证明:在直角三角形中,当其中一个锐角是60度时,这个角的对边与邻边的比值遵循特定的比例。具体来说,如果将这个直角三角形的斜边视为单位长度(即1),那么对边(对应于60度角的边)长度为√3,邻边长度为1。因此,根据正切(tan)的定义,即对边与邻边的比值,我们有tan(60°) = tan(π/3) = 对边/邻边 = √3/1 = √3。
*/
ret = ret.Replace("tan(π/3)", isLatexFormat ? "\\sqrt{3}" : "sqrt(3)");
}
if (expression.Contains("cot(π/3)"))
{
/*
公式:cot(π/3) = √3/3
证明:我们知道tan(π/3) = √3。余切cotθ是正切tanθ的倒数,即cotθ = 1/tanθ。因此,cot(π/3) = 1/tan(π/3) = 1/√3。
*/
ret = ret.Replace("cot(π/3)", isLatexFormat ? "\\frac{\\sqrt{3}}{3}" : "sqrt(3)/3");
}
return ret;
}
// 将函数定义为字符串
string functionString = "cos(x)"; // 将函数解析为符号表达式
SymbolicExpression function = SymbolicExpression.Parse(functionString);
// 代入x=π/3到函数
string x_value = "π/3";
SymbolicExpression val1 = SymbolicExpression.Parse(x_value);
SymbolicExpression x = SymbolicExpression.Parse("x");
SymbolicExpression y = function.Substitute(x, val1);
string ret_y = calculate_trigonometric_functions(y.ToString(), true);
// 关于x符号化的微分函数
SymbolicExpression derivative = function.Differentiate("x");
// 代入x=π/3到微分函数
SymbolicExpression result = derivative.Substitute(x, val1);
string ret = result.ToString();
if (ret.Contains("sin(π/3)"))
{
// sin(π/3) = √3/2
ret = ret.Replace("sin(π/3)", "\\sin \\frac{\\pi}{3}") + "=" + calculate_trigonometric_functions(ret, true);
}
if (ret.Contains("cos(π/3)"))
{
// cos(π/3) = 1/2
ret = ret.Replace("cos(π/3)", "\\cos \\frac{\\pi}{3}") + "=" + calculate_trigonometric_functions(ret, true);
}
if (ret.Contains("tan(π/3)"))
{
// tan(π/3) = √3
ret = ret.Replace("tan(π/3)", "\\tan \\frac{\\pi}{3}") + "=" + calculate_trigonometric_functions(ret, true);
}
if (ret.Contains("cot(π/3)"))
{
// cot(π/3) = √3/3
ret = ret.Replace("cot(π/3)", "\\cot \\frac{\\pi}{3}") + "=" + calculate_trigonometric_functions(ret, true);
}
string latexExpr0 = ConvertToLatex(functionString);
string latexExpr1 = ConvertToLatex(derivative.ToString());//将求解结果函数和值写入Tex文件
string filePath = "derivative_tangents_normals.tex"; // 文件路径
StringBuilder sb = new StringBuilder(500);
string latexHead = @"\documentclass{article}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行
";
string value = x_value.Replace("π","\\pi");
string[] values = value.Split("/");
value = $"\\frac{{{values[0]}}}{{{values[1]}}}";
sb.Append(latexHead);
sb.Append("\r\n");
sb.Append("求曲线$y=" + latexExpr0 + $"$上点$({value},{ret_y})$处的切线方程和法线方程。\r\n");
sb.Append("\r\n");
sb.Append($"解:$y'|_{{x={value}}}=({latexExpr1})|_{{x={value}}}={ret}$,\r\n");
sb.Append("\r\n");
sb.Append($"曲线在点$({value},{ret_y})$处的切线方程为:\r\n");
sb.Append("\r\n");
string tangentsFunction = "y + result * (x - x_value)"; // 将切线函数解析为符号表达式
SymbolicExpression tangents = SymbolicExpression.Parse(tangentsFunction);
SymbolicExpression y0 = SymbolicExpression.Parse("y");
SymbolicExpression result0 = SymbolicExpression.Parse("result");
SymbolicExpression x_value0 = SymbolicExpression.Parse("x_value");
SymbolicExpression tangentsExpression = tangents.Substitute(y0, y).Substitute(result0, result).Substitute(x_value0, x_value);
ret = calculate_trigonometric_functions(tangentsExpression.ToString(), false);
tangentsExpression = SymbolicExpression.Parse(ret);
sb.Append($"$y={tangentsExpression.ToLaTeX()}$,\r\n");
sb.Append("\r\n");
sb.Append($"曲线在点$({value},{ret_y})$处的法线方程为:\r\n");
sb.Append("\r\n");
string normalsFunction = "y - result ^ -1 * (x - x_value)"; // 将切线函数解析为符号表达式
SymbolicExpression normals = SymbolicExpression.Parse(normalsFunction);
SymbolicExpression normalsExpression = normals.Substitute(y0, y).Substitute(result0, result).Substitute(x_value0, x_value);
ret = calculate_trigonometric_functions(normalsExpression.ToString(), false);
normalsExpression = SymbolicExpression.Parse(ret);
sb.Append($"$y={normalsExpression.ToLaTeX()}$。\r\n");
string latexTail = @"
\end{CJK}
\end{document}";
sb.Append(latexTail);
string content = sb.ToString(); // 要写入的文本内容
Encoding utf8bom = new UTF8Encoding(true);
File.WriteAllText(filePath, content, utf8bom);
derivative_tangents_normals.tex文件内容:
xml
\documentclass{article}
\usepackage{amsmath,amssymb,amsfonts}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK}{UTF8}{gkai}%正文放在此行下与\end{CJK}之间就行
求曲线$y=\cos x$上点$(\frac{\pi}{3},\frac{1}{2})$处的切线方程和法线方程。
解:$y'|_{x=\frac{\pi}{3}}=(-\sin x)|_{x=\frac{\pi}{3}}=-\frac{\sqrt{3}}{2}$,
故曲线在点$(\frac{\pi}{3},\frac{1}{2})$处的切线方程为:
$y=\frac{1}{2} - \frac{1}{2}\sqrt{3}\left(-\frac{\pi}{3} + x\right)$,
曲线在点$(\frac{\pi}{3},\frac{1}{2})$处的法线方程为:
$y=\frac{1}{2} + \frac{-\frac{\pi}{3} + x}{2\sqrt{3}}$。
\end{CJK}
\end{document}