I misunderstood the Julia set.

title image

I misunderstood the Julia set and ended up creating something completely different. I'm not sure what to call these drawing results, but I'll show you these along with the p5.js code.

And I'll show you the right (perhaps) code to draw the Julia set later.

 

👉 この記事は日本語でも読めます。

 

How to calculate the Julia set?

'The Julia set is two complementary sets defined from a function.'
Wikipedia : Julia set

I couldn't grasp its meaning at all, but I decided to attempt to draw the Julia set as a visual representation through creative coding. As a result, I found the following calculation formula.

Xn+1 = Xn * Xn - Yn * Yn + a
Yn+1 = 2 * Xn * Yn + b

A-ha! I see! So I just calculate (x, y) using a recurrence equation and then plot it, right?

 

Something I've never seen before.

So I plotted the points I calculated with the parameters a = -0.3 and b = -0.63.

A multitude of plotted points is forming a mysterious shape.

/** 
 * I misunderstood the Julia set.
 * calculate (x, y) using a recurrence equation and then plot it.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0
 * p5.js 1.6.0
 * created 2023.05.06
 */

  const w = 640;
  const h = w;
  const a = -0.3;
  const b = -0.623;

  function setup() {
    createCanvas(w, h);
    noLoop();

    translate(w * 0.8, h * 0.8);
    background(240);
    noFill();

    let xn = 0;
    let yn = 0;
    for (let i = 0; i < 10000; i++) {
      let x = pow(xn, 2) - pow(yn, 2) + a;
      let y = 2 * xn * yn + b;
      point(x * w, y * h);
      xn = x;
      yn = y;
    }

  }


Humm. It seems like something I've never seen before. Is it a kind of Julia set?

 

I got lost, but I will continue on this path.

I tried changing the way of drawing, but it still didn't form anything like a Julia set. Even using well-known parameter values for 'a' and 'b' didn't have any effect.

I thought it happened because I was trying to create it without understanding the Julia set.

But, I'll prioritize having fun writing code that creates something interesting than reproducing something correctly. That's my approach to 'creative coding'.

Then, it created something interesting (creepy) by chance when I connected the calculated points with 'curveVertex()'.

Creepy moire pattern

/** 
 * I misunderstood the Julia set.
 * calculate (x, y) using a recurrence equation and then draw the curve with it.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0
 * p5.js 1.6.0
 * created 2023.05.06
 */

  const w = 640;
  const h = w;
  const a = -0.3;
  const b = -0.6225;
 
  function setup() {
    createCanvas(w, h);
    noLoop();
 
    translate(w * 0.8, h * 0.8);
    background(240);
    noFill();
 
    let xn = 0;
    let yn = 0;
    beginShape();
    for (let i = 0; i < 5000; i++) {
      let x = pow(xn, 2) - pow(yn, 2) + a;
      let y = 2 * xn * yn + b;
      if (i % 3 == 0) {
        curveVertex(x * w, y * h);
      }
      xn = x;
      yn = y;
    }
    endShape();
 
  }


The key of this code is weeding out the points to draw.

if (i % 3 == 0) {


 

The true colors of Julia set.

The calculation and drawing of the Julia set indeed involve recurrence equations. But instead of plotting the resulting (x, y) coordinates, the approach is to use the number of iterations until certain conditions as the drawing.


Here are the codes to draw some Julia set. I used noise() to change the hue value and alpha value. The saturation and brightness are fixed values. You can make something more with these example codes.

p5.js


/** 
 * The true colors of Julia set.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0
 * p5.js 1.6.0
 * created 2023.05.06
 */

  const w = 640;
  const h = w;
  const calcMax = 100;
  const paramA = -0.7015;
  const paramB = -0.3845;
  const zoom = 1.5;

  function setup() {
    createCanvas(w, h);
    colorMode(HSB, 360, 100, 100, 100);
    noLoop();

    background(0.0, 0.0, 90.0, 100.0);
    noStroke();

    for (let x = 0; x < w; x++) {
      for (let y = 0; y < h; y++) {
        // calc
        let x0 = map(x, 0, w, -zoom, zoom);
        let y0 = map(y, 0, h, -zoom, zoom);
        let diverCnt = 0;
        for (let calcCnt = 0; calcCnt < calcMax; calcCnt++) {
          let x1 = pow(x0, 2) - pow(y0, 2) + paramA;
          let y1 = 2 * x0 * y0 + paramB;
          if (pow(x1, 2) + pow(y1, 2) > 4.0) {
            break;
          }
          x0 = x1;
          y0 = y1;
          diverCnt++;
        }

        // draw
        let nParam = map(diverCnt, 0, calcMax, 0.0, 1.0);
        let hueVal = noise(100.0, nParam * 50.0) * 240.0;
        let satVal = 90.0;
        let briVal = 30.0;
        let alpVal = noise(200.0, nParam * 20.0) * 100.0;
        fill(hueVal % 360.0, satVal, briVal, alpVal);
        rect(x, y, 1.0, 1.0);
      }
    }
  }

Processing


/** 
 * The true colors of Julia set.
 * 
 * @author @deconbatch
 * @version 0.1
 * @license CC0
 * Processing 3.5.3
 * created 2023.05.06
 */

public void setup() {
  size(640, 640);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  smooth();
  noLoop();

  int calcMax = 100;
  float paramA = -0.7015;
  float paramB = -0.3845;
  float zoom = 1.5;

  background(0.0, 0.0, 90.0, 100.0);
  noStroke();

  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      // calc
      float x0 = map(x, 0, width, -zoom, zoom);
      float y0 = map(y, 0, height, -zoom, zoom);
      int diverCnt = 0;
      for (int calcCnt = 0; calcCnt < calcMax; calcCnt++) {
        float x1 = pow(x0, 2) - pow(y0, 2) + paramA;
        float y1 = 2 * x0 * y0 + paramB;
        if (pow(x1, 2) + pow(y1, 2) > 4.0) {
          break;
        }
        x0 = x1;
        y0 = y1;
        diverCnt++;
      }

      // draw
      float nParam = map(diverCnt, 0, calcMax, 0.0, 1.0);
      float hueVal = noise(100.0, nParam * 50.0) * 240.0;
      float satVal = 90.0;
      float briVal = 30.0;
      float alpVal = noise(200.0, nParam * 20.0) * 100.0;
      fill(hueVal % 360.0, satVal, briVal, alpVal);
      rect(x, y, 1.0, 1.0);
    }
  }

}

 

We are free to fail.

You can create something even with flawed code. It might be one of the joys of creative coding.

You are free to attempt drawing the Julia set and end up with completely different results. You are allowed to get lost and wander toward a fascinating path. This time, I was able to experience the joy of such creative coding.

 

Next Post Previous Post
No Comment
Add Comment
comment url