mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-29 06:12:18 -06:00
ScatterDraw: Improved user equations handling
git-svn-id: svn://ultimatepp.org/upp/trunk@11840 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
a27679e85c
commit
32e034bd0e
5 changed files with 73 additions and 25 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<String, double> 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<String> 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<String> varNames;
|
||||
EvalExpr eval;
|
||||
int idx;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#include "ScatterDraw.h"
|
||||
|
||||
#define TFILE <ScatterDraw/ScatterDraw.t>
|
||||
#include <Core/t.h>
|
||||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -943,6 +943,7 @@ private:
|
|||
bool labelsChanged;
|
||||
bool stacked;
|
||||
bool serializeFormat;
|
||||
int selectedSeries;
|
||||
};
|
||||
|
||||
template <class 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("")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue