osgEarth 2.1.1
|
Public Types | |
typedef std::pair< std::string, unsigned > | Variable |
typedef std::vector< Variable > | Variables |
Public Member Functions | |
NumericExpression () | |
NumericExpression (const Config &conf) | |
NumericExpression (const std::string &expr) | |
NumericExpression (double staticValue) | |
NumericExpression (const NumericExpression &rhs) | |
const Variables & | variables () const |
void | set (const Variable &var, double value) |
double | eval () const |
const std::string & | expr () const |
bool | empty () const |
Config | getConfig () const |
void | mergeConfig (const Config &conf) |
Private Types | |
enum | Op { OPERAND, VARIABLE, ADD, SUB, MULT, DIV, MOD, MIN, MAX, LPAREN, RPAREN, COMMA } |
typedef std::pair< Op, double > | Atom |
typedef std::vector< Atom > | AtomVector |
typedef std::stack< Atom > | AtomStack |
Private Member Functions | |
void | init () |
Private Attributes | |
std::string | _src |
AtomVector | _rpn |
Variables | _vars |
double | _value |
bool | _dirty |
Simple numeric expression evaluator with variables.
Definition at line 33 of file Expression.
typedef std::pair<Op,double> osgEarth::Symbology::NumericExpression::Atom [private] |
Definition at line 74 of file Expression.
typedef std::stack<Atom> osgEarth::Symbology::NumericExpression::AtomStack [private] |
Definition at line 76 of file Expression.
typedef std::vector<Atom> osgEarth::Symbology::NumericExpression::AtomVector [private] |
Definition at line 75 of file Expression.
typedef std::pair<std::string,unsigned> osgEarth::Symbology::NumericExpression::Variable |
Definition at line 36 of file Expression.
typedef std::vector<Variable> osgEarth::Symbology::NumericExpression::Variables |
Definition at line 37 of file Expression.
enum osgEarth::Symbology::NumericExpression::Op [private] |
osgEarth::Symbology::NumericExpression::NumericExpression | ( | ) | [inline] |
Definition at line 40 of file Expression.
{ }
NumericExpression::NumericExpression | ( | const Config & | conf | ) |
Definition at line 52 of file Expression.cpp.
{ mergeConfig( conf ); init(); }
NumericExpression::NumericExpression | ( | const std::string & | expr | ) |
NumericExpression::NumericExpression | ( | double | staticValue | ) |
NumericExpression::NumericExpression | ( | const NumericExpression & | rhs | ) |
bool osgEarth::Symbology::NumericExpression::empty | ( | ) | const [inline] |
double NumericExpression::eval | ( | ) | const |
Evaluate the expression.
Definition at line 199 of file Expression.cpp.
{ if ( _dirty ) { std::stack<double> s; for( unsigned i=0; i<_rpn.size(); ++i ) { const Atom& a = _rpn[i]; if ( a.first == ADD ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( op1 + op2 ); } } else if ( a.first == SUB ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( op1 - op2 ); } } else if ( a.first == MULT ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( op1 * op2 ); } } else if ( a.first == DIV ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( op1 / op2 ); } } else if ( a.first == MOD ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( fmod(op1, op2) ); } } else if ( a.first == MIN ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( std::min(op1, op2) ); } } else if ( a.first == MAX ) { if ( s.size() >= 2 ) { double op2 = s.top(); s.pop(); double op1 = s.top(); s.pop(); s.push( std::max(op1, op2) ); } } else // OPERAND or VARIABLE { s.push( a.second ); } } const_cast<NumericExpression*>(this)->_value = s.size() > 0 ? s.top() : 0.0; const_cast<NumericExpression*>(this)->_dirty = false; } return !osg::isNaN( _value ) ? _value : 0.0; }
const std::string& osgEarth::Symbology::NumericExpression::expr | ( | ) | const [inline] |
Config NumericExpression::getConfig | ( | ) | const |
Definition at line 67 of file Expression.cpp.
void NumericExpression::init | ( | ) | [private] |
Definition at line 75 of file Expression.cpp.
{ _vars.clear(); _rpn.clear(); StringTokenizer tokenizer( "", "'\"" ); tokenizer.addDelims( "[],()%*/+-", true ); tokenizer.keepEmpties() = false; StringVector t; tokenizer.tokenize( _src, t ); //tokenize(_src, t, "[],()%*/+-", "'\"", false, true); // identify tokens: AtomVector infix; bool invar = false; for( unsigned i=0; i<t.size(); ++i ) { if ( t[i] == "[" && !invar ) { invar = true; } else if ( t[i] == "]" && invar ) { invar = false; infix.push_back( Atom(VARIABLE,0.0) ); _vars.push_back( Variable(t[i-1],0) ); } else if ( t[i] == "(" ) infix.push_back( Atom(LPAREN,0.0) ); else if ( t[i] == ")" ) infix.push_back( Atom(RPAREN,0.0) ); else if ( t[i] == "," ) infix.push_back( Atom(COMMA,0.0) ); else if ( t[i] == "%" ) infix.push_back( Atom(MOD,0.0) ); else if ( t[i] == "*" ) infix.push_back( Atom(MULT,0.0) ); else if ( t[i] == "/" ) infix.push_back( Atom(DIV,0.0) ); else if ( t[i] == "+" ) infix.push_back( Atom(ADD,0.0) ); else if ( t[i] == "-" ) infix.push_back( Atom(SUB,0.0) ); else if ( t[i] == "min" ) infix.push_back( Atom(MIN,0.0) ); else if ( t[i] == "max" ) infix.push_back( Atom(MAX,0.0) ); else if ( (t[i][0] >= '0' && t[i][0] <= '9') || t[i][0] == '.' ) infix.push_back( Atom(OPERAND,as<double>(t[i],0.0)) ); // note: do nothing for a comma } // convert to RPN: // http://en.wikipedia.org/wiki/Shunting-yard_algorithm AtomStack s; unsigned var_i = 0; for( unsigned i=0; i<infix.size(); ++i ) { Atom& a = infix[i]; if ( a.first == LPAREN ) { s.push( a ); } else if ( a.first == RPAREN ) { while( s.size() > 0 ) { Atom top = s.top(); s.pop(); if ( top.first == LPAREN ) break; else _rpn.push_back( top ); } } else if ( a.first == COMMA ) { while( s.size() > 0 && s.top().first != LPAREN ) { _rpn.push_back( s.top() ); s.pop(); } } else if ( IS_OPERATOR(a) ) { if ( s.empty() || a.first > s.top().first ) { s.push( a ); } else { while( s.size() > 0 && a.first < s.top().first && IS_OPERATOR(s.top()) ) { _rpn.push_back( s.top() ); s.pop(); } s.push( a ); } } else if ( a.first == MIN || a.first == MAX ) { s.push( a ); } else if ( a.first == OPERAND ) { _rpn.push_back( a ); } else if ( a.first == VARIABLE ) { _rpn.push_back( a ); _vars[var_i++].second = _rpn.size()-1; // store the index } } while( s.size() > 0 ) { _rpn.push_back( s.top() ); s.pop(); } }
void NumericExpression::mergeConfig | ( | const Config & | conf | ) |
void NumericExpression::set | ( | const Variable & | var, |
double | value | ||
) |
Set the value of a variable.
Definition at line 188 of file Expression.cpp.
const Variables& osgEarth::Symbology::NumericExpression::variables | ( | ) | const [inline] |
Access the expression variables.
Definition at line 54 of file Expression.
{ return _vars; }
bool osgEarth::Symbology::NumericExpression::_dirty [private] |
Definition at line 82 of file Expression.
Definition at line 79 of file Expression.
std::string osgEarth::Symbology::NumericExpression::_src [private] |
Definition at line 78 of file Expression.
double osgEarth::Symbology::NumericExpression::_value [private] |
Definition at line 81 of file Expression.
Definition at line 80 of file Expression.