Introduction | Main elements | Messages sent and received | Graphical interface | Scripts | Reference | Functions index

Version française

## Principles

With IanniX, you can write your own scripts to more easily create your complex projects. Scripts are written in Javascript but even with a limited knowledge of Javascript, many types of useful scripts can be created. In addition to this documentation you are reading, many example scripts are provided for you study. They can be found in the Examples section of the Scripts and Styles browser in the Inspector.

To open a script for viewing, right click on a script in the browser and choose `Open`. The context menu also contains other commands for working with scripts. In addition you can run a script by double clicking on its name in the Inspector.

If you wish to learn more Javascript for more advanced scripting there are many books, online tutorials and reference msterials available to help you. Also, feel free to inquire on the IanniX forum for further information on the conventions used in writing JavaScript, or for tips in writing IanniX scripts.

Here is a link to the complete language reference of the version of Javascript used in IanniX: Reference

## Controlling IanniX From a Script

### The Javascript `run()` Command

The run() function is used to send most commands to IanniX from scripts. Commands must be provided to run() as a single string, so command text must be enclosed quotation marks. Example:

`run("zoom 100");` Set the display zoom to 100 percent

To combine numeric parameters with text commands to produce a string to pass to `run()`, use the concatenation operator. In the following example center_x and center_y are in numeric variables and must be concatenated to the command string.

`run("setPos current " + center_x + " " + center_y + " 0");`

Other examples:

- Clear the score:
  `run("clear");`
- Set the display zoom to 100 percent:
  `run("zoom 100");`
- Give the trigger an ID based on the value of the script variable `myID:`
  `run("add trigger " + myID);`
- Set the group of the trigger to be "foo":
  `run("setGroup current foo");`
- Set the position of the trigger to be x=1, y=3, z=0:
  `run("setPos current 1 3 0");`
- Set the message for the trigger:
  `run("setMessage current 1, osc://127.0.0.1:57120/trigger trigger_id trigger_xPos trigger_yPos cursor_id");`
- Scale the trigger to half its default size:
  `run("setSize current 0.5");`

Remember the «`;`» at the end of each line. Note that constant numeric or string parameters may be included directly in the command string, whereas values in variables must be joined with the concatentation operator. Be sure to include spaces in concatenated strings so that commands and parameters in the resulting string are separated by at least one space.

See the Functions Index for a list of the functions you can use in the `run()` command to control IanniX.

### The `title()` and `ask()` Commands

In addition to `run()`, two other Javascript functions are provided for script writing:

- Declare "name" to be the name of your project:
  `title("name");`
- Open a window where the user can fill in the constants to initialize the script:
  `ask("category, label, variable, defaultValue);`
  The parameter «category» allows the grouping of multiple `ask()` requests in under a heading. All requests with the same category are grouped under the heading «category». «Label» is used as the data request prompt. «Variable» is the name of a variable that is created to hold the data. «Default» is the value suggested to the user as the default value of the variable. The user is free to name the categories, labels and variables as required.

### The Structure of a Script

IanniX executes a script in several phases. You can control the phase in which your commands are performed by grouping them under functions that are called at specific phases of execution. The functions are:

- Called by IanniX to prepare a script run:
  `onCreate()`
  {
  //Insert your commands here
  };
- Called by IanniX to carry out the intended actions of the script:
  `onConfigure()
  {
  //Insert your commands here
  };`
- Called each time IanniX receives an OSC message. This section is only required for scripts that are to receive OSC messages. (For example for script configuration):
  `onMessage()
  {
  //Insert your commands here
  };`

Here is an example of a simple script:

              //Setup of the script
              function onConfigure() {
                  title("My new script");             //Name the script

                  //Ask for parameters to customize the script behavior
                  iannix.ask("Triggers", "Trigger x-position", "trigger_xPosition", 3);
              }

              //Creation of the score
              function onCreate() {
                  run("clear");                       //Clear score objects
                  run("center 0 0");                  //Center on score origin
                  run("zoom 100");                    //100% zoom

                  run("add trigger 1");               //Add a trigger with ID 1
                  run("setPos current 1 2 0");        //Move the trigger to coordinates (1, 2, 0)

                  addATrigger();                      //Call a your custom function
              }

              //Define a custom function
              function addATrigger() {
                  //Insert the code to add and configure a trigger here
                  //Normally the function addATrigger() would have parameters to pass
                  //it the required features of the trigger to add.
              }

The only two functions that should be in the `configure()` function are `title() and `ask()`. All the rest of your code to be executed should be placed in the `create()` function. In addition you can define your own functions, define constants, etc. outside of any of the main functions. For example, the function `addATrigger()`, above.`

### Creating your own functions

Example: This function provides a random number between parameters `min` and `max`.

`function randomFloat(min, max) {
return Math.random() * (max-min) + min;
}`

### Creating your own libraries of functions

Iannix provides the ability to predefine libraries of frequently used functions for use in writing scripts. Files of type `<name>.js` in the Tools folder are scanned during IanniX startup and variables, classes and function definitons are made available for use in scripts. Note that if a library file is edited while IanniX is running, IanniX must be restarted for the changes to take effect.

### Predefined helper variables and functions

IanniX includes a library of helper functions defined in the file "JavaScript Library.js."
The library includes the following functions:

### Useful Constants

- `E`: the mathematical constant e
- `LN2`: the natural logarithm of 2
- `LN10`: the natural logarithm of 10
- `LOG2E`: the base 2 logarithm of e
- `LOG10E`: the logarithm to the base 10 of e
- `PI`: the constant PI
- `TWO_PI`: two times PI
- `THIRD_PI`: Pi over 3
- `QUARTER_PI`: Pi over 4
- `HALF_PI`: Pi over 2
- `SQRT1_2`: one over the square root of two
- `SQRT2`: the square root of two

### Math Functions:

- `abs(x)`: the absolute value of x
- `acos(x)`: the arccosine of x
- `asin(x)`: the arcsine of x
- `atan(x)`: the arctangent of x
- `atan2(x,y)`: the arctangent of x divided by y
- `ceil(x)`: the next higher integer above x
- `cos(x)`: cosine of x
- `exp(x)`: e to the power x
- `floor(x)`: the next lower integer below x
- `log(x)`: logarithm to the base 2 of x
- `min(x,y)`: the minimum of x and y
- `max(x,y)`: the maximum of x and y
- `pow(x,y)`: x raised to the power y
- `round(x)`: x rounded nearest integer, higher or lower
- `sin(x)`: the sine of x
- `sqrt(x)`: the square root of x
- `sq(x)`: x squared
- `tan(x)`: the tangent of x
- `degrees(x)`: the radian angle x converted into degrees
- `radians(x)`: the degree angle x converted into radians
- `random(low, high)`: returns a random number between low and high
- `constrain(x, min, max)`: values of x below min and above max are discarded
- `dist(x1, y1, z1, x2, y2, z2)`: the distance between the points `(x1, y1, z1)` and `(x2, y2, z2)`

### Data Scaling Functions

- Scale x to cover the range from low to high, assuming x ranges between 0.0 and 1.0:
  `norm(x, low, high)`:
- Scale x to cover the range from low to high, assuming x ranges between 0.0 and 1.0,
  with `mid` being returned as the value for x=0.5:
  `rangeMid(x, low, mid, high)`
- Scale x to cover the range from `low2` to `high2`, assuming x ranges between `low1` and `high1`:
  `map(x, low1, high1, low2, high2)`

## Curve Plotting

IanniX provides the `plot()` function to help you plot 2D or 3D parametric curves based on mathematical functions, either using cartesian or polar coordinates.

A parametric curve is defined as a function of one independent parameter (usually denoted t) that defines the values of the plotting coordinates as a function of t. For cartesian type plot (i.e. in terms of x, y, x) you must provide functions to define the values of x and y optionally z. as a function of t. For a polar type plot, you must provide functions of t to define r (the radius), theta (the angle) and optionally phi (the angle above or below the plane). In IanniX the functions must define the coordinates for values of t ranging from 0.0 to 1.0.

The curve plotting features uses a number of advanced Javascript features, but you can use it by inserting your equations into simple patterns, one pattern for x, y, z (Cartesion) curve plotting and another pattern for radial curve plotting.

### Cartesian Curve Plotting

Substitute your expressions for the text to the right of the colons for each of the variables x, y and z in the following pattern. Remember to include the comma at the end of the expression.

              plot(function(t){ return {
                 index   : 0, nbPoints: 300,
                 offset  : {x: 0, y:0, z:0},

                 x   : expression giving x in terms of t,
                 y   : expression giving y in terms of t,
                 z   : expression giving z in terms of t,

                 t   : [0,1]
              }});

### Polar Coordinate Curve Plotting

Substitute your expressions for the text to the right of the colons for each of the variables theta, r and phi in the following pattern. Remember to include the comma at the end of the expression.

              plot(function(t) { return {
                 index   : 0, nbPoints: 300,
                 offset  : {x: 0, y:0, z:0},

                 theta   : expression giving the angle theta (in radians) in terms of t,
                 r       : expression giving r in terms of t,
                 phi     : expression giving the angle phi (in radians) in terms of t,

                 t       : [0,1]
              }});

### Example: Script to Create a Parabolic Curve Using Cartesion Coordinates

To see the results of this script, run the example "Simple Parabola" in the Inspector Examples files.

              function onCreate() {
                  //Viewport setup
                  run("clear");
                  run("center 0 0");
                  run("rotate 0 0 0");
                  run("zoom 100");

                  run("add curve  1000");
                  run("setPos     current 0 0 0");

                  //Plot curve
                  plot(function(t) { return {
                      index   : 0, nbPoints: 300,
                      offset  : {x: 0, y:0, z:0},

                      x   : 5*t,   //i.e. x = 5 times t
                                   //(As t runs from 0 to 1, x runs from 0 to 5.)

                      y   : 3*t*t, //i.e. y = t squared
                                   //(as t runs from 0 to 1, y runs from 0 to 3.)

                      z   : 0,     //z is always 0

                      t       : [0,1] }});

                  //Add a cursor
                  run("add cursor 1001");
                  run("setCurve   current lastCurve");
                  run("setSpeed   current auto 100");
              }

### Example: Script to Create a Simple Spiral Using Radial Coordinates

To see the results of this script, run the example "Simple Spiral" in the Inspector Examples files.

              function onCreate() {
                  //Viewport setup
                  run("clear");
                  run("center 0 0");
                  run("rotate 0 0 0");
                  run("zoom 100");

                  run("add curve  1000");
                  run("setPos     current 0 0 0");

                  //Plot curve
                  plot(function(t) { return {
                      index   : 0, nbPoints: 300,
                      offset  : {x: 0, y:0, z:0},

                      theta   : TWO_PI * t,	  //i.e. theta = two Pi times t
                            //(As t runs from 0 to 1, theta runs from 0 to two Pi.)
                            //Since an angle of 2*Pi in radians is 360 degrees, theta
                            //rotates once as t goes from 0 to 1.

                      r       : 3*t,          //i.e. x = 3 times t
                            //(As t  runs from 0 to 1, the radius runs from 0 to 3.)

                      phi     : 0,		  //phi is always zero

                      t       : [0,1] }});

                  //Add a cursor
                  run("add cursor 1001");
                  run("setCurve   current lastCurve");
                  run("setSpeed   current auto 100");
              }

For an example of the interesting and crazy curves you can easily create with parametric equations, try duplicating (with the context menu) the "Learn - Simple Spiral" example in the IanniX Inspector Example scripts. Now open the script with the context menu and change the `phi : 0` to `phi : sin(20*t)`. Execute the script by double clicking on it in the Inspector. Now hold down the Alt key and drag the mouse on the score view to see the wavy 3D curve you created. Start the cursor running to see it undulate over the curve.

## Drawing Curves with Straight Line and Cubic Bezier Segments

The IanniX setPointAt() function allows scripts to create 2D and 3D paths from a sequence of straight line and curved (cubic Bezier) segments.

### Creating a Curve

Start a new curve with:
`run("add curve id");`
Creates a curve object with the specified ID. The curve has not yet been given any points. The location of a new object defaults to (0,0,0).

### The setPointAt Function

The setPointAt function is used to add points to or change points on a curve. There are several behaviors of the setPointAt() function depending the parameters passed to it:

- To set the first point of the path:
  `run("setPointAt id 0 x y <z>");
  which defines point number 0 as x, y (and optionally z for a 3D path).`
- To add a straight line segment to the path:
  `run("setPointAt id pNum x y <z>");`
  where pNum is the point number which should always be the previous pNum+1.
- To change the endpoint of a straight line segment in an existing path:
  `run("setPointAt id pNum x y <z>");`
  where pNum is the the number of the point to change.
- To add a curved segment and define its curvature:
  `run("setPointAt id pNum x y <z> dxStart dyStart <dzStart> dxEnd dyEnd <dzEnd> ");`
  where the end point of the segment is x, y and optionally z. The the segment starts tangent to a line from the start point, (the end of the previous segment) to the point `(xStart+dxStart, yStart+dyStart, <zStart+dZstart>)`. The segment ends tangent to a line from the end point `(x, y, <z>)` to the point `(x+dxEnd, y+dyEnd, <z+dyEnd>)`. Note that the start point would be the point `(x, y, <z>)` in the previous call to setPointAt.
- To change a previously defined curved segment:
  `run("setPointAt id pNum cx1 cy1 <cz1> cx2 cy2 <cz2> x y <z>");`
  where pNum is the number of a previously defined point and the other parameters are as defined above.

  (Optional parameters are indicated by bracketing between < >)

All forms of `setPointAt` specify the location of the point as x y <z>. The forms that specify Bezier segments include two other points, cx1 cy1 <cz1> and cx2 cy2 <cz2>, that describe the curvature. The direction of the curve leaving its start point is tangent to the line from the start point to the first control point cx1 cy1 <cz1>. The direction of the curve arriving its end point is tangent to the line from the control point cx2 cy2 <cz2> to the end point x y <z>.

### Example of Creating a Curve With 2D and 3D Segments

The following is the code of the example "Learn - Curve points" that can be found in the Inspector script browser. It creates a path with with five segments and five points. The first segment is a 2D straight line, the next is a 2D Bezier, the next is a 3D straight line, and the fourth segment is a 3D Bezier. Run the example script to see what the curve looks like. To see its shape in 3D hold down the Alt key and drag the mouse on the score area. You can reset the viewing angle by running the "Reset orientation" script in the Tools section of the script browser.

              //Creation of the score
              function onCreate() {
                  //Viewport setup
                  run("clear");
                  run("center 0 0");
                  run("zoom 100");
                  run("rotate 0 0 0");

                  //Create a curve
                  run("add curve  1000");

                  //Point number 0
                  //Location x0 = -2, y0 = 1
                  run("setPointAt current  0  -2 1");

                  //Draw a 2D straight segment from point number 0, to
                  //point number 1, which is at (x1,y1) = (-2,3)
                  run("setPointAt current  1   -2  3");

                  //Draw a 2D bezier segment from point number 1, to
                  //point number 2, which is at (x2,y2) = (2,3)
                  //Segment start is tangent to a line from (x1,y1) to (x1+2, y1+2)
                  //Segment end is tangent to a line from (x2,y2) to (x2+0,x2+3)
                  run("setPointAt current  2    2  3   +2 +2   +0 +3 ");

                  //Draw a 3D Straight segment from point number 2, to
                  //point number 3, which is at (x3,y3,z3) = (0,2,1)
                  run("setPointAt current  3    0 2 1");

                  //Draw a 3D bezier segment from point number 3, to
                  //point number 4, which is at (x4,y4,z4) = (-2,-1,0)
                  //Start tangent to a line from (x3,y3,z3) to (x3+0,y3-1,z3+2)
                  //End tangent to a line from (x4,y4,z4) to (x4+4,x4+0,z4+0)
                  run("setPointAt current  4   -2 -1 0   +0 -1 +2   +4 +0 +0");

                  //Add a cursor on the curve
                  run("add cursor 1");
                  run("setCurve   current lastCurve");
                  run("setSpeed   current auto 10");
              }