Dev:Potential Formula Framework

From Synfig Studio :: Documentation
Jump to: navigation, search

[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) ]


We aim to define layer parameters through a function definition (ie, a formula). The compact syntax of the typical mathematical notation could be an efficient way to represent the value of a parameter across all frames.

Today, creating synfig conversions (potentially with linking) can require a significant amount of manual work subject to error and resulting in a nontrivial loss of time. [As an example, see this tutorial.] We want to substitute the manual conversion procedure with the specification of formulas.

We understand that a single compact formula may very likely cease to represent the value of the parameter once we have introduced animations. Our formula system must then include all information necessary to account for any possible change over time (ie, over frames), and, since animations can introduce rather arbitrary changes in value, this can potentially lead to a very complex specification of our formula.

We'd like each "formula" to have a string representation that is as simple as possible.

We'd like a graphical interface for creating and manipulating a formula.

We also want to be able to go back and forth between the sif representation of the value for a parameter and the formula form.

Animations Present Challenges

Currently, determining the value a parameter takes at some point in time is achieved either (a) by setting the value of the parameter to a constant value (for all frames), either (a1) directly or (a2) after having introduced conversions and linking; (b) by setting the value of the parameter to a different value in at least two frames (ie, introducing one or more dependent waypoints), using "Animate Editing Mode" or introducing the conversion frame dependency, either (b1) directly or (b2) after having introduced conversions and linking; or (c) through the process of interpolation that takes effect for frames being animated between relevant waypoints, either (c1) directly or (c2) after having introduced conversions and linking at either of the adjacent waypoints. ["Directly" means the parameter's value has no conversions or linking.]

The motivation behind introducing a formula framework is to provide a simpler interface to the current procedure used to create conversions ((a2), (b2), (c2)). As a special case, setting the value of a parameter "directly" ((a1), (b1), (c1)) also falls within the scope of a formula, namely the formula "= c", where c is the direct constant value chosen.

For cases (b) and (c), where waypoint dependencies have been introduced, a "simple" explicit formula is not likely to describe the parameter's value at all frames. We would likely need multiple formulas, each applying to the disjoint subsets of a partitioning of all the frames.

To see how we might be able to deal with the effects of the waypoints, we consider that a function (in the mathematical sense) is nothing but a mapping from one set of values to another set of values. In our case here, we have a mapping from the set of frame numbers (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). That is, we want a "formula" to specify what single value the parameter will take at each individual frame. A single simple formula won't be correct, in general, amid animation waypoints and the associated interpolations. We'll need a bifurcation consisting of multiple formulas with supporting notation.

Formulas that Capture All Frame Values despite Animations

We can represent any mapping (ie, "formula") as a two column table. This is the most general way to specify our mappings. The rows are labeled 1, 2, 3 in column one (to represent each frame), and the value in the second column is the value the parameter takes at that frame number.

As an example [add table diagram later], a table with rows: "1", "34.3"; "2", "23"; and "3", "235"; represents that the parameter has value 34.3 for frame 1, 23 for frame 2, and 235 for frame 3.

[In this and other early sections of this page, we'll use formula string notation that might be a bit simplified from the full string syntax described later.]

dfgdfgdfg fdgsdfgdfgsdgf 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 }

Procedure for Updating Formula after Creating Dependent Waypoint

[This should cover all the conversion cases in all combination cases possible. consider sibling/cousin case vs ancestor vs decendant.]

Formula String Syntax in More Detail

Basic Features

Relationship to Synfig Conversions

Example of Formula String that Shows the Automatically Generated Synfig Conversions


Example of Formula String Accounting for Interpolation


Example of Formula String that Includes Parameter Linking

Example of Formula String and the Corresponding SIF sections

Full BNF

[link to external document]

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 create a 1-1 mapping with conversions as they are now. All values in the current conversion system must be specified with formulas as well. Later, for presentational purposes only, we use mathematics rules to simplify (eg, "3*1*sin(x)*1" gets shown as "3sin(x)"). This means "formulas" will be implied from the sif file and need not be stored. Doing things this way allows for backwards compatibility as much as possible and avoiding gratuitous redundancies in the sif format. [Error detection/correction redundancies should be addressed as a separate issue if desired.]
As an example, the "add" conversion will be "A*(N+M)". Note the scalar value being multiplied by the two addends just as is the case today, and, similar to as things are now, the A would have a default value of "1.0".
We note that any given waypoint, at worst, adds a single deviation and possible addition of a bifurcation entry; however, we can have many more waypoints than frames. For example, a parameter might depend on 5 other values, all of which could be animated independently and at every frame. Or eg2: any five non-overlapping subsections of the "formula" can be changed at each frame [..or equivalently, we can have multiple sibling/cousin node within the tree change at each frame.] In each of these cases, we end up with 5 times more waypoints than frames; thus, it should be clear that some waypoints won't introduce further changes in our formula system or that perhaps we should simplify multiple bifurcations when possible so as never to have more than the same number of bifurcations as there are frames. Not yet clear if it is preferable to have { [1]:33+x, [2]:343+y } or { {[1]:33, [2]:343} + {[1]:x, [2]:y} }.
Still to come (hopefully) are some rules and examples. Eventually, we have to specify the precise rules for all possible scenarios.
Missing above is how to interpolate around the waypoints. We may want to add a symbol to specify the in/out interpolation modes from each waypoint.
It should be an easy notational change to add this semantic information and any similar one to the "[..]:" notation introduced above. Eg, {[c,l:0]: 6, [l,c:10, c,c:20]: 5 } means that the value of the parameter starts off at 6 and changes linearly to become 5 at frame 10 and then stays at 5 thereafter (up to and past frame 20). Perhaps a better notation in cases where most of the interpolations are similar would be to consider specifying each of these few combinations pointing to the waypoints that use them, rather than repeat the combination at each waypoint. Eg, { c,c l,c:2, 32,123-200,205 [0]:2323, [1]:2343, [2]:33, [3-31]:322, [32]:234, [123-200]:22, [205]:252 } to mean that waypoints 2, 32, 123-200, and 205 use linear/constant while every other waypoint uses constant/constant.
We may need to augment the notation to specify waypoints explicitly (eg, adding a "w" in there somewhere), but perhaps waypoints are implied (is there any other possibility once we change values ggdfgsdfgdfg?).
Yea, I think any specified values once animation has been introduced, counts as a waypoint. So this is implied mostly. Some minor rule(s) might be added for the sake of formality or to handle any degenerate case that might exist.

I am still learning about synfig so I may have added any number of errors to this page. Jose X 00:47, 31 May 2010 (UTC)

Graphical Formula Support

The Formula Panel

A Formula Panel shows the value of a selected layer parameter using the formula system described on this page.

It can also show a partial result when more than one parameters have been selected and these have some common values/formulas. In this case, we can determine, eg, exactly during which frames we want these multiple parameters to remain equal.

Linking is shown by referring to the relevant parameter by name (will exporting be required?) with the easy option to see how that parameter is itself defined: when hovering the mouse over that linked parameter, a context menu pop-up can allow a Formula Neighbor Panel to be displayed for that parameter.

A Formula Neighbor Panel is like a Formula Panel except that it is independent of whatever layer parameter may happen to be selected at that point in time (ie, it's decoupled from current selections).

What Does the Formula Panel Look like?

Creating and Editing Formulas through the Formula Panel

[Eventually, there will be mock pictures to show all the features of formula creation/editing in action.]

An Example

Let's see how we can create graphically the following formula: { []:3sin(2x+4), []: }

fghfghfghg 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.