|
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();
}
Here is the call graph for this function:| 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;
}
Here is the caller graph for this function:| 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();
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| 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.
Here is the caller graph for this function:| const Variables& osgEarth::Symbology::NumericExpression::variables | ( | ) | const [inline] |
Access the expression variables.
Definition at line 54 of file Expression.
{ return _vars; }
Here is the caller graph for this function: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.
1.7.3