Creative Coding Blog

Maths, coding and art

Motifs on Lissajous figures II

In this article, we will look at some other motifs.

A square motif

Here is the Lissajous curve for A = 3 and B = 2 using a square motif. The motif is a square, outlined in dark red and filled with light blue. Both colours are very transparent.

Here the outline of the square creates a complex path, while the blue fill clouds some parts of the image creating depth.

Here is the complete code:

void motif()
{
    fill(64, 64, 255, 8);
    strokeWeight(2);
    stroke(128, 0, 0, 32);
    rect(-100, -100, 200, 200);
}

void lissajous(float r, float cx, float cy, float A, float B, float P)
{
    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);
        pushMatrix();
        translate(x, y);
        rotate(A*t);
        motif();
        popMatrix();
    }
}

void setup()
{
    size(600, 600);
}

void draw()
{
    clear();
    background(255);
    
    lissajous(150, 300, 300, 3, 2, 0);
}

Using colour

In this next example, we use an ellipse instead of a square as the motif shape. Aside from some minor changes (the values of A, B, and the step amount of t), the man change is that we vary the colour of the fill of the ellipse:

Rather than using a fixed value for the fill colour, we will calculate different r, g and b values for each ellipse as we go through the loop. We will use simple scheme, for example the red values is calculated like this:

r = 128*(1 + sin(B*t))

Since the sine function varies between +/-1, the term 1 + sin(x) varies between 0 and 2. So our red value varies between 0 and 256, the full range.

The green and blue values vary in a similar way, except that they change at different rates. This means that the colour of the ellipse changes smoothly and continuously as we draw the different ellipses, creating a gradient effect. Here is the full code:

void motif(float r, float g, float b)
{
    fill(r, g, b, 5);
    strokeWeight(2);
    noStroke();
    stroke(0, 64, 128, 32);
    ellipse(-20, -100, 40, 200);
}

void lissajous(float r, float cx, float cy, float A, float B, float P)
{
    for (float t = 0; t < TWO_PI; t += 0.005)
    {
        float x = cx + r * cos(A*t + P);
        float y = cy + r * sin(B*t);
        pushMatrix();
        translate(x, y);
        rotate(A*t);
        motif(128*(1 + sin(B*t)), 128*(1 + cos(B*t)), 64*(1 + cos(t)));
        popMatrix();
    }
}

void setup()
{
    size(600, 600);
}

void draw()
{
    clear();
    background(255);
    
    lissajous(95, 300, 300, 4, 5, 0);
}