Exponential Move Formula

Moho allows users to write new tools and plugins. Discuss scripting ideas and problems here.

Moderators: Víctor Paredes, Belgarath, slowtiger

Post Reply
User avatar
Rhoel
Posts: 844
Joined: Fri Feb 25, 2005 8:09 am
Location: Phnom Penh, Cambodia
Contact:

Exponential Move Formula

Post by Rhoel »

I have been working on the fairing calcuations over the last few days.

One fairing option not available on Moho is Exponential. This is needed if you are doing an "infinite zoom/track" - the one which goes from a shot of the entire world, then tracks into a continent, then city, house. person, etc down to molecular level. Usually, this is many shots grouped together: Its tricky to set up and without this formula, you're never going to do it ... when working on 4 Dino's in New York (aka We're Back) for Universal, I had to calculated a move from 22F (22" inches wide" to an equivalent 0.25F zoom - it took 3 separate backgrounds and a week of Lynx Robotics software to calculate the Zoom, NS, and EW axis positions, including preparationof the field guides. To make it really fun, the move linked into an animated take-over and morph :).

Ah, the good old days of film ... I miss them. (Really, I do).

Back to the numbers. The great thing about this formula is that contains just 6 lines of code, with only one line of number-crunching. It's simple, elegant but a vital bit of maths. Don't even think of asking how I arrived at the answer or figured it out - just accept it works.

okay, here is the code (in Python)

Code: Select all

# -----------------------------------------
#     Exponetial calculation vr: 1.00
#         (c) 2006 TJ Francis
#           ---------------
#             Open Licence
# just credit me if you use it commercially
#------------------------------------------

position_a = 4.0                    # --- start position of move
position_b = 16.0                   # --- End Positof of move
Frames = 8                          # --- How many frames, difficult, huh?

import math                         # --- include the math module

#--- Calc --------------------
unit_a = math.log(position_a)       # --- Convert to Log values
unit_b = math.log(position_b)       

inc = (unit_b - unit_a)/Frames      # --- find the "linear" step value

n = 0                               # --- Intialize the variables
value = 0.0
for n in range(Frames+1):           
    value = math.exp((unit_a + (inc*n)))        # --- generate the positions
# ----------------------------
    print n ,"  ", '% 6.1f' % (value)           # --- Echo the results

If you are a photographer, the values, 4 and 16 will mean something to you, and the value at frame 4 is interesting as the mid-point is not 10 as you expect.

If someone wants to convert to lua script, then fine. I think this is of more interest to LM, which is why its .py.

I have a working python-code slow-in/constant/slow out formula - this one is linear fairings (soft stop): I am working on the radian fairings now - should have that finished by the week end. The documentation is taking a little time, as is the quirky nature of python code - I'm used to Pascal ... I cannot get the multi-dimentional array creation to work at present, and its driving me nuts (error is unknown function: array). I have now installed MubPY and hope that fixes the problem.

Any other idea why a = ([1, 2, 3], [4.0, 5.0, 6.5]) throws an error? I usually drop all the cruched numbers into a table, then just refer back to them for printing, driving motors etc. Saves on dual pass calculations.


Rhoel
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

For who is interested, this is the output of the python script:

Code: Select all

0       4.0
1       4.8
2       5.7
3       6.7
4       8.0
5       9.5
6      11.3
7      13.5
8      16.0
jeff
Posts: 127
Joined: Fri Aug 20, 2004 12:32 pm
Location: London, UK
Contact:

Post by jeff »

Rhoel,

Thanks for your fascinating posting. Sadly, I am old enough to know exactly what you are getting at, (I used to have a 16/35mm stand), but too untechnical to understand how to translate your formula into a practical tool within Moho. Any chance you could program the information in a Lua script for dummies like me?
Exponential track-ins were a pet hate for me in the steam-power days of animation. A wonderful mathematician and film-maker called Brian Salt had written (but no one would publish) all the formulae needed and kindly passed them on to me, but I was too dumb even when I was young to understand how to use them. I believe they started by requiring you to enter the exact focal length of the camera lens, but then it all descended into maths too difficult for me to follow. I did write some little programs in Basic based on other formulae of his to generate EW NS moves, but never understood exponential.

I would dispute your statement that only exponential fairings are missing from Moho. In fact there is no simple ease in or ease out, even though they are listed. If you try them out you will see what I mean. They are certainly not what a traditional animator would expect. Fortunately, there are work rounds. A few users have been quietly chipping away at LM to offer real motion graph control, but the author of the software hasn't risen to the challenge yet. Perhaps your posting will inspire him.

Regards,

Jeff
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Re: Exponential Move Formula

Post by Rasheed »

Rhoel wrote:Any other idea why a = ([1, 2, 3], [4.0, 5.0, 6.5]) throws an error? I usually drop all the cruched numbers into a table, then just refer back to them for printing, driving motors etc. Saves on dual pass calculations.
I'm not sure what you mean, because in Python interactive mode

Code: Select all

a = ([1, 2, 3], [4.0, 5.0, 6.5])
doesn't throw an error. However, you can't modify a tuple, so a

Code: Select all

a[0][4] = 4
will raise an error here. I think you'd better store you arrays in dictionaries or lists, which are mutable, so you can append your values to it. BTW lists have order, but dictionaries don't have order.

tuple notation: ( 1, 2, 3 )
list notation: [ 1, 2, 3 ]
dictionary notation: { 0:1, 1:2, 2:3 }

Code: Select all

>>> a = ( 1, 2, 3 ) # tuple
>>> b = [ 1, 2, 3 ] # list
>>> c = { 0:1, 1:2, 2:3 } # dictionary
>>> for i in range(0,3):
...     print a[i] , b[i] , c[i]
... 
1 1 1
2 2 2
3 3 3
>>>
The advantage of using dictionaries (which work with key/value pairs) is that you can use the x value as a key and the y value as its value, so you can have a discrete function y == F(x):

Code: Select all

>>> F = {}
>>> F[1.0] = 4.0
>>> F[2.5] = 6.0
>>> F[4.0] = 8.0
>>> print F
{2.5: 6.0, 1.0: 4.0, 4.0: 8.0}
And as you may have noticed in this code example, a dictionary is unordered.

If you want to store vectors, you could try this approach:

Code: Select all

>>> vectors = {}
>>> vectors[0] = ( 0.25, -0.75, 0.4)
>>> vectors[1] = ( -0.3, 1.0, 0.5 )
>>> print vectors
{0: (0.25, -0.75, 0.40000000000000002), 1: (-0.29999999999999999, 1.0, 0.5)}
Or even better:

Code: Select all

>>> x = "x"; y = "y"; z = "z"
>>> v = {}
>>> v[0] = { x:0.25, y:-0.25, z:-0.4 }
>>> v[1] = { x:-0.3, y:1.0, z:0.5 }
>>> for i in range(0,2):     
...  print v[i][x], v[i][y], v[i][z]
... 
0.25 -0.25 -0.4
-0.3 1.0 0.5
And they may even be more efficient methods of storing vector coordinates. I just whipped these up with Python interactive mode.
User avatar
Rhoel
Posts: 844
Joined: Fri Feb 25, 2005 8:09 am
Location: Phnom Penh, Cambodia
Contact:

Post by Rhoel »

jeff wrote:A wonderful mathematician and film-maker called Brian Salt
The wonderful and I think sadly-departed Mr Salt. He did eventually get his book published - I have two copies ... It used to be available through Chromacolour on their book list ... not sure it's even in print. Regretably, both my copies are in the UK and I am in Thailand ... as you can tell, I'm as organised as usual. :)

I did convert Brians standard calculation into a computer once - did it in Pascal (lovely language) and it worked but produced numbers suited to automation and not manual cameras. I hacked the calculation so it was human friendly - producing increments that were always 1/4 handle turn ... doing 200 frames of 0.8 was a pain. Doing 200 frames of 0.75 was easy. Easy = less mistakes.

As for the ease-in out problems. Its well documented and yes, we have been putting pressure on LM to fix. '(Check the bug topics for the thread).

This "broke' bit of Moho is why I'm playing with the calculations. I've written the formula before and have 25 years of daily camera and compositing experience to bring to the solution ... basically, I understand the interactions between the different elements - and yes, it is complicated, I fully understand why Mike/LM have been having problems with the code. It requires a different type of maths to the (now) common parametric curves (Bezier Hermite etc). I'll publish all the background when I release the code. I already have an ease-in/out calc finished .. the first one i\was a linear fairing - it produces a reasonable camera move but is less suitable for animation (The measuring tool is the bouncing ball exercise - linear makes the bouce look a little heavy [this observation is noticable if you are being really picky]).

I am working on the radian version now - having Brian's formula would be a big help but I know the principle well. Getting it down in code is a headache, especially when Python is not your usual language. most of the time is spent on syntax errors, not in the formula writing.

Hopefully, haveing a ready to wear bit of code will persuade LM to implement the change.

Regards
Rhoel
User avatar
Rhoel
Posts: 844
Joined: Fri Feb 25, 2005 8:09 am
Location: Phnom Penh, Cambodia
Contact:

Re: Exponential Move Formula

Post by Rhoel »

Rasheed wrote:
If you want to store vectors, you could try this approach:

Code: Select all

>>> vectors = {}
>>> vectors[0] = ( 0.25, -0.75, 0.4)
>>> vectors[1] = ( -0.3, 1.0, 0.5 )
>>> print vectors
{0: (0.25, -0.75, 0.40000000000000002), 1: (-0.29999999999999999, 1.0, 0.5)}
Or even better:

Code: Select all

>>> x = "x"; y = "y"; z = "z"
>>> v = {}
>>> v[0] = { x:0.25, y:-0.25, z:-0.4 }
>>> v[1] = { x:-0.3, y:1.0, z:0.5 }
>>> for i in range(0,2):     
...  print v[i][x], v[i][y], v[i][z]
... 
0.25 -0.25 -0.4
-0.3 1.0 0.5
Many thanks for this - I was not aware of how dictionaries were organised ... I had been looking for a parallel to Pascals arrays with records - where (array = record of framenumber:integer, velovity_data: real, Potition_data:real). Dictionaries seem to do that, can be appended, sorted and written directly.

So I'll now retire to a darken room to get my head around how to structure the beast. My favoured way of working is to write all the values to a look-up table, in this case
frame[0] = (velocity, position)
frame[1] = (velocity, position)
etc.

The reason for this is the calculation is in two parts - first to make a ""velocity template", then apply that velocity to the distance data. The secret is to create a template of the move using known dummy data (where the value of velocity is =<1. Having a max velocity of 1 is vitally important, and it took me 3 days to figure its importance out. It's critical since the ease-in and out might be of different lengths - that can cause speed glitches when moving in ot out of the linear component. But if the maximum velocity is 1, then the fairing velcities will always be less. After that, the rest is easy since the its just Base_increment = Total Distance/(sum of velocity values). Any position become Base_increment * velocity[frame].

I am now evaluating whether a Fibonacci progression (more likely to be an inverse Fibonacci progression) or Radian maths will produce the better deceleration.

If I can get the dictionaries to work quickly, it will mean I have have both values written to the same table, making print-out/graphics much easier to evaluate.

Either way, figuring out that the max-velocity can only be value 1 makes implimenting the code into LM's linear code straight forward - passing the value of the linear component into the fairing calculation is now very simple.

And yes, I know I'm sad and incorrigible, and I should get out more, especially since I live in Thailand, surrounded by some first-rate distractions :)

Thanks for all the help.

Rhoel
User avatar
rylleman
Posts: 750
Joined: Tue Feb 15, 2005 5:22 pm
Location: sweden
Contact:

Post by rylleman »

Roel, it's great that you take your time to do this! I only hope LM will implement it in Moho where it is much needed.
User avatar
Rasheed
Posts: 2008
Joined: Tue May 17, 2005 8:30 am
Location: The Netherlands

Post by Rasheed »

@Rhoel: I found a Python 2.4 quick ref guide for you:
http://rgruet.free.fr/PQR24/PQR2.4.html
and a good 10 minutes guide:
http://www.poromenos.org/tutorials/python
Post Reply