diff --git a/uppsrc/ScatterDraw/Equation.cpp b/uppsrc/ScatterDraw/Equation.cpp index 39e657fb7..7069f5cf7 100644 --- a/uppsrc/ScatterDraw/Equation.cpp +++ b/uppsrc/ScatterDraw/Equation.cpp @@ -167,20 +167,29 @@ double EvalExpr::Term(CParser& p) { return p.ReadDouble(); } -double EvalExpr::Mul(CParser& p) { +double EvalExpr::Pow(CParser& p) { double x = Term(p); - for(;;) + for(;;) { + if(p.Char('^')) + x = pow(x, Term(p)); + else + return x; + } +} + +double EvalExpr::Mul(CParser& p) { + double x = Pow(p); + for(;;) { if(p.Char('*')) x = x * Mul(p); else if(p.Char('/')) { - double y = Mul(p); + double y = Pow(p); if(y == 0) p.ThrowError(t_("Divide by zero")); x = x / y; - } else if(p.Char('^')) - x = pow(x, Mul(p)); - else + } else return x; + } } double EvalExpr::Exp(CParser& p) { @@ -254,15 +263,22 @@ String EvalExpr::TermStr(CParser& p, int numDigits) { return FormatDoubleFix(p.ReadDouble(), IsNull(numDigits) ? 3 : numDigits); } -String EvalExpr::MulStr(CParser& p, int numDigits) { +String EvalExpr::PowStr(CParser& p, int numDigits) { String x = TermStr(p, numDigits); + for(;;) + if(p.Char('^')) + x = x + "^" + TermStr(p, numDigits); + else + return x; +} + +String EvalExpr::MulStr(CParser& p, int numDigits) { + String x = PowStr(p, numDigits); for(;;) if(p.Char('*')) x = x + "*" + MulStr(p, numDigits); else if(p.Char('/')) - x = x + "/" + MulStr(p, numDigits); - else if(p.Char('^')) - x = x + "^" + MulStr(p, numDigits); + x = x + "/" + PowStr(p, numDigits); else return x; } diff --git a/uppsrc/ScatterDraw/Equation.h b/uppsrc/ScatterDraw/Equation.h index e175a9cbe..bff44cad2 100644 --- a/uppsrc/ScatterDraw/Equation.h +++ b/uppsrc/ScatterDraw/Equation.h @@ -214,19 +214,35 @@ public: String EvalStr(String line, int numDigits = 3); void SetCaseSensitivity(bool val = true) {noCase = !val;} - VectorMap constants; - VectorMap variables; + const String &GetFunction(int id) {return functions.GetKey(id);} + int GetFunctionsCount() {return functions.GetCount();} + + void SetConstant(String name, double value = 0) {constants.GetAdd(name, value);} + void SetConstant(int id, double value = 0) {constants[id] = value;} + double GetConstant(String name) {return constants.Get(name, Null);} + void GetConstant(int id, String &name, double &value) {name = constants.GetKey(id); value = constants[id];} + int GetConstantsCount() {return constants.GetCount();} + + void SetVariable(String name, double value = 0) {variables.GetAdd(name, value);} + void SetVariable(int id, double value = 0) {variables[id] = value;} + double GetVariable(String name) {return variables.Get(name, Null);} + void GetVariable(int id, String &name, double &value) {name = variables.GetKey(id); value = variables[id];} + int GetVariablesCount() {return variables.GetCount();} private: void *Functions_Get(CParser& p); double Term(CParser& p); + double Pow(CParser& p); double Mul(CParser& p); double Exp(CParser& p); String TermStr(CParser& p, int numDigits); + String PowStr(CParser& p, int numDigits); String MulStr(CParser& p, int numDigits); String ExpStr(CParser& p, int numDigits); bool noCase; + VectorMap constants; + VectorMap variables; VectorMap functions; }; @@ -237,15 +253,15 @@ public: void Init(String _name, String _strEquation, String varHoriz = "x") { name = _name; strEquation = _strEquation; - eval.constants.GetAdd(varHoriz); - idx = eval.constants.GetCount() - 1; + eval.SetConstant(varHoriz); + idx = eval.GetConstantsCount() - 1; eval.EvalStr(strEquation); - coeff.SetCount(eval.variables.GetCount()); + coeff.SetCount(eval.GetVariablesCount()); } double f(double x) { - eval.constants[idx] = x; + eval.SetConstant(idx, x); for (int i = 0; i < coeff.GetCount(); ++i) - eval.variables[i] = coeff[i]; + eval.SetVariable(i, coeff[i]); return eval.Eval(strEquation); } String SetName(String _name) {name = _name;}