Mathematical Expression Evaluator
Posted on January 14, 2015
Our latest addition to the Murl Engine is a practical mathematical expression evaluator. The evaluator allows you to specify a mathematical expression as parameter value in resource XML files. (updated 24.05.2015)
The ability to use mathematical expressions instead of fixed values is often very beneficial.
You can set up graph objects directly within XML graph resource files without the need of additional C++ code.
This is especially useful when you are working with instance replications.
For instance, the feature image shows an example where a mathematical expression is used to align some PlaneGeometry
objects along a heart shaped path.
To specify a mathematical expression, enclose the expression in curly braces. This is the same notation as with passed attribute values. Here is a simple example:
<PlaneGeometry id="plane_{replication}" posX="{replication*10}" posY="0"/>
Combining Expressions
A sequence of expressions can be defined by using a semicolon separated list. The last expression is assigned to the attribute, e.g.:
<PlaneGeometry posX="{R=400;r=100;b=65;t=replication*0.01;(R-r)*Sin(t)-b*Sin((R-r)/r*t)}" />
It is also possible to nest expressions which will result in a separate evaluation for each nested expression:
<PlaneGeometry posX="{{2*3}+6}}" />
Datatypes
The evaluator supports the following data types:
Double, SInt32, Bool, StringThe correct data type is determined automatically. An explicit type conversion can be done in functional notation:
<PlaneGeometry posX="{SInt32(replication*0.1)}" />
To specify a String
, enclose the characters in single quotes:
<Node id="{'ab'+String('c')+BoolToString(1)}" />
The result for the expression above would be:
abctrueConditional statements
The if
function can be used for conditional if/else expressions.
<PlaneGeometry posX="{if(replication > 10, 100, 0)}" />
A C++ equivalent for this expression would be:
if (replication > 10) { posX = 100; } else { posX = 0; }
Alternatively the switch
function can be used to create a conditional expression.
The switch
function expects a condition parameter followed by a number of case parameters.
The condition parameter is clamped to the range [0, number_of_case_parameters-1]. Example:
<PlaneGeometry posX="{switch(replication * 0.1, 100, 200, 50)}" />
In this example the condition parameter is clamped to the range [0,2]. Therefore 100 is assigned to instances 0 to 9, 200 to instances 10 to 19 and 50 to all others.
Equivalent C++ code for the expression above would be:
SInt32 condition = SInt32(replication * 0.1) if (condition < 0) { condition = 0; } switch(condition) { case 0: posX = 100; break; case 1: posX = 200; break; default: posX = 50; }
Random Number Generator
A global Random Number Generator (RNG) is provided to allow the usage of random numbers.
The RNG is always initialised with the same seed value and therefore is always generating the same sequence of numbers. The function Seed(value)
can be used to set a new seed value.
The function Seed()
without parameters uses the current system time as seed value.
<Instance graphResourceId="graph_plane" replications="{Seed(42);10}"/>
For example, RandSInt(start, end)
can be used to draw a new random number.
<PlaneGeometry posX="{replication*10}" posY="{RandSInt(-100,100)}" />
C++ Default Parameters
You can define global default parameters in the IApp::Configure()
method and read those parameters in your mathematical expression.
The method GetDefaultGraphParameters()
has been added to the IEngineConfiguration
class for that purpose.
Bool App::MyApp::Configure(IEngineConfiguration* engineConfig, IFileInterface* fileInterface) { IAttributes* defaultParameters = engineConfig->GetDefaultGraphParameters(); defaultParameters->AddAttribute("myPosParam","42"); … }
The new default parameter can be read as every other variable:
<PlaneGeometry posX="{myPosParam}" />
Available Operators, Functions and Constants
The following list contains all available operators, functions and constants.
The usage is the same as for the corresponding C++ equivalents.
For String
functions the first parameter needs to be the String
where the method should be applied.
Operators:
+, -, *, /, % (Addition, subtraction, multiplication, division, modulo) <<, >> (Shift operators) &, |, ^, ~ (Bitwise AND, OR, XOR, NOT) &&, ||, ^^, ! (Logical AND, OR, XOR, NOT) = (Assignment) ==, !=, <, <=, >, >= (Relational operators) # (Comment operator)
Constants:
E, PI, TWO_PI, HALF_PI, INV_PI, INV_TWO_PI, INV_HALF_PI, DEG_TO_RAD, RAD_TO_DEG, MM_TO_CM, CM_TO_MM, MM_TO_INCHES, CM_TO_INCHES, INCHES_TO_MM, INCHES_TO_CMConditional Functions:
if, switchMath Functions (Murl::Math):
Abs, Sgn, Min, Max, Clamp, IsNaN, IsInfinite, IsFinite, Exp, Log, Log2, Log10, Sqrt, Pow, Fmod, Sin, Cos, Tan, ArcSin, ArcCos, ArcTan, ArcTan2, SinHyp, CosHyp, TanHyp, ArcSinHyp, ArcCosHyp, ArcTanHyp, Floor, Ceil, Round, IsEqual, DegToRad, RadToDeg, MapAngle, AddAngle, SubAngle, Lerp, InterpolationString Functions (Murl::String):
GetLength, Trim, TrimLeft, TrimRight, Left, Right, Mid, ToLowerUTF8, ToUpperUTF8, GetLengthUTF8, Replace, Find, ReverseFind, FindFirstOf, FindFirstNotOf, StartsWith, EndsWith, CompareExplicit Type Conversion:
SInt32, Double, Bool, StringConversion Functions (Murl::Util):
StringToDouble, StringToSInt32, StringToBool, DoubleToString, SInt32ToString, BoolToStringRandom Number Generator (Murl::Util::Rng):
Seed, Rand, RandBool, RandSInt, RandReal, RandDouble
Note
Please note that the following characters should be escaped in XML files:
Don't miss out on any update,
subscribe to our newsletter.