View Full Version : Jscript in Quartz Composer.

01-18-2009, 06:25 PM
Hi all,
I am transitioning some of my work with iterated function systems and attractor sets to quartz composer from Pd/GEM. I am very excited that apple chose to include the extensibility of a great scripting language like JS, since QC lacks objects such as arrays and persistent storage for strings and nums. I haven't touched JS since highschool.

My eventual goal is to build a javascript object that iterates functions for X,Y, and Z values: x2 = (x1+1.12)*(y1+1.2)*1.24 <or something similar.

Does anyone know of a good source of example code for IFS or JS in QC? Should I be using a for loop, or is their a better method?


Here is the working example code from QC:

A simple script that takes two input values, sums them and returns the result.

Special keywords for defining input and output key types:
__boolean, __index, __number, __string, __image, __structure, __virtual

Note that the function input arguments are read-only.

function (__number outputNumber) main (__number inputNumber[2])
var result = new Object();
result.outputNumber = inputNumber[0] + inputNumber[1];
return result;

JS in QC reference:

01-18-2009, 07:08 PM
An IFS is a list of (A,b,p), where, at each iteration, starting from x0, you choose from the list randomly (such that each list tuple is chosen with probability p) and update by setting x = Ax+b, yes?

I would try something like this (and this would allow for non-linear transforms as well):

// Define your transforms here

var list = new Array();

// Choose x = Ax+b 50% of the time, where:
// A = [a,b,c;d,e,f;g,h,i] and b = [j;k;l]
[0.5, function(x) {
return [
a*x[0]+b*x[1]+c*x[2] + j,
d*x[0]+e*x[1]+f*x[2] + k,
g*x[0]+h*x[1]+i*x[2] + l

// Choose x = [x_1;x_2;sin(x_3) / (x_1*x_2)] the other 50% of the time
[0.5, function(x) {
return [
Math.sin(x[2]) / x[0] / x[1]

// construct the CDF of probabilities
var cdf = new Array(list.length);
cdf[0] = list[0][0]
for (var i = 1; i < list.length; i++) {
cdf[i] = cdf[i-1] + list[i][0];

// now whenever you need an appropriately distributed transformation, call getTransform()
// it returns a function. For example:
// var t = getTransform(); x = t(x);

function getTransform() {
var r = Math.random();
for (var i = 0; i < cdf.length; i++) {
if (r <= cdf[i])
return list[i][1];

Should be enough to get you started at least.

01-19-2009, 04:45 PM
Thanks a lot. That looks great, I'll have to pick it over with a fine-toothed comb! The problem that I've run into with QC is the persistence of vars(arrays included.) It seems that the JS is recompiled with every frame, so in order to have persistent variables over time, they must be inside of objects. I admit that I am new to OOP, yet I understand the concepts. Also, I think the IFS is a big first step for me, so I am going to try an attractor set using the iteration method. For instance: the clifford attractor:

x<sub>n+1</sub> = sin(a y<sub>n</sub>) + c cos(a x<sub>n</sub>)<br>

y<sub>n+1</sub> = sin(b x<sub>n</sub>) + d cos(b y<sub>n</sub>)<br>

So I think the first step for me is to create a simple objects which iterates a function and stores it at an output each time it is rendered(each frame). For example, a counter, which I am having enough trouble with as it is.