Introduction
This software graphs an equation written only by clicking the buttons and setting the limits and the steps to a graph. The problem is to recognize the equation operators and operands, set its priority and evaluate all the equations.
Background
This link explains the process to create a Postfix from an Infix expression.
Using the Code
Postfix Method
This method returns the Postfix equation in a string
array:
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;
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;
}
else if (c == "(")
{
p.Push(c);
}
else if (c == ")")
{
while ((p.Peek().ToString() != "("))
{
infijo[k] = p.Pop().ToString();
k++;
}
p.Pop();
}
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;
}
Priority and Operator Methods
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;
}
Evaluation Method
This method returns the result from evaluating the Postfix equation with an unknown variable:
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;
}
Graph Method
This method receives the graph title, axis title, limits, colors, Postfix Equation.
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();
}
Points of Interest
The Windows Form Application includes events to validate the input equation. The final version tested by the Sinc Function(Sin(x)/x)
with limits (-10,10), step (0.1) looks like this:
The application also includes a simple calculator (calc button), which is something like Windows Calc - this is only a plus. Enjoy and if there is something wrong, please let me know.