Function parser for OpenSCAD and parametric curve grapher
by arpruss, published
Liked ByView All
Give a Shout Out
If you print this Thing and display it in public proudly give attribution by printing and displaying this tag.Print Thing Tag
One of the OpenSCAD limitations is the inability to pass functions to functions or modules.
This library lets you define mathematical functions in a string, using all of the OpenSCAD mathematical operators (and a bit more). This string is then compiled to an optimized representation which can be evaluated fairly quickly. For instance:
use <eval.scad>; f = "pow(x,3)*y-x*cos(y)+y"; fc = compileFunction(f); echo(eval(fc, [["x", 12], ["y", -5]]));
will evaluate the function at x=12 and y=-5.
Parsing the string is not fast, but if you evaluate the compiled function for different variable values, the evaluated function should be fairly fast (in my test, about 10,000
eval()s per second).
There are three public functions provided:
compileFunction(f): takes a function string
fand returns an optimized compiled representation; the representation is described here: http://www.thingiverse.com/thing:2289738
There may be some bugs in the optimization. If you run into problems, add the optional argument
eval(fc, variables): takes a compiled function
fcand evaluates it for the specified parameter values;
variablesis a vector of
[variableName, value]pairs; for instance,
evaluateFunction(expression, variables): use this to evaluate an uncompiled function once; this is a convenience function equivalent to
eval(compileFunction(expression,optimize=false),variables); if you are going to evaluate the function more than a couple of times, please compile it once first, and then call
eval()on the compiled version
The string function representations should be able to use all of the following standard OpenSCAD language elements:
+ - * / % pow sqrt cos sin tan acos asin atan atan2 abs ceil exp floor ln log round sign PI cross norm max min concat let ?: != == >= <= < > ! && ||
Vectors are supported, using
[x,y,z] style vector forming and
Numbers can be specified in the usual way, and the
false constants are available.
^ infix operator is provided as a shorthand for
ATAN2 are provided which are radian-based trigonometric functions.
There are likely multiple bugs I have yet to catch, and there may be some subtle deviations from OpenSCAD order of operations.
The demo file is a 3D parametric curve grapher. You should be able to use the Customizer (unless it times out) to change the formula.
On my i5 based Windows 10 laptop, per 10,000 runs with
compileFunction()with optimization: 25 seconds
compileFunction()without optimization: 21 seconds
eval()applied to precompiled function: 0.8 seconds
Note: As I update eval.scad, I will upload new versions here. However, I will not be regularly updating the version inside the demo file. There is a repository here:
- May 6, 2017: No longer distinguish the "fast" variables x,y,z,t from the others. Remove dollar sign operator for variable values in compiled form now that I've discovered a fast check for whether something is a string.
- May 16, 2017: Fix evaluator bug in some functions like
- May 17, 2017:
evaluateFunction()should now work if fed in an already-compiled function; in that case,
compileFunction()returns its input and
evaluateFunction()is the same as
eval(); this means that you can seamlessly support compiled and uncompiled function arguments in the same module; I also removed a warning when optimizing a function that uses
- May 18, 2017:
Upgrade this Thing with Thingiverse AppsCustomization
Edit, personalize, or revise this ThingPrint Fulfilment
Order a print of this ThingTools and Utilities
Repair, slice, or enhance this Thing
Function parser for OpenSCAD and parametric curve grapher by arpruss is licensed under the Creative Commons - Attribution license.
What does this mean?
- You must attribute (give credit) to the creator of this Thing.
- Remixing or Changing this Thing is allowed.
- Commercial use is allowed.
Show Some Love
Say thanks by giving arpruss a tip and help them continue to share amazing Things with the Thingiverse community.Tip Designer
We're sure arpruss would love to see what you've printed. Please document your print and share a Make with the community.
To post a Make simply visit this Thing again and click I Made One to start uploading your photo. It’s even easier to post a Make via the Thingiverse Mobile app (available via Google Play and Apple App Store).