LaserBoy Liquid Math (Language)
is an animated 3D color vector function graphing calculator in plain ascii text.
It is a subset of the LaserBoy ascii text format.
Everything within this subset begins with the keyword:
math
It has two internal registers, A and B that hold whole "frame_sets" of 3D real_number color vector art (framed animations).
All of the math that makes this work is in double precision floating point numbers.
There is a set of pre-defined variables that can be changed from their default values. These "parameters" are used in a series of functions that "generate" either a single frame or an entire animated frame_set.
This is how a frame_set gets loaded into a register (A or B).
It is also possible to load frame_sets from importing dxf, LaserBoy_txt or whatever is loaded in "LaserBoy_space" (the running application) before opening the LaserBoy_txt file.
There is a set of functions that "operate" on whatever is in these registers (A and B).
Some of the operators are unary. So they push B to A and leave the result of ƒ(B) in B.
C = ƒ(B)
delete A
A = B
B = C
Some of the operators are binary and calculate the expression A ƒ B, push B to A and leave the result of A ƒ B in B.
C = A ƒ B
delete A
A = B
B = C
The "result" of a generator or operator is typically in B, unless it is the first instruction that puts a frame_set into empty registers which goes in A. When an instruction pushes B to A the previous frame_set in A is deleted. C in the expressions above is temporary and has no meaning after an instruction is complete.
This result can be rendered into LaserBoy_space, saved as txt, dxf or bitmaps.
It can also be stored in a "list" of frame_sets and later recalled and loaded into B for further calculations, pushing the previous B to A.
Multiple frame_sets in this list can be combined into one frame_set and rendered into LaserBoy_space, saved as txt, dxf or bitmaps.
Once a math generated frame_set is loaded into LaserBoy_space, it is in signed short integers and can be saved as ILDA, or optimized wave.
All of the generators that calculate the contents of a frame or frame_set are based on the values of a set of named parameters. All of these parameters have default values and only changes in their values need to be indicated in the txt before calling any of the generators that use them.
A generator that populates a single frame is calculated over an interval from "start" to start + "duration" in "iterations" steps (vertices in the frame).
Some of the generators that populate frames are different types of cycloids (Spirograph). These use the parameters:
rhodonea_numerator
rhodonea_denominator
fixed_radius
roller_radius
roller_offset
Many of the generators use objects of the class LaserBoy_oscillator. An "LBO" is a function itself. It is modeled from the function sin(t) where t is on the interval.
There are six numbered LOBs and each one has four posible "positions" in the generators that use them.
Each LBO has a set of parameters:
function
amplitude
frequency
phase
duty_cycle
damping
offset
Which are used in the expression:
LBO(t) == amplitude * function(t * frequency + phase) * e ^ (-damping / t) + offset
duty_cycle is a parameter that has no representation in the above expression. It actually changes the character of function. The value of duty_cycle must be between 0.0 and 1.0. A value of 0.5 is 50%. The sin function has 50% above and 50% below its zero value.
By default all LBOs have the values that make them behave like the standard sin(t) function.
math LBO1 function sin
math LBO1 amplitude 1.0
math LBO1 frequency 1.0
math LBO1 phase 0.0
math LBO1 duty_cycle 0.5
math LBO1 damping 0.0
math LBO1 offset 0.0
There are three factors that determin the units of one rotation or period. One trip around the unit circle is 0.0 to two_pi radians. But this period can be expressed in degrees (0.0 to 360.0) or in periods of two_pi, whole rotations (0.0 to 1.0). Values for phase can be in degrees. Angular rotations can be written in numbers of whole rotations and the start and duration of the interval on the real number line can be in units of whole periods as well.
math phase_cycle 360.0
math rotation_cycle 1.0
math interval_cycle 1.0
The values of start and duration are relative to interval_cycle.
(actual_value_in_radians) = start * (two_pi / interval_cycle)
(actual_value_in_radians) = duration * (two_pi / interval_cycle)
To calculate just one oscillator itself over the interval using all default values of:
math start 0.0
math duration 1.0
math iterations 100
All that needs to be noted in text is:
math oscillator
math render
This alone in LaserBoy_txt will create a frame set of a single frame with the sin function calculated in 100 iterations from 0.0 to two_pi.
The line "math render" is the instruction that takes the real number frame_set in the register (result) and renders it into LaserBoy_space (the running application's frame_set) in scaled, signed short integer.
Since the generator "oscillator" only uses one LBO it is LBO1. The numbered LBOs are always used in the order they appear in the expression of the generator. There are generators that use 1, 2, 3, 4 or 6 of them in various expressions that may result in 2D or 3D vector line figures.
LBO1 through LBO6 exist for a set of generators that use up to that amount of LBOs.
The parameter "function" of an LBO can be any one of:
math LBO1 function sin
math LBO1 function triangle
math LBO1 function ramp
math LBO1 function square
math LBO1 function pulse
math LBO1 function trapeziod
math LBO1 function circle
Each of these is a kind of drop-in replacement for the notion of the sin function. All of them have a duty_cycle that changes their characteristic shape.
The "function" of an LBO can be set to one of these pure, named wave-forms or it can be a mix of any of them. Each LBO has a mixer for the outputs of each function type designated by its name in the mixer. These are the default values:
math LBO1 sin 1.0
math LBO1 triangle 0.0
math LBO1 ramp 0.0
math LBO1 square 0.0
math LBO1 pulse 0.0
math LBO1 trapeziod 0.0
math LBO1 circle 0.0
Setting the "function" parameter of an LBO with a named wave_from will set the coresponding mixer level to 1.0 and all others to 0.0. Setting multiple values of the mixer must be done after that to achieve a blend of function outputs. Function mixer values must be between 0.0 and 1.0. The blend is calculated to always normalize to 1.0 such that:
total = sin
+ triangle
+ ramp
+ square
+ pulse
+ trapeziod
+ circle
output = (sin / total) * sin_output (t)
+ (triangle / total) * triangle_output (t)
+ (ramp / total) * ramp_output (t)
+ (square / total) * square_output (t)
+ (pulse / total) * pulse_output (t)
+ (trapeziod / total) * trapeziod_output (t)
+ (circle / total) * circle_output (t)
again, where t is in the interval.
The mixer is a balance between all the wave-form outputs. It always normalizes to unity. It is not a means of controling the amplitude of the output. A mixer state of all 0.0 values is not valid and will cause an error report.
The generator "oscillator" calculates one single frame in a frame_set.
Animation in this notation is acheived by defining two sets of parameters; initial and final.
math frames 3
Number of frames is also a parameter. When LaserBoy calculates a generator that produces an animated set of frames it uses linear interpolation to find all of the frames in between the initial and the final sets of parameters. The default value of "frames" is 3. This results in three frames in the frame_set. The first is 100% initial values. The last is 100% final values and the middle is half way in between.
There is a set of six initial state oscillators and a set of six final state oscillators that are used by all the generators that calculate animated frame_sets using LaserBoy oscillators. The set of initial oscillators are the same ones used in the generators that calculate a single frame. The set of final oscillators are named with an underscore as the first character.
_LBO1
_LBO2
_LBO3
_LBO4
_LBO5
_LBO6
There are final state parameters for start, duration and iterations as well.
_start
_duration
_iterations
Every generator that makes animated frame_sets requires all of the parameters of its single frame counterpart, plus the final state values of all of those parameters, plus the desired number of frames in the resulting frame_set.
Any or all of the values of the parameters that go into generating the contents of a single frame can be changed between the initial set and the final set of values. The retulting frame_set will be an animation showing the progressive effect of the change in states from one to the other.
So the simple "oscillator" generator from above can be animated. Generators that use initial and final state parameters to make animated frame_sets also begin wih the underscore character.
_oscillator
The instructions for creating an animated frame_set of an oscillator starting with a frequency of 1.0 and transitioning into an oscillator with a frequency of 10.0 would look like this:
math frames 100
math _LBO1 frequency 10.0
math _oscillator
math render
The values of:
math frames 100
math _LBO1 frequency 10.0
are the only values that are changed from their defaults before the _oscillator generator is called.
This will generate a frame_set of 100 frames and put it into the regeters. The "render" command scales the real_number coordinates to fit in LaserBoy_space (the running application) in signed short integers.
Animation is visualized as the gradual change in increments of (1 / frames) per frame in the parameters from initial to final.
All of the animated frame_set generators use both "positions" of all of the parameters they take.
math start 0.0
math duration 1.0
math iterations 100
math _start 0.0
math _duration 1.0
math _iterations 100
math LBO1 function trapeziod
math LBO1 duty_cycle 0.0
math _LBO1 function circle
math _LBO1 duty_cycle 1.0
math _oscillator
math render
There is also a final state set of parameters for the animated cycloid generators.
math rhodonea_numerator 5.0
math rhodonea_denominator 11.0
math fixed_radius 1.0
math roller_radius 2.0
math roller_offset 0.0
math _rhodonea_numerator 7.0
math _rhodonea_denominator 13.0
math _fixed_radius 1.0
math _roller_radius 7.0
math _roller_offset 14.0
All of the math generators have both single frame and animated frame_set versions. A single frame is still a frame_set. It just has one frame.
math oscillator
math _oscillator
Once a frame_set is either generated or imported and loaded into the registers, operators can be called to alter the contents of the frame_set. Unary operators work on a single frame_set and only require one frame_set to be loaded in the registers. Binary operators require both registers A and B to be loaded.
There are unary operators that move scale and rotate the last frame_set added to the registers, leaving the result of the operation as the new last frame_set ƒ(B), deleting A and pushing the previous B back to A.
The operators:
math move
math scale
math rotate
use the parameters:
math displacement 0.0 0.0 0.0
math factor 1.0 1.0 1.0
math fulcrum 0.0 0.0 0.0
math rotation 0.0 0.0 0.0
These parameters are all 3D_real. All three x y z values are set in one line.
Changes to their default values must be noted before the operator is called.
In these three forms, the operators transform every frame exactly the same way in a frame_set.
In the cases of move and scale, every vertex of every frame is changed by either adding or multiplying with the cooresponding x y z values of the parameter. In the case of the rotate opertator, every vertex in the frame is rotated around the fulcrum in the units set in
math rotation_cycle 1.0
It's worth noting that whole number values in any of the axis of rotation are in full rotations which leaves no change in the rotational positions of the vertices around that axis.
There are also animated version of these operators that use final state parameters.
math _displacement 0.0 0.0 0.0
math _factor 1.0 1.0 1.0
math _fulcrum 0.0 0.0 0.0
math _rotation 0.0 0.0 0.0
math _move
math _scale
math _rotate
The animated versions of these operators take initial and final parameters and the change between them is distributed through the frame_set.
Another set of operators "spread" their effect from the first vertex to the last vertex of every frame. In the case of the unary operator "spread_move" the displacement of each vertex in the frame gets a portion of the destination coordinates x y z added to it proportional to its position in the ordered list of vertices. This creates an effect like moving the paper along a straight path while an image is being drawn on it. The first vertex has no displacement and the last has 100% of the displacement.
math spread_move
math spread_scale
math spread_rotate
In the case of "spread_scale" there is another parameter to indicate a final set of scaling factors for the set of vertices in each frame.
math displacement 0.0 0.0 0.0
math factor 1.0 1.0 1.0
math factor_ 1.0 1.0 1.0
math fulcrum 0.0 0.0 0.0
math rotation 0.0 0.0 0.0
The underscore character at the end of the parameter name "factor_" indicates a final state partameter used in an operation within the vertices of each frame.
math factor 0.0 0.0 0.0
math factor_ 1.0 1.0 1.0
This notation indicates the change in scaling factors from the first to last vertex of each frame. The default values of all of the positions of factor are all 1.0 or unity scale (no effect). But if the initial "factor" is set to all 0.0 and the final "factor_" is set to all 1.0, the image will appear to be growing from a single point (zero dimmensions) to "actual_size".
math factor 1.0 1.0 1.0
math _factor 1.0 1.0 1.0
This notation indicates the change in scaling factors from the first to last frame is the frame_set.
math factor 1.0 1.0 1.0
math factor_ 1.0 1.0 1.0
math _factor 1.0 1.0 1.0
math _factor_ 1.0 1.0 1.0
math _spread_scale
The operator "_spread_scale" uses all four positions of the parameter "factor". That is the initial and final scaling factor of the first frame and initial and final for the last frame.
The animated forms of these operators also begin with an underscore to indicate a progressive effect through the set of frames.
math _spread_move
math _spread_scale
math _spread_rotate
By default, all of these "spread" operators do their effect in a linear fassion. That is each vertex gets the same incremental change of (1 / number_of_vertices). But it is possible to acceleratre or decellerate the effect of the change.
math move_acceleration 0.0
math scale_acceleration 0.0
math rotate_acceleration 0.0
The default values of 0.0 indicate that there is no acceleration effect. A positive number will cause the calculation to create an effect that increases with every vertex. In the case of "spread_move" each vertex will get a larger portion added to it moving toward "destination".
Acceleration factors are used in an exponential expression with the base e.
A negative number has exactly the opposite effect as a positive number. It decelerates toward its final value. Essentially it's like accelerating from the other end backwards to the initial value.
Then there are the binary operators that use both registers as operands.
math add
math multiply
math warp
In these "single state" versions, only one frame is used from the frame_set in the second register to effect all of the frames in the frame_set of the first regitser. So, every frame in the frame_set in register A gets the x y z values added, multiplied or "warped" with the cooresponding x y z values in the first frame of the frame_set in register B.
The "warp" operator rotates the vertices in every frame of A by the coresponding vertex values in the first frame of B around each axis. Values in the set of verticed used for rotation are normalized. Since the default behaviour of an LBO is the sin function and the sin function always returns a value from -1.0 to +1.0 rotational displacement is in units of pi. A values of -1.0 to +1.0 are scaled to be -pi to +pi rasians (one full rotation).
In any case where one frame or every frame is paired with another frame or frames for a binary operation, the two frames being combined by the operator might not have the same number of vertices. LaserBoy employs a kind of vector set position interpolation to find an x y z value that exists between the actual vertices of the frame with fewer. If one frame has say, 1057 vertices and the other has only 100, the resulting frame after the operation will have 1057 vertices. The x y z values from the frame with only 100 vertices is calculated by a portion of the frame with more vertices, such that 1057 points are found along the lines indicated by the vectors in the frame that has only 100. It doesn't matter which register has the frame_set with more or less vertices per frame. It always caculates to the higher vertex count.
There are also animated frame_set versions of these operators that begin with the underscore character.
math _add
math _multiply
math _warp
These versions of the operators work from frame to frame between the two frame_sets loaded in the registers. So the contents of each frame in A are added, multiplied or warped by the coresponding frame in the frame_set in B.
Here again there may be a missmatch in the number of frames in each frame_set. So, LaserBoy matches operator frame to frame using some frames multiple times to complete all of the operations of the greater number of frames.
Two of the binary operators are commutative.
A ƒ B == B ƒ A
The operator add in its singular form is not commutative because it only uses the first frame of the last frame_set loaded in the registers. For this reason, none of the singular binary operators are commutitive. But frame to frame addition and multiplication are commutitive.
For all of the binary operators that are not commutative there is the
math swap
instruction. This does exactly what it says. It swaps the frame_sets of A and B before a binary operator is called that is not commutative.
The general concept of using this calculator is:
Set the values of the parameters about to be used in a generator.
Call the generator to calculate itself using its parameters. This will load the calculated frame_set into the first location of the registers.
At this point, parameters may be set for use by a unary operator and the call of the unary operator would load the result into the second of the two registers, or another generator may be called perhaps with different parameters set just before it was called. In either event the resulting frame_set will load into the second of the two registers.
Once there are two frame_sets loaded into the registers, the binary operators can be called.
Anytime there is a frame_set in the registers it can be stored in a list. The first frame_set stored to the list must have a name. A frame_set can be recalled from the list and copied into the registers.
A list of frame_sets can be spliced end-to-end into one frame_set and loaded into the registers, starting with the frame_set of name.
Similarly a list of frame_sets can be composited into each other by splicing the sets of verticies in each frame and the result loaded into the reisters.
A list of frame_sets can be rendered into LaserBoy_space and normalized as one whole frame_set (sharing the same dimensial space).
The list can be saved directly as txt, dxf, or bitmaps.
The list can be gleaned of all frame_sets with no name. A frame_set of name can be delisted.
There are also instructions that import color vector frame_sets from LaserBoy_space, txt files or directories of dxf files. A call of one of these import instructions makes a new frame_set and loads it into the registers.
Any instruction that creates a new frame_set will delete the first frame_set in the registers and push the second to the first. Every frame_set has an internal flag that indicates if it has been used in a calculation, copied to the list or rendered to LaserBoy_space, bmp, dxf or txt. Each frame_set is check before it is deleted to make sure it was used in some way. If it was not, it is considered an error and reported. Likewise, the list keeps track of its frame_sets use and reports if there are any left in the list unused at the end of the txt file.
All of the parameters exist and have default values before the text file is even opened. Every LBO is by default the sin(t) function. Any of their attributes can be changed before calling a generator that uses them.
math LBO1 reset
will set the named LBO back to its default values.
math LBO_reset_all
will set them all back to fefault values.
There are four possible "positions" that parameters can have in the expression that a generator uses to calculate the contents of every frame in a frame_set.
math LBO1 {attribute} {value}
Just the name itself indicates
the initial value of each frame's function interval
(the expression used to populate the vertices in each frame)
-OF-
the initial value for the first frame in a frame_set.
math LBO1_ {attribute} {value}
An underscore after the name indicates
the final value of each frame's function interval
-OF-
the initial value for the first frame in a frame_set.
math _LBO1 {attribute} {value}
An underscore before the name indicates
the initial value of each frame's function interval
-OF-
the final value for the last frame in a frame_set.
math _LBO1_ {attribute} {value}
An underscore before and after the name indicates
the final value of each frame's function interval
-OF-
the final value for the last frame in a frame_set.
Or to put it another way...
Parameters change from initial to final over the interval of each frame.
(LBO1 to LBO1_)
This is "intra_interval_interpolation".
Parameters change from initial to final over the frames of a frame_set.
(LBO1 to _LBO1)
Put those two concepts together and you get
( LBO1 to LBO1_) to (_LBO1 to _LBO1_).
[This document is not done yet!]
# Complete list of parameters and their default values:
#----------------------------------------------
math normalize_frames_with_origin no
math normalize_frames_individually no
math include_unit_reference no
math save_true_color_dxf no
math overwrite_txt_files no
math bmp_render_vertices no
math bmp_render_vectors yes
math save_txt_with_color {value of running app. Can be set yes or no}
math save_txt_color_hex {value of running app. Can be set yes or no}
math disable_bmp no
math disable_dxf no
math disable_txt no
math x_of_pi no
math y_of_pi no
math z_of_pi no
math radii_of_pi no
math intra_interval_interpolation {assumed to be no until an iii final parameter is defined. Can be set to no}
math moving_fulcrum {assumed to be no until a fulcrum_ parameter is defined. Can be set to no}
math to_frame 0.9
math hues_span_factor 1.0
math hues_index_multiple 1
math hues_shift 0
math bmp_line_width 1
math phase_cycle 360.0
math rotation_cycle 1.0
math interval_cycle 1.0
math frames 3
math still_frames 1
math first_frames 1
math last_frames 1
math start 0.0
math _start 0.0
math duration 1.0
math _duration 1.0
math iterations 100.0
math _iterations 100.0
math rhodonea_numerator 1.0
math _rhodonea_numerator 1.0
math rhodonea_denominator 1.0
math _rhodonea_denominator 1.0
math fixed_radius 1.0
math _fixed_radius 1.0
math roller_radius 1.0
math _roller_radius 1.0
math roller_offset 1.0
math _roller_offset 1.0
math displacement 0.0 0.0 0.0
math _displacement 0.0 0.0 0.0
math move_acceleration 0.0
math _move_acceleration 0.0
math factor 1.0 1.0 1.0
math factor_ 1.0 1.0 1.0
math _factor 1.0 1.0 1.0
math _factor_ 1.0 1.0 1.0
math scale_acceleration 0.0
math _scale_acceleration 0.0
math fulcrum 0.0 0.0 0.0
math fulcrum_ 0.0 0.0 0.0
math _fulcrum 0.0 0.0 0.0
math _fulcrum_ 0.0 0.0 0.0
math fulcrum_acceleration 0.0
math _fulcrum_acceleration 0.0
math rotation 0.0 0.0 0.0
math _rotation 0.0 0.0 0.0
math rotation_acceleration 0.0
math _rotation_acceleration 0.0
math LBO1 function sin
math LBO1 amplitude 1.0
math LBO1 frequency 1.0
math LBO1 phase 0.0
math LBO1 duty_cycle 0.5
math LBO1 damping 0.0
math LBO1 offset 0.0
math LBO1 sin 1.0
math LBO1 triangle 0.0
math LBO1 ramp 0.0
math LBO1 square 0.0
math LBO1 pulse 0.0
math LBO1 trapeziod 0.0
math LBO1 circle 0.0
math LBO1_ function sin
math LBO1_ amplitude 1.0
math LBO1_ frequency 1.0
math LBO1_ phase 0.0
math LBO1_ duty_cycle 0.5
math LBO1_ damping 0.0
math LBO1_ offset 0.0
math LBO1_ sin 1.0
math LBO1_ triangle 0.0
math LBO1_ ramp 0.0
math LBO1_ square 0.0
math LBO1_ pulse 0.0
math LBO1_ trapeziod 0.0
math LBO1_ circle 0.0
math _LBO1 function sin
math _LBO1 amplitude 1.0
math _LBO1 frequency 1.0
math _LBO1 phase 0.0
math _LBO1 duty_cycle 0.5
math _LBO1 damping 0.0
math _LBO1 offset 0.0
math _LBO1 sin 1.0
math _LBO1 triangle 0.0
math _LBO1 ramp 0.0
math _LBO1 square 0.0
math _LBO1 pulse 0.0
math _LBO1 trapeziod 0.0
math _LBO1 circle 0.0
math _LBO1_ function sin
math _LBO1_ amplitude 1.0
math _LBO1_ frequency 1.0
math _LBO1_ phase 0.0
math _LBO1_ duty_cycle 0.5
math _LBO1_ damping 0.0
math _LBO1_ offset 0.0
math _LBO1_ sin 1.0
math _LBO1_ triangle 0.0
math _LBO1_ ramp 0.0
math _LBO1_ square 0.0
math _LBO1_ pulse 0.0
math _LBO1_ trapeziod 0.0
math _LBO1_ circle 0.0
math LBO2 function sin
math LBO2 amplitude 1.0
math LBO2 frequency 1.0
math LBO2 phase 0.0
math LBO2 duty_cycle 0.5
math LBO2 damping 0.0
math LBO2 offset 0.0
math LBO2 sin 1.0
math LBO2 triangle 0.0
math LBO2 ramp 0.0
math LBO2 square 0.0
math LBO2 pulse 0.0
math LBO2 trapeziod 0.0
math LBO2 circle 0.0
math LBO2_ function sin
math LBO2_ amplitude 1.0
math LBO2_ frequency 1.0
math LBO2_ phase 0.0
math LBO2_ duty_cycle 0.5
math LBO2_ damping 0.0
math LBO2_ offset 0.0
math LBO2_ sin 1.0
math LBO2_ triangle 0.0
math LBO2_ ramp 0.0
math LBO2_ square 0.0
math LBO2_ pulse 0.0
math LBO2_ trapeziod 0.0
math LBO2_ circle 0.0
math _LBO2 function sin
math _LBO2 amplitude 1.0
math _LBO2 frequency 1.0
math _LBO2 phase 0.0
math _LBO2 duty_cycle 0.5
math _LBO2 damping 0.0
math _LBO2 offset 0.0
math _LBO2 sin 1.0
math _LBO2 triangle 0.0
math _LBO2 ramp 0.0
math _LBO2 square 0.0
math _LBO2 pulse 0.0
math _LBO2 trapeziod 0.0
math _LBO2 circle 0.0
math _LBO2_ function sin
math _LBO2_ amplitude 1.0
math _LBO2_ frequency 1.0
math _LBO2_ phase 0.0
math _LBO2_ duty_cycle 0.5
math _LBO2_ damping 0.0
math _LBO2_ offset 0.0
math _LBO2_ sin 1.0
math _LBO2_ triangle 0.0
math _LBO2_ ramp 0.0
math _LBO2_ square 0.0
math _LBO2_ pulse 0.0
math _LBO2_ trapeziod 0.0
math _LBO2_ circle 0.0
math LBO3 function sin
math LBO3 amplitude 1.0
math LBO3 frequency 1.0
math LBO3 phase 0.0
math LBO3 duty_cycle 0.5
math LBO3 damping 0.0
math LBO3 offset 0.0
math LBO3 sin 1.0
math LBO3 triangle 0.0
math LBO3 ramp 0.0
math LBO3 square 0.0
math LBO3 pulse 0.0
math LBO3 trapeziod 0.0
math LBO3 circle 0.0
math LBO3_ function sin
math LBO3_ amplitude 1.0
math LBO3_ frequency 1.0
math LBO3_ phase 0.0
math LBO3_ duty_cycle 0.5
math LBO3_ damping 0.0
math LBO3_ offset 0.0
math LBO3_ sin 1.0
math LBO3_ triangle 0.0
math LBO3_ ramp 0.0
math LBO3_ square 0.0
math LBO3_ pulse 0.0
math LBO3_ trapeziod 0.0
math LBO3_ circle 0.0
math _LBO3 function sin
math _LBO3 amplitude 1.0
math _LBO3 frequency 1.0
math _LBO3 phase 0.0
math _LBO3 duty_cycle 0.5
math _LBO3 damping 0.0
math _LBO3 offset 0.0
math _LBO3 sin 1.0
math _LBO3 triangle 0.0
math _LBO3 ramp 0.0
math _LBO3 square 0.0
math _LBO3 pulse 0.0
math _LBO3 trapeziod 0.0
math _LBO3 circle 0.0
math _LBO3_ function sin
math _LBO3_ amplitude 1.0
math _LBO3_ frequency 1.0
math _LBO3_ phase 0.0
math _LBO3_ duty_cycle 0.5
math _LBO3_ damping 0.0
math _LBO3_ offset 0.0
math _LBO3_ sin 1.0
math _LBO3_ triangle 0.0
math _LBO3_ ramp 0.0
math _LBO3_ square 0.0
math _LBO3_ pulse 0.0
math _LBO3_ trapeziod 0.0
math _LBO3_ circle 0.0
math LBO4 function sin
math LBO4 amplitude 1.0
math LBO4 frequency 1.0
math LBO4 phase 0.0
math LBO4 duty_cycle 0.5
math LBO4 damping 0.0
math LBO4 offset 0.0
math LBO4 sin 1.0
math LBO4 triangle 0.0
math LBO4 ramp 0.0
math LBO4 square 0.0
math LBO4 pulse 0.0
math LBO4 trapeziod 0.0
math LBO4 circle 0.0
math LBO4_ function sin
math LBO4_ amplitude 1.0
math LBO4_ frequency 1.0
math LBO4_ phase 0.0
math LBO4_ duty_cycle 0.5
math LBO4_ damping 0.0
math LBO4_ offset 0.0
math LBO4_ sin 1.0
math LBO4_ triangle 0.0
math LBO4_ ramp 0.0
math LBO4_ square 0.0
math LBO4_ pulse 0.0
math LBO4_ trapeziod 0.0
math LBO4_ circle 0.0
math _LBO4 function sin
math _LBO4 amplitude 1.0
math _LBO4 frequency 1.0
math _LBO4 phase 0.0
math _LBO4 duty_cycle 0.5
math _LBO4 damping 0.0
math _LBO4 offset 0.0
math _LBO4 sin 1.0
math _LBO4 triangle 0.0
math _LBO4 ramp 0.0
math _LBO4 square 0.0
math _LBO4 pulse 0.0
math _LBO4 trapeziod 0.0
math _LBO4 circle 0.0
math _LBO4_ function sin
math _LBO4_ amplitude 1.0
math _LBO4_ frequency 1.0
math _LBO4_ phase 0.0
math _LBO4_ duty_cycle 0.5
math _LBO4_ damping 0.0
math _LBO4_ offset 0.0
math _LBO4_ sin 1.0
math _LBO4_ triangle 0.0
math _LBO4_ ramp 0.0
math _LBO4_ square 0.0
math _LBO4_ pulse 0.0
math _LBO4_ trapeziod 0.0
math _LBO4_ circle 0.0
math LBO5 function sin
math LBO5 amplitude 1.0
math LBO5 frequency 1.0
math LBO5 phase 0.0
math LBO5 duty_cycle 0.5
math LBO5 damping 0.0
math LBO5 offset 0.0
math LBO5 sin 1.0
math LBO5 triangle 0.0
math LBO5 ramp 0.0
math LBO5 square 0.0
math LBO5 pulse 0.0
math LBO5 trapeziod 0.0
math LBO5 circle 0.0
math LBO5_ function sin
math LBO5_ amplitude 1.0
math LBO5_ frequency 1.0
math LBO5_ phase 0.0
math LBO5_ duty_cycle 0.5
math LBO5_ damping 0.0
math LBO5_ offset 0.0
math LBO5_ sin 1.0
math LBO5_ triangle 0.0
math LBO5_ ramp 0.0
math LBO5_ square 0.0
math LBO5_ pulse 0.0
math LBO5_ trapeziod 0.0
math LBO5_ circle 0.0
math _LBO5 function sin
math _LBO5 amplitude 1.0
math _LBO5 frequency 1.0
math _LBO5 phase 0.0
math _LBO5 duty_cycle 0.5
math _LBO5 damping 0.0
math _LBO5 offset 0.0
math _LBO5 sin 1.0
math _LBO5 triangle 0.0
math _LBO5 ramp 0.0
math _LBO5 square 0.0
math _LBO5 pulse 0.0
math _LBO5 trapeziod 0.0
math _LBO5 circle 0.0
math _LBO5_ function sin
math _LBO5_ amplitude 1.0
math _LBO5_ frequency 1.0
math _LBO5_ phase 0.0
math _LBO5_ duty_cycle 0.5
math _LBO5_ damping 0.0
math _LBO5_ offset 0.0
math _LBO5_ sin 1.0
math _LBO5_ triangle 0.0
math _LBO5_ ramp 0.0
math _LBO5_ square 0.0
math _LBO5_ pulse 0.0
math _LBO5_ trapeziod 0.0
math _LBO5_ circle 0.0
math LBO6 function sin
math LBO6 amplitude 1.0
math LBO6 frequency 1.0
math LBO6 phase 0.0
math LBO6 duty_cycle 0.5
math LBO6 damping 0.0
math LBO6 offset 0.0
math LBO6 sin 1.0
math LBO6 triangle 0.0
math LBO6 ramp 0.0
math LBO6 square 0.0
math LBO6 pulse 0.0
math LBO6 trapeziod 0.0
math LBO6 circle 0.0
math LBO6_ function sin
math LBO6_ amplitude 1.0
math LBO6_ frequency 1.0
math LBO6_ phase 0.0
math LBO6_ duty_cycle 0.5
math LBO6_ damping 0.0
math LBO6_ offset 0.0
math LBO6_ sin 1.0
math LBO6_ triangle 0.0
math LBO6_ ramp 0.0
math LBO6_ square 0.0
math LBO6_ pulse 0.0
math LBO6_ trapeziod 0.0
math LBO6_ circle 0.0
math _LBO6 function sin
math _LBO6 amplitude 1.0
math _LBO6 frequency 1.0
math _LBO6 phase 0.0
math _LBO6 duty_cycle 0.5
math _LBO6 damping 0.0
math _LBO6 offset 0.0
math _LBO6 sin 1.0
math _LBO6 triangle 0.0
math _LBO6 ramp 0.0
math _LBO6 square 0.0
math _LBO6 pulse 0.0
math _LBO6 trapeziod 0.0
math _LBO6 circle 0.0
math _LBO6_ function sin
math _LBO6_ amplitude 1.0
math _LBO6_ frequency 1.0
math _LBO6_ phase 0.0
math _LBO6_ duty_cycle 0.5
math _LBO6_ damping 0.0
math _LBO6_ offset 0.0
math _LBO6_ sin 1.0
math _LBO6_ triangle 0.0
math _LBO6_ ramp 0.0
math _LBO6_ square 0.0
math _LBO6_ pulse 0.0
math _LBO6_ trapeziod 0.0
math _LBO6_ circle 0.0
# Complete list of generators:
#----------------------------------------------
# https://en.wikipedia.org/wiki/Rhodonea
#
# ratio = rhodonea_numerator / rhodonea_denominator
#
# x = radius * cos(ratio * t) * cos(t)
# y = radius * cos(ratio * t) * sin(t)
math rhodonea
math _rhodonea
#----------------------------------------------
# https://en.wikipedia.org/wiki/Epicycloid
#
# ratio = fixed_radius / roller_radius;
#
# x = roller_radius * (ratio + 1) * cos(t)
# - roller_radius * cos((ratio + 1) * t)
#
# y = roller_radius * (ratio + 1) * sin(t)
# - roller_radius * sin((ratio + 1) * t)
math epicycloid
math _epicycloid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Epitrochoid
#
# ratio = fixed_radius / roller_radius;
#
# x = roller_radius * (ratio + 1) * cos(t)
# - roller_offset * cos((ratio + 1) * t)
#
# y = roller_radius * (ratio + 1) * sin(t)
# - roller_offset * sin((ratio + 1) * t)
math epitrochoid
math _epitrochoid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Hypocycloid
#
# ratio = fixed_radius / roller_radius
#
# x = (fixed_radius - roller_radius) * cos(t)
# + roller_radius * cos((ratio - 1) * t)
#
# y = (fixed_radius - roller_radius) * sin(t)
# - roller_radius * sin((ratio - 1) * t)
math hypocycloid
math _hypocycloid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Hypotrochoid
#
# ratio = fixed_radius / roller_radius
#
# x = (fixed_radius - roller_radius) * cos(t)
# + roller_offset * cos((ratio - 1) * t)
#
# y = (fixed_radius - roller_radius) * sin(t)
# - roller_offset * sin((ratio - 1) * t)
math hypotrochoid
math _hypotrochoid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Rhodonea
#
# LBO1 phase += (phase_cycle / 4) // convert to cosine-like function
# LBO2 phase += (phase_cycle / 4)
# LBO3 phase += (phase_cycle / 4)
# ratio = rhodonea_numerator / rhodonea_denominator
#
# x = radius * LBO1(ratio * t) * LBO2(t)
# y = radius * LBO3(ratio * t) * LBO4(t)
math oscillator_rhodonea
math _oscillator_rhodonea
#----------------------------------------------
# https://en.wikipedia.org/wiki/Epicycloid
#
# LBO1 phase += (phase_cycle / 4) // convert to cosine-like function
# LBO2 phase += (phase_cycle / 4)
# ratio = fixed_radius / roller_radius;
#
# x = roller_radius * (ratio + 1) * LBO1(t)
# - roller_radius * LBO2((ratio + 1) * t)
#
# y = roller_radius * (ratio + 1) * LBO3(t)
# - roller_radius * LBO4((ratio + 1) * t)
math oscillator_epicycloid
math _oscillator_epicycloid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Epitrochoid
#
# LBO1 phase += (phase_cycle / 4) // convert to cosine-like function
# LBO2 phase += (phase_cycle / 4)
# ratio = fixed_radius / roller_radius;
#
# x = roller_radius * (ratio + 1) * LBO1(t)
# - roller_offset * LBO2((ratio + 1) * t)
#
# y = roller_radius * (ratio + 1) * LBO3(t)
# - roller_offset * LBO4((ratio + 1) * t)
math oscillator_epitrochoid
math _oscillator_epitrochoid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Hypocycloid
#
# LBO1 phase += (phase_cycle / 4) // convert to cosine-like function
# LBO2 phase += (phase_cycle / 4)
# ratio = fixed_radius / roller_radius
#
# x = (fixed_radius - roller_radius) * LBO1(t)
# + roller_radius * LBO2((ratio - 1) * t)
#
# y = (fixed_radius - roller_radius) * LBO3(t)
# - roller_radius * LBO4((ratio - 1) * t)
math oscillator_hypocycloid
math _oscillator_hypocycloid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Hypotrochoid
#
# LBO1 phase += (phase_cycle / 4) // convert to cosine-like function
# LBO2 phase += (phase_cycle / 4)
# ratio = center_radius / roller_radius
#
# x = (center_radius - roller_radius) * LBO1(t)
# + roller_offset * LBO2((ratio - 1) * t)
#
# y = (center_radius - roller_radius) * LBO3(t)
# - roller_offset * LBO4((ratio - 1) * t)
math oscillator_hypotrochoid
math _oscillator_hypotrochoid
#----------------------------------------------
# https://en.wikipedia.org/wiki/Lissajous_curve
#
# x = LBO1(t)
# y = LBO2(t)
# also named _oscillator_xy
math lissajou
math _lissajou
#----------------------------------------------
# https://en.wikipedia.org/wiki/Lissajous_curve
#
# x = LBO1(t)
# y = LBO2(t)
# z = LBO3(t)
# also named _oscillator_xyz
math lissajou_xyz
math _lissajou_xyz
#----------------------------------------------
# x = t
# y = LBO1(t)
math oscillator
math _oscillator
#----------------------------------------------
# x = t
# y = LBO1(t) + LBO2(t)
math oscillator_sum
math _oscillator_sum
#----------------------------------------------
# x = LBO1(t)
# y = LBO2(t)
math oscillator_xy
math _oscillator_xy
#----------------------------------------------
# x = LBO1(t)
# y = LBO2(t)
# z = LBO3(t)
math oscillator_xyz
math _oscillator_xyz
#----------------------------------------------
# https://en.wikipedia.org/wiki/Harmonograph
#
# x = LBO1(t) + LBO2(t)
# y = LBO3(t) + LBO4(t)
math harmonograph
math _harmonograph
#----------------------------------------------
# https://en.wikipedia.org/wiki/Harmonograph
#
# x = LBO1(t) + LBO2(t)
# y = LBO3(t) + LBO4(t)
# z = LBO5(t) + LBO6(t)
math harmonograph_xyz
math _harmonograph_xyz
#----------------------------------------------
# x = t
# y = LBO1(t) * LBO2(t)
math amplitude_mod
math _amplitude_mod
#----------------------------------------------
# x = LBO1(t) * LBO2(t)
# y = LBO3(t) * LBO4(t)
math amplitude_mod_xy
math _amplitude_mod_xy
#----------------------------------------------
# x = LBO1(t) * LBO2(t)
# y = LBO3(t) * LBO4(t)
# z = LBO5(t) * LBO6(t)
math amplitude_mod_xyz
math _amplitude_mod_xyz
#----------------------------------------------
# x = t
# y = LBO1(t) ~*~ LBO2(t)
math frequency_mod
math _frequency_mod
#----------------------------------------------
# x = LBO1(t) ~*~ LBO2(t)
# y = LBO3(t) ~*~ LBO4(t)
math frequency_mod_xy
math _frequency_mod_xy
#----------------------------------------------
# x = LBO1(t) ~*~ LBO2(t)
# y = LBO3(t) ~*~ LBO4(t)
# z = LBO5(t) ~*~ LBO6(t)
math frequency_mod_xyz
math _frequency_mod_xyz
#----------------------------------------------
# x = t
# y = LBO1(t) ~+~ LBO2(t)
math phase_mod
math _phase_mod
#----------------------------------------------
# x = LBO1(t) ~+~ LBO2(t)
# y = LBO3(t) ~+~ LBO4(t)
math phase_mod_xy
math _phase_mod_xy
#----------------------------------------------
# x = LBO1(t) ~+~ LBO2(t)
# y = LBO3(t) ~+~ LBO4(t)
# z = LBO5(t) ~+~ LBO6(t)
math phase_mod_xyz
math _phase_mod_xyz
#----------------------------------------------
# x = LBO1(t) * cos(t)
# y = LBO1(t) * sin(t)
math polar
math _polar
#----------------------------------------------
# x = (LBO1(t) + LBO2(t)) * cos(t)
# y = (LBO1(t) + LBO2(t)) * sin(t)
math polar_sum
math _polar_sum
#----------------------------------------------
# x = (LBO1(t) * LBO2(t)) * cos(t)
# y = (LBO1(t) * LBO2(t)) * sin(t)
math polar_amplitude_mod
math _polar_amplitude_mod
#----------------------------------------------
# x = (LBO1(t) ~*~ LBO2(t)) * cos(t)
# y = (LBO1(t) ~*~ LBO2(t)) * sin(t)
math polar_frequency_mod
math _polar_frequency_mod
#----------------------------------------------
# x = (LBO1(t) ~+~ LBO2(t)) * cos(t)
# y = (LBO1(t) ~+~ LBO2(t)) * sin(t)
math polar_phase_mod
math _polar_phase_mod
###############################################
###############################################