65.9K
CodeProject 正在变化。 阅读更多。
Home

图形计算器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.53/5 (25投票s)

2008年4月12日

CPOL
viewsIcon

86332

downloadIcon

5437

交互式显示数学函数图形的软件工具。

GraficadoraSource

引言

此软件通过点击按钮设置限制和步长来绘制方程。问题在于识别方程运算符和操作数,设置其优先级并评估所有方程。

背景

此链接 解释了从中缀表达式创建后缀表达式的过程。

Using the Code

后缀方法

此方法以string 数组的形式返回后缀方程

public string[] postfijo(string ecuacion)
        {
            int l = ecuacion.Length;
            string[] infijo = new string[l];
            int j; int k = 0; int i; 
            string c; string tmp = "";
            for ( i = 0; i < l; i++)
            {
                c = ecuacion[i].ToString();
                int band = 0;
                int band3 = 0;
                //Operando
                if (char.IsDigit(c, 0) || c == "x")
                {
                    j = i;
                    if (j < l)
                    {
                        while (char.IsDigit(ecuacion, j) || 
                        ecuacion[j].ToString() == ".")
                        {
                            infijo[k] = infijo[k] + ecuacion[j].ToString();
                            j++;
                            band++;
                            if (j == l)
                            {
                                break;
                            }
                        }
                    }
                    if (band > 0)
                    {
                        k++;
                        j--;
                    }
                    if (c == "x")
                    {
                        infijo[k] = c;
                        k++;
                    }
                    i = j;
                }//Paréntesis (
                else if (c == "(")
                {
                    p.Push(c);
                }//Paréntesis )
                else if (c == ")")
                {
                    while ((p.Peek().ToString() != "("))
                    {
                        infijo[k] = p.Pop().ToString();
                        k++;
                    }
                    p.Pop();
                }
                //Operandos 
                //Funciones seno, coseno, tangente, logaritmo, raiz cuadrada
                else if (c == "-" || c == "+" || c == "*" || c == "/" || c == "T" || 
                c == "S" || c == "C" || c == "L" || c == "^" || c == "E")
                {
                    j = i; 
                    tmp = "";
                    while (char.IsLetter(ecuacion, j))
                    {
                        tmp = tmp + ecuacion[j].ToString();
                        j++;
                        band3++;
                    }
                    if (band3 > 0)
                    {
                        p.Push(tmp);
                        j--;
                    }
                    i = j;
                    if (band3 == 0)
                    {
                        while ((p.Count > 0) && (p.Peek().ToString() != "(") && 
                        (prioridad(p.Peek().ToString()) >= prioridad(c)))
                        {
                            infijo[k] = p.Pop().ToString();
                            k++;
                            band3++;
                        }
                        p.Push(c);
                    }
                } 
            }
            while (p.Count>0)
            {
                infijo[k] = p.Pop().ToString();
                k++;
            }

            return infijo;            
        }

优先级和运算符方法

public int prioridad(string c)
        {
            if ((c == "+") || (c == "-"))
                return 0;
            if ((c == "*") || (c == "/"))
                return 1;
            if (c == "^")
                return 2;
            if ((c == "Log") || (c == "Sen") || (c == "Cos") || (c == "Tan") || 
                (c == "Exp") || (c == "Sqrt"))
                return 3;
            return -1;
        }

public bool operador(string o)
        {
                if (char.IsDigit(o, 0) || o == "x")
                    return false;
                
                if (char.IsLetter(o, 0))
                    return true;
                return true;
        }

评估方法

此方法返回评估具有未知变量的后缀方程的结果

public double evaluacion(string[] val, double x)
        {
            int i = 0;
            string operando1; string operando2;
            double op1; double op2;

            string c;
            double res = 0;
            for (i = 0; i < val.Length; i++)
            {
                if (val[i] == null)
                    break;
                c = val[i].ToString();

                
                    if (operador(c))
                    {
                        if (c == "+" || c == "-" || c == "*" || c == "/" || c == "^")
                        {
                            operando2 = p.Pop().ToString();
                            operando1 = p.Pop().ToString();

                            if (operando2 == "x")
                            {
                                op2 = x;
                            }
                            else
                            {
                                op2 = Convert.ToDouble(operando2);
                            }
                            if (operando1 == "x")
                            {
                                op1 = x;
                            }
                            else
                            {
                                op1 = Convert.ToDouble(operando1);
                            }
                            switch (c)
                            {
                                case "+":
                                    res = op1 + op2;
                                    p.Push(res);
                                    break;
                                case "-":
                                    res = op1 - op2;
                                    p.Push(res);
                                    break;
                                case "*":
                                    res = op1 * op2;
                                    p.Push(res);
                                    break;
                                case "/":
                                    res = op1 / op2;
                                    p.Push(res);
                                    break;
                                case "^":
                                    res = Math.Pow(op1, op2);
                                    p.Push(res);
                                    break;
                                default:
                                    break;
                            }
                        }
                        else
                        {

                            operando1 = p.Pop().ToString();
                            if (operando1 == "x")
                            {
                                op1 = x;
                            }
                            else
                            {
                                op1 = Convert.ToDouble(operando1);
                            }
                            switch (c)
                            {

                                case "Tan":
                                    res = Math.Tan(op1);
                                    p.Push(res);
                                    break;
                                case "Cos":
                                    res = Math.Cos(op1);
                                    p.Push(res);
                                    break;
                                case "Sen":
                                    res = Math.Sin(op1);
                                    p.Push(res);
                                    break;
                                case "Log":
                                    res = Math.Log(op1);
                                    p.Push(res);
                                    break;
                                case "Sqrt":
                                    res = Math.Sqrt(op1);
                                    p.Push(res);
                                    break;
                                case "Exp":
                                    res = Math.Exp(op1);
                                    p.Push(res);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
              
                else
                {
                    p.Push(c);
                }
            }
            double eval=Convert.ToDouble(p.Pop().ToString());
            return eval;
        }

绘图方法

此方法接收图形标题、轴标题、限制、颜色和后缀方程。

private void Grafica(ZedGraphControl zgc, string titulo, string ejeX, 
    string ejeY, double limInf, double limSup, string[] postfija, 
    double presicion, Color graph, Color graphLine)
        {
            GraphPane myPane = zgc.GraphPane;

            myPane.Title.Text = titulo;
            myPane.XAxis.Title.Text = ejeX;
            myPane.YAxis.Title.Text = ejeY;
            PointPairList list = new PointPairList();

            for (double x = limInf; x <= limSup; x+=presicion)
            {
                double y = evaluacion(postfija, x);

                list.Add(x, y);
            }

            LineItem myCurve = myPane.AddCurve
                    (titulo, list, graphLine, SymbolType.Diamond);
            myCurve.Symbol.Fill = new Fill(Color.Black);
            myCurve.Line.Fill = new Fill(Color.White, graph, 45F);
            myPane.Chart.Fill = new Fill(Color.Snow, Color.LightGoldenrodYellow, 45F);
            myPane.Fill = new Fill(Color.White, Color.FromArgb(220, 220, 255), 45F);
            zgc.AxisChange();
        }

关注点

Windows 窗体应用程序包括用于验证输入方程的事件。最终版本通过Sinc 函数(Sin(x)/x),限制为 (-10,10),步长为 (0.1) 进行测试,结果如下

graph1.jpg

该应用程序还包括一个简单的计算器(calc 按钮),类似于 Windows 计算器 - 这只是一个附加功能。 享受吧,如果有什么问题,请告诉我。

© . All rights reserved.