Dev:Potential Formula Framework
[Beware: Rough notes.. may pain the reader's mind. Will finish this initial draft later.. some sections make sense (I hope) but a few are even more sketchy. A few examples down below may help tie some things together. Please don't yet delete sections that don't make sense. Jose X 02:12, 30 May 2010 (UTC) ]
Contents
Introduction
We aim to associate a function definition (ie, a formula) with any given parameter (of a layer). The compact syntax of the typical mathematical notation could be an efficient way to represent the value of a parameter across all frames.
Currently, determining the value a parameter takes at some point in time is achieved either (a) by setting the specific value manually (introducing waypoints), (b) explicitly without waypoints fgdfg once conversions and linking have been set up, or (c) interpolation .. In its most flexible form, conversions and linking require a significant amount of manual work subject to error and resulting in a nontrivial loss of time. We want to substitute the conversion and linking with the specification of formulas.
We understand that a compact formula may very likely cease to represent the value of the parameter once we have introduced waypoints; hence, we would ideally like to mix formulas with a compact notation to describe the exceptions to the formula created by the introduction of the waypoints.
We'd also like a graphical interface for creating and manipulating this formula. We'd like a string representation as well.
We also want to be able to go back and forth between the sif representation of the value for a parameter and the compact formula form.
Waypoints Present Challenges
.. In order to deal with waypoints, we have to consider that the function is, in its most general form, nothing but a mapping from the set of frames (ie, the natural numbers, 1, 2, 3, .. up to the last frame number) to the set of values the given parameter will take at each frame (eg, a real value). We can represent such a mapping as a two column table. The rows are labeled 1, 2, 3... (representing each frame), and the value in the other column at a given row is the value of the associated parameter at the frame number matching the row number. A major goal, however, will be to try to use formulas and short-cuts to capture as many values of the table as possible in as compact a fashion as possible (without sacrificing readability).
..Let's consider the case where we start off with a formula to describe the values of a parameter. As an initial description, we can consider the formula to be a function of the independent variable "frame" (aka time). .. We can start off with a formula (though we can even start off with a table mapping for maximum flexibility). In the worst case scenario, after a waypoint is introduced which modifies the mapping for that paramter, we can revert to a full table form. A major focus of this page is to consider how we can try to preserve compact notations despite the introduction of waypoints...
tree nodes.. leaves. For conversions ..
Formulas can Survive Waypoints
In the most general form, at each row we can represent the value of the parameter as a formula that applies only at that frame. And each row can have a different formula. This general case is where each frame's value is defined very differently from each other for that parameter. [Note, that a value is a special case of a formula, eg, y=5 is a value and a formula.. and so is y=sin(x) @ x=6]
Eg, row 1 having x+23sin(2*pi*x)+1 means row 1 has value 2. It seems ridiculous to represent 2 by a long complex formula that will only apply for a single frame, but the point is to recognize this general case: that we have a formula at every single row.
The ideal case for us is if every single row has the same exact formula. In this case, rather than listing every row and associated value/formula, we can simply list that formula. This is the ideal short-hand that signifies that every single row is defined by that same formula. [For example, y=3x in mathematics means that "3x" defines how every single point is calculated. We need not specify every single value when we use this short-hand.]
Our hope is always to reduce the large tables into small compact form by "refactoring" as much as possible. To this end, we will develop short-hand notation as necessary.
In this initial analysis, we'll consider the case where we start with a formula and then expand from this as little as possible.
To augment formulas, we can use { } notation to capture rows within a table mapping.
Eg, if every single frame can be described through some version of a sine wave, then we might define the full correct mapping (taking waypoints into account) from some version of a sine wave with `{' `}' within the formula to specify parts that vary according to the table.
Example 1 of Formula String with Waypoints
If the first through fifth frames have value 3sin(x), the sixth frame has value 3sin(x+1), the seventh frame has value 3sin(2x+1), and the eigth through 100th frames have 3sin(x), then the full mapping can be described by:
3sin( { x, [6]:x+1, [7]:2x+1} ).
Note how much more compact and "almost" equal to a simple formula is this notation (vs. a full table of 100 rows) to capture 2 divergences from the formula (to correspond perhaps to 2+ waypoints).
We are also using simple proven notation similar to what is used to define sparse arrays in some programming languages.
How would synfig arrive at that compact form?
Well, starting with a (canonical) tree representation of 3sin(x) [pic goes here], we find that that same tree lasts throughout the entire 100 frames, except that the node initially holding x gets replaced (with x+1, later with 2x+1, and then again with x). Thus, we can represent the full mapping by a formula representing the constant outside parts and one or more internal tables { } to capture the parts that did vary within the tree. If the function had changed at the root level, then our mapping would be an outer level bifurcation (more than one formula template) so as to capture all 100 rows within at least one of the bifurcation parts. Remember that the general form for any mapping for a parameter during 100 frames would be a 100 row table. [In our current case, all of those 100 rows have "3sin (blah)".]
Example 2 of Formula String with Waypoints
As above but row 9 is defined by 4sin(x), row 15 by 47, and rows 66, 67, and 73 by 3sin(x+1).
We can express this as:
{ 3sin( { x, [6, 66-67, 73]:x+1, [7]:2x+1} ), [9]:4sin(x), [15]:47 }
Some Issues not yet Addressed
-- To be done is to find the canonical tree form and canonical string form and find precise rules for mapping one to the other. Try to prove all of this and other important statements. -- We note that any given waypoint, at worst, adds a single deviation; however, we can have many more waypoints than frames (eg, multiple sibling changes within the tree at each frame). -- Missing above is how to interpolate around the waypoints. We may want to add a symbol to specify the in/out of each waypoint. -- We may need to augment the notation to specify waypoints explicitly, but perhaps waypoints are implied (is there any other possibility?).
Graphical Formula Support
A Formula Panel would show the existing formula (as per the above notation) for a selected parameter or more than one parameter if they match (maybe even try to factor out the common portions if multiple parameters have been selected).
A Formula Tool (or the Formula Panel) would be used to create and edit formulas. You drag and drop any of various well-defined formula components (like sin(x) or +). This would roughly pattern the conversions possible in synfig today. There would be a way to explicitly add row exceptions: "{ ... }". The location of the drop would define how the component modified the existing partial formula being created. Instead of adding further formula components at extension points (perhaps represented by variables initially.. and representing the parameters of the related synfig conversion), we can define these as a constant value or link to another parameter.
The formula creation GUI might have multiple views since some might be preferable over others depending on context and the synfig user.