## Lissajous figures with Processing

A Lissajous figure, sometimes called a Lissajous curve, is formed by these parametric equations:

```
x = r * cos(A*t)
y = r * sin(B*t)
```

Essentially, you can think of it a the point (x, y) oscillates from left to right `A`

times per second, and also oscillates up and down `B`

times a second. By changing `A`

and `B`

we can create some interesting curves.

Normally, you should choose `A`

and `B`

to be small integers. This creates a closed curve as `t`

varies between 0 and `2*pi`

## Examples

If we set `A`

to 1 and `B`

to 2, the `y`

value oscillates twice as quickly as the `x`

value, so it creates a figure of eight shape:

If we set `A`

to 3 and `B`

to 4 we get a more complex shape:

## The code

Here is the code to create a Lissajous figure in Processing:

```
void lissajous(float r, float cx, float cy, float A, float B)
{
PShape s = createShape();
s.beginShape();
for (float t = 0; t < TWO_PI; t += 0.01)
{
float x = cx + r * cos(A*t);
float y = cy + r * sin(B*t);
s.vertex(x, y);
}
s.endShape(CLOSE);
shape(s);
}
void setup()
{
size(600, 600);
}
void draw()
{
clear();
background(64);
noFill();
strokeWeight(2);
stroke(255, 0, 0);
lissajous(250, 300, 300, 3, 4);
}
```

The `lissajous`

function takes these parameters:

`r`

- the radius (ie size) of the shape.`cx`

,`cy`

- the centre of the shape in the x and y directions.`A`

,`B`

- the parameters in the equation.

The code inside this function is fairly similar to the circle example. In the loop we calculate the points (x, y) for values of `t`

from 0 to `2*pi`

. We add the points as the vertices of a `PShape`

. The final shape is an approximation to the Lissajous curve. and we draw it by calling the `shape`

function.

In the `draw`

function we create the shape with a radius of 250 and a centre (300, 300), which fits our image size of 600 pixels square.

Try different values of A and B. You should use integer values to get a closed shape.

## Exploring different values

In this image we have included every combination of `A`

and `B`

from 1 to 6, to create a map of Lissajous figures:

In this map, the column gives the value of `A`

(the first column is `A = 1`

, the second column is `A = 2`

etc), and the row gives the value of `B`

.

You will notice that all the shapes on the leading diagonal are circles. When A and B are both 1, the equations are:

```
x = r * cos(t)
y = r * sin(t)
```

which you might recognise as the parametric equation of a circle. When A and B are both 2, the equations are:

```
x = r * cos(2*t)
y = r * sin(2*t)
```

This creates exactly the same shape, the point just rotates around the circle twice as fast. As `t`

moves from 0 to `2*pi`

, the point goes round twice rather than just once. When A and B are both 3, it also draws a circle but the point goes round 3 times, etc.

You will also notice that the shape `A = 1`

, `B = 2`

is the same shape as `A = 2`

, `B = 4`

and also `A = 3`

, `B = 6`

, for the same reason.

One final interesting thing is the curve `A = 2`

, `B = 1`

(second column, first row). This curve is actually a parabola!

## Code for the Lissajous map

The code is the same as before, we have just used a different `draw`

function:

```
void draw()
{
clear();
background(64);
noFill();
strokeWeight(1);
stroke(255, 0, 0);
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
lissajous(40, 50+100*i, 50+100*j, i+1, j+1);
}
}
}
```

Here we use a nested loop to step through every combination of `A`

(given by `i+1`

), and `B`

(given by `j+1`

). The images are much smaller (`r`

is 40) and each image is placed in a different position on the page.

## Adding a phase term

One last thing we can do with Lissajous curves is to add a phase term to the `x`

equation:

```
x = r * cos(A*t + P)
```

This means that rather than starting at zero, the `x`

term effectively starts at `P`

. We can change the `lissajous`

function to accept the extra parameter:

```
void lissajous(float r, float cx, float cy, float A, float B, float P)
{
PShape s = createShape();
s.beginShape();
for (float t = 0; t < TWO_PI; t += 0.01)
{
float x = cx + r * cos(A*t + P);
float y = cy + r * sin(B*t);
s.vertex(x, y);
}
s.endShape(CLOSE);
shape(s);
}
```

Let’s draw a set of curves with different values of `P`

. The first curve has `P = 0`

, with `P`

increasing by 0.2 in each successive image (in reading order):

As you can see, the phase term makes slight changes to the shape. We can use this to create interesting variations.

Here is the complete code for the image above:

```
void lissajous(float r, float cx, float cy, float A, float B, float P)
{
PShape s = createShape();
s.beginShape();
for (float t = 0; t < TWO_PI; t += 0.01)
{
float x = cx + r * cos(A*t + P);
float y = cy + r * sin(B*t);
s.vertex(x, y);
}
s.endShape(CLOSE);
shape(s);
}
void setup()
{
size(600, 600);
}
void draw()
{
clear();
background(64);
noFill();
strokeWeight(2);
stroke(255, 0, 0);
lissajous(65, 75, 75, 3, 2, 0);
lissajous(65, 225, 75, 3, 2, 0.2);
lissajous(65, 375, 75, 3, 2, 0.4);
lissajous(65, 525, 75, 3, 2, 0.6);
lissajous(65, 75, 225, 3, 2, 0.8);
lissajous(65, 225, 225, 3, 2, 1);
lissajous(65, 375, 225, 3, 2, 1.2);
lissajous(65, 525, 225, 3, 2, 1.4);
}
```