Beispiel #1
0
        /// <summary>
        /// Calculate the equation.
        /// </summary>
        private void Calculate()
        {
            double value = 0.0d;

            try {
                Equation equation = Equation.ParseEquation(_equation);

                value = equation.GetValue();
                _history.Add(_equation + "=" + value.ToString("G5"));
                _windowPos.height = 0.0f;
                _windowPos.width  = 0.0f;

                if (_history.Count > MAX_HISTORY)
                {
                    _history.RemoveRange(0, _history.Count - MAX_HISTORY);
                }
            } catch (ParsingException e) {
                Debug.Log(_equation + ":" + e.Message);
                _history.Add(_equation + "\n" + e.Message);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Raises the window event.
        /// </summary>
        /// <param name="windowId">Window identifier.</param>
        private void OnWindow(int windowId)
        {
            GUILayout.BeginHorizontal(GUILayout.MinWidth(300.0f));
            GUILayout.BeginVertical(GUILayout.MaxWidth(300.0f + (_width * 50.0f)));
            GUILayout.BeginHorizontal();
            GUILayout.Label("History:", _labelStyle);
            if (GUILayout.Button("Clear", _buttonStyle))
            {
                _history.Clear();
                _windowPos.height = 0.0f;
                _windowPos.width  = 0.0f;
            }
            GUILayout.EndHorizontal();
            GUILayout.TextArea(String.Join("\n", _history.ToArray()), _textAreaStyle);
            GUILayout.BeginHorizontal(GUILayout.MinWidth(300.0f + (_width * 50.0f)));
            GUILayout.Label("Equation Input:", _labelStyle);
            if (GUILayout.Button("Wider", _buttonStyle) && _width < 6)
            {
                _width++;
            }
            if (GUILayout.Button("Narrower", _buttonStyle) && _width > 0)
            {
                _width--;
                _windowPos.width = 0.0f;
            }
            GUILayout.EndHorizontal();
            GUI.SetNextControlName("EquationIn");
            _equation = GUILayout.TextField(_equation, _textFieldStyle);
            if (Event.current.isKey && GUI.GetNameOfFocusedControl() == "EquationIn")
            {
                if (Event.current.keyCode == KeyCode.UpArrow || Event.current.keyCode == KeyCode.DownArrow)
                {
                    if (Event.current.keyCode == KeyCode.UpArrow)
                    {
                        if (_hIdx < 0)
                        {
                            _hIdx = _history.Count - 1;
                        }
                        else
                        {
                            _hIdx--;
                        }
                    }
                    else if (Event.current.keyCode == KeyCode.DownArrow)
                    {
                        _hIdx++;
                        if (_hIdx >= _history.Count)
                        {
                            _hIdx = -1;
                        }
                    }
                    if (_hIdx < 0)
                    {
                        _hIdx     = -1;
                        _equation = "";
                    }
                    else
                    {
                        string hist = _history [_hIdx];
                        if (hist.IndexOf('=') > 0)
                        {
                            hist = hist.Remove(hist.IndexOf('='));
                        }
                        if (hist.IndexOf('\n') > 0)
                        {
                            hist = hist.Remove(hist.IndexOf('\n'));
                        }
                        _equation = hist;
                    }
                }
                else if (Event.current.keyCode == KeyCode.Return)
                {
                    Calculate();
                }
            }
            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Calculate", _buttonStyle))
            {
                Calculate();
            }
            if (GUILayout.Button(_simple ? "More" : "Less", _buttonStyle))
            {
                _simple           = !_simple;
                _windowPos.width  = 0.0f;
                _windowPos.height = 0.0f;
            }
            if (GUILayout.Button("Close", _buttonStyle))
            {
                Hide();
            }
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();

            if (!_simple)
            {
                GUILayout.BeginVertical(GUILayout.MaxWidth(300.0f));
                int oldMenu = _menuSelection;
                _menuSelection = GUILayout.SelectionGrid(_menuSelection,
                                                         new string[] { "Graph", "Cheat Sheet", "Notes", "Help" }, 2, _buttonStyle,
                                                         GUILayout.MinWidth(300.0f));
                if (_menuSelection == 0)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("X Min:", _labelStyle, GUILayout.MaxWidth(50.0f));
                    _xmin = GUILayout.TextField(_xmin, _textFieldStyle, GUILayout.MaxWidth(250f));
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("X Max:", _labelStyle, GUILayout.MaxWidth(50.0f));
                    _xmax = GUILayout.TextField(_xmax, _textFieldStyle, GUILayout.MaxWidth(250f));
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();

                    if (GUILayout.Button("Graph", _buttonStyle))
                    {
                        Graph();
                    }
                    if (GUILayout.Button("Reset Graph", _buttonStyle))
                    {
                        _graph            = null;
                        _geq              = null;
                        _windowPos.height = 0.0f;
                        _windowPos.width  = 0.0f;
                    }

                    GUILayout.EndHorizontal();
                    if (_graph != null)
                    {
                        GUILayout.Label("Y max:" + _ymax.ToString("G10"), _labelStyle);
                        GUILayout.Box(_graph.getImage());
                        Rect   boxRect          = GUILayoutUtility.GetLastRect();
                        string mouseOverMessage = "";
                        if (boxRect.Contains(Event.current.mousePosition))
                        {
                            float x = Event.current.mousePosition.x - boxRect.x - 25.0f;
                            if (x >= 0 && x <= 250.0f)
                            {
                                double delta = (_gxmax - _gxmin) / 250.0d;

                                mouseOverMessage = "X:" + (_gxmin + x * delta).ToString("G5") +
                                                   " Y:" + _geq.GetValue(_gxmin + x * delta).ToString("G5");
                            }
                        }
                        GUILayout.Label("Y min:" + _ymin.ToString("G10"), _labelStyle);
                        GUILayout.Label(mouseOverMessage, _labelStyle);
                    }
                }
                else if (_menuSelection == 1)
                {
                    GUILayout.Label("Cheat Sheet", _labelStyle);
                    GUILayout.TextArea(CHEAT_SHEET, _textAreaStyle);
                }
                else if (_menuSelection == 2)
                {
                    GUILayout.Label("Notes", _labelStyle);
                    _globalScratchPad = GUILayout.TextArea(_globalScratchPad, _textAreaStyle);
                }
                else if (_menuSelection == 3)
                {
                    GUILayout.Label("Help", _labelStyle);
                    GUILayout.TextArea(HELP, _textAreaStyle);
                }
                if (_menuSelection != oldMenu)
                {
                    _windowPos.height = 0.0f;
                }
                GUILayout.EndVertical();
            }
            GUILayout.EndHorizontal();

            GUI.DragWindow();
        }
Beispiel #3
0
        /// <summary>
        /// Parses the equation string returning an Equation object. Error checking is minimal and will evaluate
        /// invalid strings in unique and meaningless ways.
        /// </summary>
        /// <returns>The equation object.</returns>
        /// <param name="eqText">Equation text.</param>
        static public Equation ParseEquation(string eqText)
        {
            char[]   eq       = eqText.ToCharArray();
            string   constant = "";
            Equation equation = new Equation();

            for (int index = 0; index < eqText.Length; index++)
            {
                // Ignore whitespace.
                if (Char.IsWhiteSpace(eq[index]))
                {
                    continue;
                }
                if (eq [index] == ',')
                {
                    continue;
                }
                if (eq [index] == '=')
                {
                    continue;
                }

                bool addConstant = false;
                // Determine if this looks like a constant (0-9, -, ., or e surrounded by digits).
                if (Char.IsDigit(eq [index]) ||
                    (Char.ToLower(eq [index]) == 'e' && constant != "") ||
                    eq[index] == '.')
                {
                    constant   += eq [index];
                    addConstant = true;
                    // We are at the end of the constant, make it a term.
                }
                else if (constant != "")
                {
                    ConstantTerm ct = new ConstantTerm(Double.Parse(constant));
                    equation.SetNextTerm(ct);
                    constant = "";
                }
                // We are at the end of the string. Turn the last constant into a term if applicable.
                if (index + 1 == eqText.Length && constant != "")
                {
                    ConstantTerm ct = new ConstantTerm(Double.Parse(constant));
                    equation.SetNextTerm(ct);
                    constant = "";
                }

                if (eq [index] == '-')
                {
                    int k = index + 1;
                    while (k < eqText.Length)
                    {
                        if (!Char.IsWhiteSpace(eq [k]))
                        {
                            break;
                        }
                        k++;
                    }
                    if (k >= eqText.Length)
                    {
                        throw new ParsingException("Ends with a - sign.");
                    }
                    // First term is negative or it is part of a negative exponent in a constant.
                    if (Char.IsDigit(eq [k]) &&
                        (equation.GetPrevTerm(-1) == null || constant != ""))
                    {
                        constant   += eq [index];
                        addConstant = true;
                    }
                    else
                    {
                        int j = index - 1;
                        while (j > 0)
                        {
                            if (!Char.IsWhiteSpace(eq [j]))
                            {
                                break;
                            }
                            j--;
                        }
                        // First term, but not followed by digit.
                        if (j < 0)
                        {
                            j = 0;
                        }

                        // Not a digit and not a paren, must be an operation, so this must be a negation.
                        if (!Char.IsDigit(eq [j]) && eq[j] != ')')
                        {
                            if (Char.IsDigit(eq [k]))
                            {
                                constant   += eq [index];
                                addConstant = true;
                            }
                            else
                            {
                                NegationTerm neg = new NegationTerm();
                                equation.SetNextTerm(neg);
                                continue;
                            }
                        }
                    }
                }

                // We have a parenthetical statement. Find the end of this parenthesis and parse it as its own equation.
                if (eq [index] == '(')
                {
                    int nesting = 1;
                    int j       = index + 1;
                    for (; j < eqText.Length; j++)
                    {
                        if (eq [j] == '(')
                        {
                            nesting++;
                        }
                        if (eq [j] == ')')
                        {
                            nesting--;
                        }
                        if (nesting == 0)
                        {
                            break;
                        }
                    }
                    equation.SetNextTerm(ParseEquation(eqText.Substring(index + 1, j - index - 1)));
                    index = j;
                    // Ignore the end parenthesis.
                }
                else if (eq [index] == ')')
                {
                }
                else if (eq [index] == '^')
                {
                    ExponentTerm exp = new ExponentTerm(equation.GetPrevTerm((int)OperatorPriority.EXPONENT));
                    equation.SetNextTerm(exp);
                }
                else if (eq [index] == '*')
                {
                    MultiplyTerm mult = new MultiplyTerm(equation.GetPrevTerm((int)OperatorPriority.MULTIPLY));
                    equation.SetNextTerm(mult);
                }
                else if (eq [index] == '/')
                {
                    DivideTerm div = new DivideTerm(equation.GetPrevTerm((int)OperatorPriority.DIVISION));
                    equation.SetNextTerm(div);
                }
                else if (eq [index] == '%')
                {
                    ModuloTerm div = new ModuloTerm(equation.GetPrevTerm((int)OperatorPriority.DIVISION));
                    equation.SetNextTerm(div);
                }
                else if (eq [index] == '+')
                {
                    AdditionTerm addition = new AdditionTerm(equation.GetPrevTerm((int)OperatorPriority.ADDITION));
                    equation.SetNextTerm(addition);
                }
                else if (eq [index] == '-' && constant == "")
                {
                    SubtractionTerm sub = new SubtractionTerm(equation.GetPrevTerm((int)OperatorPriority.SUBTRACTION));
                    equation.SetNextTerm(sub);
                }
                else if (eq [index] == 'l' && eq [index + 1] == 'n')
                {
                    NaturalLogTerm ln = new NaturalLogTerm();
                    equation.SetNextTerm(ln);
                    index += 1;
                }
                else if (eq [index] == 's' && eq [index + 1] == 'i' && eq [index + 2] == 'n')
                {
                    if (eq [index + 3] == 'h')
                    {
                        SinhTerm sin = new SinhTerm();
                        equation.SetNextTerm(sin);
                        index += 1;
                    }
                    else
                    {
                        SinTerm sin = new SinTerm();
                        equation.SetNextTerm(sin);
                    }
                    index += 2;
                }
                else if (eq [index] == 's' && eq [index + 1] == 'q' && eq [index + 2] == 'r' && eq [index + 3] == 't')
                {
                    SqrtTerm sqrt = new SqrtTerm();
                    equation.SetNextTerm(sqrt);
                    index += 3;
                }
                else if (eq [index] == 'c' && eq [index + 1] == 'o' && eq [index + 2] == 's')
                {
                    if (eq [index + 3] == 'h')
                    {
                        CoshTerm cosh = new CoshTerm();
                        equation.SetNextTerm(cosh);
                        index += 1;
                    }
                    else
                    {
                        CosTerm cos = new CosTerm();
                        equation.SetNextTerm(cos);
                    }
                    index += 2;
                }
                else if (eq [index] == 't' && eq [index + 1] == 'a' && eq [index + 2] == 'n')
                {
                    if (eq [index + 3] == 'h')
                    {
                        TanhTerm tanh = new TanhTerm();
                        equation.SetNextTerm(tanh);
                        index += 1;
                    }
                    else
                    {
                        TanTerm tan = new TanTerm();
                        equation.SetNextTerm(tan);
                    }
                    index += 2;
                }
                else if (eq [index] == 'p' && eq [index + 1] == 'i')
                {
                    ConstantTerm ct = new ConstantTerm(Math.PI);
                    equation.SetNextTerm(ct);
                    index += 1;
                }
                else if (eq [index] == 'x')
                {
                    XTerm xt = new XTerm();
                    equation.SetNextTerm(xt);
                }
                else if (eq [index] == 'e' && constant == "")
                {
                    ConstantTerm ct = new ConstantTerm(Math.E);
                    equation.SetNextTerm(ct);
                }
                else if (eq [index] == 'a')
                {
                    index += 1;
                    if (eq [index] == 's' && eq [index + 1] == 'i' && eq [index + 2] == 'n')
                    {
                        ASinTerm asin = new ASinTerm();
                        equation.SetNextTerm(asin);
                        index += 2;
                    }
                    else if (eq [index] == 'c' && eq [index + 1] == 'o' && eq [index + 2] == 's')
                    {
                        ACosTerm acos = new ACosTerm();
                        equation.SetNextTerm(acos);
                        index += 2;
                    }
                    else if (eq [index] == 't' && eq [index + 1] == 'a' && eq [index + 2] == 'n')
                    {
                        ATanTerm atan = new ATanTerm();
                        equation.SetNextTerm(atan);
                        index += 2;
                    }
                }
                else if (!addConstant)
                {
                    int start = index;
                    if (start > 5)
                    {
                        start -= 5;
                    }
                    else
                    {
                        start = 0;
                    }
                    int end = index;
                    if (end + 5 < eqText.Length)
                    {
                        end += 5;
                    }
                    else
                    {
                        end = eqText.Length - 1;
                    }
                    throw new ParsingException("Unable to parse equation at " + index +
                                               ". Unknown character near:" + eqText.Substring(start, end));
                }
            }
            if (!equation.IsComplete())
            {
                throw new ParsingException("Incomplete equation, maybe missing a term?");
            }
            return(equation);
        }
Beispiel #4
0
        private void OnGraphWindow(int windowId)
        {
            bool draw = false;

            GUILayout.BeginVertical();
            GUILayout.BeginHorizontal();
            GUILayout.Label("Lines", _labelStyle);
            if (GUILayout.Button("+", _buttonStyle) && _graphLineCnt < _lineColor.Length)
            {
                _graphLineCnt++;
            }
            if (GUILayout.Button("-", _buttonStyle) && _graphLineCnt > 1)
            {
                _graphLineCnt--;
                _graphPos.height = 0.0f;
                if (_graphLines.ContainsKey(_graphLineCnt))
                {
                    _graphLines.Remove(_graphLineCnt);
                }
                draw = true;
            }
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            bool lockX = GUILayout.Toggle(_lockX, "Lock X");

            if (lockX != _lockX)
            {
                _refreshGraph = true;
                _lockX        = lockX;
            }
            bool lockY = GUILayout.Toggle(_lockY, "Lock Y");

            if (lockY != _lockY)
            {
                _refreshGraph = true;
                _lockY        = lockY;
            }
            GUILayout.EndHorizontal();
            try {
                if (_lockX)
                {
                    GUILayout.BeginHorizontal();
                    string updated = "";
                    string minPos  = "XMin";
                    GUILayout.Label("Xmin:", _labelStyle, GUILayout.Width(40.0f));
                    GUI.SetNextControlName(minPos);
                    updated = GUILayout.TextField(
                        _graphLineEdit == -1 ? _xmin : GetValue(_xmin), _textFieldStyle,
                        GUILayout.MinWidth(40.0f));
                    if (GUI.GetNameOfFocusedControl() == minPos)
                    {
                        if (_graphLineEdit == -1 && updated != _xmin)
                        {
                            _xmin = updated;
                            draw  = true;
                        }
                        _graphLineEdit = -1;
                    }

                    GUILayout.Label("Xmax:", _labelStyle, GUILayout.Width(40.0f));
                    string maxPos = "XMax";
                    GUI.SetNextControlName(maxPos);
                    updated = GUILayout.TextField(
                        _graphLineEdit == -1 ? _xmax : GetValue(_xmax), _textFieldStyle,
                        GUILayout.MinWidth(40.0f));
                    if (GUI.GetNameOfFocusedControl() == maxPos)
                    {
                        if (_graphLineEdit == -1 && updated != _xmax)
                        {
                            _xmax = updated;
                            draw  = true;
                        }
                        _graphLineEdit = -1;
                    }
                    GUILayout.EndHorizontal();
                }
                for (int line = 0; line < _graphLineCnt; line++)
                {
                    if (!_graphLines.ContainsKey(line))
                    {
                        _graphLines.Add(line, new GraphLine());
                        _graphLines [line].LineColor = _lineColor [line];
                    }
                    GUILayout.BeginHorizontal();
                    GUIStyle  temp  = new GUIStyle(_labelStyle);
                    Texture2D color = new Texture2D(1, 1);
                    color.wrapMode = TextureWrapMode.Repeat;
                    color.SetPixel(0, 0, _graphLines [line].LineColor);
                    color.Apply();
                    temp.normal.background = color;
                    GUILayout.Label("", temp, GUILayout.Width(20.0f));
                    string cPos = "CG" + line;
                    GUI.SetNextControlName(cPos);
                    string updated = GUILayout.TextField(
                        _graphLines [line].Content, _textFieldStyle, GUILayout.MinWidth(150.0f));

                    if (GUI.GetNameOfFocusedControl() == cPos)
                    {
                        if (_graphLineEdit == line)
                        {
                            _graphLines [line].Content = updated;
                        }
                        _graphLineEdit = line;
                    }

                    if (!_lockX)
                    {
                        string minPos = "MinG" + line;
                        GUI.SetNextControlName(minPos);
                        updated = GUILayout.TextField(
                            _graphLineEdit == line ? _graphLines [line].XMin : GetValue(_graphLines [line].XMin), _textFieldStyle,
                            GUILayout.MinWidth(20.0f));
                        if (GUI.GetNameOfFocusedControl() == minPos)
                        {
                            if (_graphLineEdit == line)
                            {
                                _graphLines [line].XMin = updated;
                            }
                            _graphLineEdit = line;
                        }

                        string maxPos = "MaxG" + line;
                        GUI.SetNextControlName(maxPos);
                        updated = GUILayout.TextField(
                            _graphLineEdit == line ? _graphLines [line].XMax : GetValue(_graphLines [line].XMax), _textFieldStyle,
                            GUILayout.MinWidth(20.0f));
                        if (GUI.GetNameOfFocusedControl() == maxPos)
                        {
                            if (_graphLineEdit == line)
                            {
                                _graphLines [line].XMax = updated;
                            }
                            _graphLineEdit = line;
                        }
                    }
                    else
                    {
                        _graphLines [line].XMin = _xmin;
                        _graphLines [line].XMax = _xmax;
                    }
                    GUILayout.EndHorizontal();
                    if (_slider > 1e-2d)
                    {
                        GUILayout.BeginHorizontal();
                        GUILayout.Label("X:" + _graphLines[line].x.ToString("0.0###"), _labelStyle);
                        GUILayout.Label("Y:" + _graphLines[line].y.ToString("0.0###"), _labelStyle);
                        GUILayout.EndHorizontal();
                    }
                    draw = draw || _graphLines [line].Dirty;
                }
                float slider = GUILayout.HorizontalSlider(_slider, 0.0f, 300.0f);
                if (slider != _slider)
                {
                    _slider          = slider;
                    draw             = true;
                    _graphPos.height = 0.0f;
                }

                if (draw)
                {
                    _ymax = Double.NaN;
                    _ymin = Double.NaN;
                }
                if (draw || _refreshGraph)
                {
                    _refreshGraph = false;
                    _graph.reset();
                    for (int line = 0; line < _graphLineCnt; line++)
                    {
                        _graphLines[line].Dirty = false;

                        if (_graphLines [line].Content.Length == 0)
                        {
                            continue;
                        }
                        if (_graphLines [line].XMin.Length == 0)
                        {
                            continue;
                        }
                        if (_graphLines [line].XMax.Length == 0)
                        {
                            continue;
                        }

                        Equation equation = Equation.ParseEquation(EvalCell(_graphLines [line].Content));
                        Equation xmin     = Equation.ParseEquation(EvalCell(_graphLines [line].XMin));
                        Equation xmax     = Equation.ParseEquation(EvalCell(_graphLines [line].XMax));

                        double min = xmin.GetValue();
                        double max = xmax.GetValue();

                        double ymin = Double.NaN;
                        double ymax = Double.NaN;

                        if (max <= min || Double.IsNaN(max) || Double.IsNaN(min))
                        {
                            continue;
                        }

                        double delta = (max - min) / 300.0d;

                        int px = 0;
                        for (double x = min; x <= max; x += delta)
                        {
                            double y = equation.GetValue(x);
                            if (Double.IsNaN(y))
                            {
                                continue;
                            }
                            if (Double.IsNaN(ymin) || y < ymin)
                            {
                                ymin = y;
                            }
                            if (Double.IsNaN(ymax) || y > ymax)
                            {
                                ymax = y;
                            }
                            if (px == (int)_slider)
                            {
                                _graphLines[line].x = x;
                                _graphLines[line].y = y;
                            }
                            px++;
                        }

                        if (Double.IsNaN(_ymin) || ymin < _ymin)
                        {
                            _ymin         = ymin;
                            _refreshGraph = true;
                        }
                        if (Double.IsNaN(_ymax) || ymax > _ymax)
                        {
                            _ymax         = ymax;
                            _refreshGraph = true;
                        }
                        if (_lockY)
                        {
                            ymin = _ymin;
                            ymax = _ymax;
                        }
                        _graph.drawLineOnGraph(x => equation.GetValue(min + x * delta), ymax, ymin, 300,
                                               _graphLines [line].LineColor);
                    }
                    if (_slider > 1e-2d)
                    {
                        _graph.drawVerticalLine((int)_slider, Color.grey);
                    }
                    _graph.Apply();
                }
            } catch (Exception e) {
                Debug.Log(e.Message + "\n" + e.StackTrace);
            }
            if (_graph != null)
            {
                GUILayout.Label("Y max:" + _ymax.ToString("G10"), _labelStyle);
                GUILayout.Box(_graph.getImage());
                GUILayout.Label("Y min:" + _ymin.ToString("G10"), _labelStyle);
            }
            GUILayout.EndVertical();
            GUI.DragWindow();
        }