From 32e034bd0e91cc6ddcdae5e48394fc85e2de1a3d Mon Sep 17 00:00:00 2001 From: koldo Date: Sat, 17 Mar 2018 09:29:19 +0000 Subject: [PATCH] ScatterDraw: Improved user equations handling git-svn-id: svn://ultimatepp.org/upp/trunk@11840 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ScatterDraw/Equation.cpp | 23 +++++++----- uppsrc/ScatterDraw/Equation.h | 60 +++++++++++++++++++++++------- uppsrc/ScatterDraw/ScatterDraw.cpp | 4 ++ uppsrc/ScatterDraw/ScatterDraw.h | 1 + uppsrc/ScatterDraw/ScatterDraw.t | 10 ++++- 5 files changed, 73 insertions(+), 25 deletions(-) diff --git a/uppsrc/ScatterDraw/Equation.cpp b/uppsrc/ScatterDraw/Equation.cpp index 4c2705ab6..a22a3149d 100644 --- a/uppsrc/ScatterDraw/Equation.cpp +++ b/uppsrc/ScatterDraw/Equation.cpp @@ -89,6 +89,8 @@ int ExplicitEquation::maxFitFunctionEvaluations = 1000; double PolynomialEquation::f(double x) { + if (x < 0) + return Null; double y = 0; for (int i = 0; i < coeff.GetCount(); ++i) y += coeff[i]*pow(x, i); @@ -133,8 +135,8 @@ String FourierEquation::GetEquation(int numDigits) { return ret; } -static double DegToRad(double deg) {return deg*M_PI/180.;} -static double RadToDeg(double rad) {return rad*180./M_PI;} +static inline double DegToRad(double deg) {return deg*M_PI/180.;} +static inline double RadToDeg(double rad) {return rad*180./M_PI;} void EvalExpr::EvalThrowError(CParser &p, const char *s) { CParser::Pos pos = p.GetPos(); @@ -152,8 +154,7 @@ EvalExpr::EvalExpr() { noCase = false; errorIfUndefined = false; - constants.Add("PI", M_PI); - constants.Add("M_PI", M_PI); + constants.Add("pi", M_PI); constants.Add("e", M_E); functions.Add("abs", fabs); @@ -190,7 +191,7 @@ double EvalExpr::Term(CParser& p) { } String strsearch; if (noCase) - strsearch = ToUpper(strId); + strsearch = ToLower(strId); else strsearch = strId; double ret = constants.Get(strsearch, Null); @@ -198,7 +199,7 @@ double EvalExpr::Term(CParser& p) { ret = variables.Get(strsearch, Null); if (IsNull(ret)) { if (errorIfUndefined) - EvalThrowError(p, Format(t_("Unknown var '%s'"), strId)); + EvalThrowError(p, Format(t_("Unknown identifier '%s'"), strId)); ret = variables.GetAdd(strsearch, 0); } } @@ -214,9 +215,11 @@ double EvalExpr::Term(CParser& p) { double EvalExpr::Pow(CParser& p) { double x = Term(p); for(;;) { - if(p.Char('^')) + if(p.Char('^')) { + if (x < 0) + EvalThrowError(p, t_("Complex number")); x = pow(x, Term(p)); - else + } else return x; } } @@ -263,7 +266,7 @@ double EvalExpr::Eval(String line) { if(p.Char('=')) { double ret = Exp(p); if (noCase) - var = ToUpper(var); + var = ToLower(var); variables.GetAdd(var) = ret; return ret; } else { @@ -289,7 +292,7 @@ String EvalExpr::TermStr(CParser& p, int numDigits) { return strId + "(" + x + ")"; } if (noCase) - strId = ToUpper(strId); + strId = ToLower(strId); if (IsNull(numDigits)) { if (constants.Find(strId) < 0) variables.GetAdd(strId, 0); diff --git a/uppsrc/ScatterDraw/Equation.h b/uppsrc/ScatterDraw/Equation.h index a54383878..43ad35710 100644 --- a/uppsrc/ScatterDraw/Equation.h +++ b/uppsrc/ScatterDraw/Equation.h @@ -99,7 +99,9 @@ class LinearEquation : public ExplicitEquation { public: LinearEquation() {SetCoeff(0, 0);} LinearEquation(double c0, double c1){SetCoeff(c0, c1);} - double f(double x) {return coeff[0] + x*coeff[1];} + double f(double x) { + return coeff[0] + x*coeff[1]; + } virtual String GetName() {return t_("Linear");} virtual String GetEquation(int numDigits = 3) { String ret = Format("%s + %s*x", FormatCoeff(0, numDigits), FormatCoeff(1, numDigits)); @@ -278,7 +280,11 @@ class RealExponentEquation : public ExplicitEquation { public: RealExponentEquation() {SetCoeff(1, 1);} RealExponentEquation(double a, double b) {SetCoeff(a, b);} - double f(double x) {return coeff[0]*pow(x, coeff[1]);} + double f(double x) { + if (x < 0) + return Null; + return coeff[0]*pow(x, coeff[1]); + } virtual String GetName() {return t_("RealExponent");} virtual String GetEquation(int numDigits = 3) { String ret = Format("%s*x^%s", FormatCoeff(0, numDigits), FormatCoeff(1, numDigits)); @@ -334,15 +340,15 @@ public: 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(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(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);} + double GetVariable(String name) {return variables.GetAdd(name);} void GetVariable(int id, String &name, double &value) {name = variables.GetKey(id); value = variables[id];} int GetVariablesCount() {return variables.GetCount();} void ClearVariables(); @@ -353,7 +359,7 @@ public: CParser p; -static void EvalThrowError(CParser &p, const char *s); + static void EvalThrowError(CParser &p, const char *s); protected: double Exp(CParser& p); @@ -363,6 +369,9 @@ protected: VectorMap variables; bool errorIfUndefined; + bool IsFunction(String str) {return functions.Get(str, 0);} + bool IsConstant(String str) {return !IsNull(GetConstant(str));} + private: void *Functions_Get(CParser& p); double Term(CParser& p); @@ -381,22 +390,46 @@ public: UserEquation(String _name, String _strEquation, String varHoriz = "x") {Init(_name, _strEquation, varHoriz);} void Init(String _name, String _strEquation, String varHoriz = "x") { name = _name; - strEquation = _strEquation; + _strEquation.Replace(" ", ""); + StringStream str(_strEquation); + Vector parts = GetCsvLine(str, ';', CHARSET_DEFAULT); + if (parts.IsEmpty()) + return; + strEquation = parts[0]; eval.Init(); eval.SetConstant(varHoriz); idx = eval.GetConstantsCount() - 1; eval.EvalStr(strEquation); - coeff.SetCount(eval.GetVariablesCount()); - for (int i = 0; i < coeff.GetCount(); ++i) - coeff[i] = 0.1; + coeff.Clear(); + varNames.Clear(); + for (int i = 0; i < eval.GetVariablesCount(); ++i) { + String varName; + double dummy; + eval.GetVariable(i, varName, dummy); + varNames << varName; + int istr; + for (istr = 1; istr < parts.GetCount(); ++istr) { + String strVar = varName + "="; + int ifound = parts[istr].Find(strVar); + if (ifound >= 0) { + double val = ScanDouble(parts[istr].Mid(strVar.GetCount())); + coeff << val; + break; + } + } + if (istr == parts.GetCount()) + coeff << 0.1; + } } double f(double x) { eval.SetConstant(idx, x); - for (int i = 0; i < coeff.GetCount(); ++i) - eval.SetVariable(i, coeff[i]); + for (int i = 0; i < coeff.GetCount(); ++i) { + eval.SetVariable(varNames[i], coeff[i]); + double ret = eval.GetVariable(varNames[i]); + } return eval.Eval(strEquation); } - void SetName(String _name) {name = _name;} + void SetName(String _name) {name = _name;} virtual String GetName() {return name;} virtual String GetEquation(int numDigits = 3) {return eval.EvalStr(strEquation, numDigits);} virtual void GuessCoeff(DataSource &series) {} @@ -405,6 +438,7 @@ public: private: String name; String strEquation; + Vector varNames; EvalExpr eval; int idx; }; diff --git a/uppsrc/ScatterDraw/ScatterDraw.cpp b/uppsrc/ScatterDraw/ScatterDraw.cpp index 7a25e1028..40f6b73e2 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.cpp +++ b/uppsrc/ScatterDraw/ScatterDraw.cpp @@ -1,5 +1,8 @@ #include "ScatterDraw.h" +#define TFILE +#include + ScatterDraw& ScatterDraw::SetColor(const Color& _color) { graphColor = _color; return *this; @@ -1943,6 +1946,7 @@ ScatterDraw::ScatterDraw() { stacked = false; serializeFormat = true; mouseHandlingX = mouseHandlingY = false; + selectedSeries = Null; } void DrawLine(Draw &w, double x0, double y0, double x1, double y1, double width, const Color &color) { diff --git a/uppsrc/ScatterDraw/ScatterDraw.h b/uppsrc/ScatterDraw/ScatterDraw.h index e1379b1da..7a34607f3 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.h +++ b/uppsrc/ScatterDraw/ScatterDraw.h @@ -943,6 +943,7 @@ private: bool labelsChanged; bool stacked; bool serializeFormat; + int selectedSeries; }; template diff --git a/uppsrc/ScatterDraw/ScatterDraw.t b/uppsrc/ScatterDraw/ScatterDraw.t index bdeef36ef..b7ce74928 100644 --- a/uppsrc/ScatterDraw/ScatterDraw.t +++ b/uppsrc/ScatterDraw/ScatterDraw.t @@ -24,9 +24,15 @@ esES("Error en %s(%f)") euES("") frFR("") -T_("Unknown var '%s'") +T_("Unknown identifier '%s'") caES("") -esES("Variable '%s' desconocida") +esES("Identificador desconocido '%s'") +euES("") +frFR("") + +T_("Complex number") +caES("") +esES("N\303\272mero complejo") euES("") frFR("")