非常好的一篇文章,Graph of Function

来源:互联网 发布:java 字符串分割 编辑:程序博客网 时间:2024/05/17 07:44

原文:http://www.codeproject.com/Articles/713686/Graph-of-Function

  • Download GraphOfFunction-noexe.zip - 245.2 KB
  • Download GraphOfFunction.zip - 404.5 KB

Introduction

My program allows you to build a graph of a function given a string. In the program the user himself defines the boundaries within which there is a graph of the construction and function of the color line. To change the priority operations can use parentheses. The program examines the construction schedule affiliation argument domain of the function. Therefore, the graph is constructed only in locations that are the domain of the function. You can build any number of graphics functions, setting for each color display. You can change and delete functions are introduced.

Windows

The main program window.

Window entry functions.

Architecture

The program works in the following way change a character string, a list of tokens, syntax tree. Character string is a collection of some symbols that represent operations, functions, numbers, parentheses, variables x and constants pi and e token . List of tokens is a list of instances of classes that implement the interface Isintahnode. Syntax tree is a tree whose nodes are operations, functions, numbers, constants and variables are in accordance with the priority of their implementation.

Graph drawing takes place on the panel using the methods of class Graphics.

Using the code

Interface ISyntaxNode describes the behavior of token. Method GetResult returns result for this token. Method IsDomainOfFunction checks whether the value of x belongs to the domain of definition of the token. Method ToStringValue returns the symbol for the token.

public interface ISyntaxNode{    string ToStringValue();    double GetResult(double x);    bool IsDomainOfFunction(double x);}  

Class Function that inherits the interface ISyntaxNode.

abstract class Function: ISyntaxNode{    private ISyntaxNode x;    public Function()    {    }    public Function(ISyntaxNode x)    {        this.x = x;    }    public  ISyntaxNode GetX()    {        return x;    }    public void SetX(ISyntaxNode x)    {        this.x = x;    }    public abstract double GetResult(double x);    public abstract bool IsDomainOfFunction(double x);    public abstract string ToStringValue();}

Class Sin that inherits from the class Function and implements the abstract methods.

class Sin: Function{    public Sin(): base()    {    }    public Sin(ISyntaxNode x): base (x)    {    }    public override double GetResult(double x)    {        return Math.Sin(GetX().GetResult(x));    }    public override bool IsDomainOfFunction(double x)    {        return GetX().IsDomainOfFunction(x);    }    public override string ToStringValue()    {        return "sin";    }}

Attributes of the class SyntaxTree that performs build syntax tree.

listOperations - is a list conventional signs operations and functions that support the program.

listBynaryOperations - is a list conventional signs binary operations that support the program.

listUnaryOperations - is a list conventional signs unary operations that support the program.

listFunctions - is a list conventional signs functions that support the program.

root - is the root of syntax trees.

static List<string> listOperations = new List<string>(new string[] { "+", "-", "*", "/", "--", "^", "sin", "cos", "tan", "ctg", "log", "abs"});static List<string> listBinaryOperations = new List<string>(new string[] { "+", "-", "*", "/", "^"});static List<string> listUnaryOperations = new List<string>(new string[] {"--" });static List<string> listFunctions = new List<string>(new string[] { "sin", "cos", "tan", "ctg", "log", "abs" });private ISyntaxNode root;   

Method BuildSyntaxTree that performs build syntax tree. Method takes one parameter, which contains a list of tokens and return operations or functions with the lowest priority.

private ISyntaxNode BuildSyntaxTree(List<ISyntaxNode> listNode){    DeleteExcessiveBrackets(listNode);    if (listNode.Count == 1)  return listNode[0];    int position;    ISyntaxNode  min = FindMinPrioritiOperation(listNode, out position);    if (listBinaryOperations.IndexOf(min.ToStringValue()) != -1)    {        BinaryOperation operation = min as BinaryOperation;        operation.SetA(BuildSyntaxTree(listNode.GetRange(0, position)));        operation.SetB(BuildSyntaxTree(listNode.GetRange(position + 1,listNode.Count - (position +1))));    }    if (listUnaryOperations.IndexOf(min.ToStringValue()) != -1)    {        UnaryOperation operation = min as UnaryOperation;        operation.SetA(BuildSyntaxTree(listNode.GetRange(position + 1, listNode.Count - (position + 1))));    }    if (listFunctions.IndexOf(min.ToStringValue()) != -1)    {        Function function = min as Function;        function.SetX(BuildSyntaxTree(listNode.GetRange(position + 1, listNode.Count - (position + 1))));    }    return min;}

Method DeleteExcessiveBrackets deletes excessive brackets. Sample: expression before executing the method - ((9-x)*17-2); expression after execution method - (9-x)*17-2.

Method FindMinPrioritiOperation seeking operation is the lowest priority. Sample: expression - (9-x)*17-2; result - operation - and position 7.

Drawing graphics

private void DrawFunction(string function, Color functionColor){    int sizeX = panelGraphFunction.Size.Width;    int sizeY = panelGraphFunction.Size.Height;    double minX = -10, maxX = 10;    double minY = -10, maxY = 10;    minX = Convert.ToDouble(textBoxMinX.Text);    maxX = Convert.ToDouble(textBoxMaxX.Text);    minY = Convert.ToDouble(textBoxMinY.Text);    maxY = Convert.ToDouble(textBoxMaxY.Text);    SyntaxTree calculator = new SyntaxTree(function);    Graphics g = panelGraphFunction.CreateGraphics();    Point currentPoint = new Point();    Point previousPoint = new Point();    bool isCurentPoint = false;    bool isPreviousPoint = false;    for (double x = minX; x < maxX; x += (maxX - minX) / sizeX)    {        double y = calculator.Calculate(x, out isCurentPoint);        if (Math.Abs(y) > maxY * 2) isCurentPoint = false;        if (isCurentPoint)        {            currentPoint.X = (int)(x / ((maxX - minX) / sizeX) - minX / ((maxX - minX) / (double)sizeX));            currentPoint.Y = (int)(sizeY - (y / ((maxY - minY) / sizeY) - minY / ((maxY - minY) / (double)sizeY)));            if (isPreviousPoint)            {                g.DrawLine(new Pen(functionColor, 2), previousPoint, currentPoint);            }        }        previousPoint = currentPoint;        isPreviousPoint = isCurentPoint;    }}

0 0
原创粉丝点击