Display grid of objects (animated circles)

Hi everyone,

I know that this is a frequent and simple question but I haven’t been able to find a solution for what I’d like to do.

I’m creating an object made of circles. In the class I have a function that modifies the x and y locations of the circles to make a “spinning spiral like” object.

I then initialize an array of objects in setup().
I’d like now to display several of them as a grid. I can’t figure out how to do it. I either manage to display all my objects at the same location on the canvas or to display only one of them.

What’s missing in my code?

Thank you in advance!

The example below displays one object:

let b = [];

function setup() {
  createCanvas(600, 600, WEBGL);
  
  for (let i = 0; i<10; i++){
    b.push(new B(i));
  }
}
function draw() {
  
  background(0);
  
    for (let i = 0; i < b.length; i++) {
    b[i].m();
    b[i].s();
  }
}

class B {
  constructor(x,y) {
    this.x = x;
    this.y = y;
    this.t = 100;
    this.speed = 0.08;
    this.rad = 10;
    }
  
  s() {
    noFill();
    stroke(255, 80);
    circle(this.x, this.y, 100); 
  }

  m() {
    this.x = this.rad * cos(this.t);
    this.y = this.rad * sin(this.t);
    this.v = 0.01;
    rotate((this.v += 1));
    this.t += this.speed;
    rotateZ(5);
      }
}

let b = [];

function setup() {
  createCanvas(600, 600, WEBGL);

  for (let i = 0; i < 10; i++) {
    b.push(new B(133, 133));
  }
}

function draw() {
  background(0);
  translate(-300, -200);
  for (let x = 0; x < 3; x++) {
    translate(130, 0);
    push();
    for (let y = 0; y < 3; y++) {
      translate(0, 130);
      push();
      for (let i = 0; i < b.length; i++) {
        //
        b[i].m();
        b[i].display();
        //
      }
      pop();
    }
    pop();
  }
}

// ================================================================

class B {
  //
  constructor(x, y) {
    let x1 = 0;
    let y1 = 0;
    this.x = x;
    this.y = y;
    this.t = 100;
    this.speed = 0.08;
    this.rad = 10;
  }

  display() {
    noFill();
    stroke(255, 80);
    circle(this.x, this.y, 100);
  }

  m() {
    this.x = this.rad * cos(this.t);
    this.y = this.rad * sin(this.t);
    this.v = 0.01;
    rotate((this.v += 1));
    this.t += this.speed;
    rotateZ(5);
  }
}
//

3 Likes

Thank you!

I need to study your code step by step to understand your use of translate(), push() and pop(). These are functions I don’t master yet.

1 Like

new version

unfortunately with a vibration I couldn’t get rid of

let b = [];
let angleY = 0;

function setup() {
  createCanvas(600, 600, WEBGL);

  for (let i = 0; i < 10; i++) {
    b.push(new Circle(0, 0));
  }
}
function draw() {
  background(0);

  rotateY((angleY += 0.0201));

  for (let x = 0; x < 3; x++) {
    for (let y = 0; y < 3; y++) {
      push();
      translate(x * 130, y * 130);
      showOneCircleGroup();
      pop();
    }
  }
}

function showOneCircleGroup() {
  for (let i = 0; i < b.length; i++) {
    b[i].calc();
    b[i].display();
    // b[i].reset();
  }
  for (let i = 0; i < b.length; i++) {
    b[i].reset();
  }
}

// =================================================

class Circle {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.t = 100;
    this.speed = 0.08;
    this.rad = 10;
  }

  display() {
    noFill();
    stroke(255, 80);
    rotate((this.v += 1));
    rotateZ(5);
    circle(this.x, this.y, 100);
  }

  calc() {
    this.x = this.rad * cos(this.t);
    this.y = this.rad * sin(this.t);
    this.t += this.speed;
    this.v = 0.01;
  }

  reset() {
    //this.t=100;
    //this.v = 0.01;
    // this.t = 100;
    this.speed = 0.08;
    this.rad = 10;
  }
}

1 Like

Hello @Alesk1969,

Very cool effect!

Scrutinize this code:

let b = [];

function setup() {
  createCanvas(600, 200, WEBGL);
  
  numCircles = 7;
  sp = 0.1/numCircles;         // Set speed proportioanal to number of circles 
  
  for (let i = 0; i<10; i++){
    b.push(new B(0, 0, sp));   // Set initial speed!
  }
}
function draw() {
  background(0);
  
  for(let j=0; j<numCircles; j++)
    {
    push();
    translate(100*j-width/2, 0);
    
    for (let i = 0; i < b.length; i++) {
      //rotate(6.01);
      b[i].m();
      b[i].s();
      rotate(6.01);
    }
    pop();
    }    
}

class B {
  constructor(x, y, sp) {
    this.x = x;
    this.y = y;
    this.t = 100;
    this.speed = sp;
    this.rad = 10;
    }
  
  s() {
    noFill();
    stroke(255, 80);
    circle(this.x, this.y, 100); 
  }

  m() {
    this.x = this.rad * cos(this.t);
    this.y = this.rad * sin(this.t);
    this.t += this.speed;
  }
}

Notes:

this.v = 0.01;
rotate((this.v += 1));
rotateZ(5);

Can be simplified to:

rotateZ(6.01);

You are applying rotations to objects and this does not need to be part of your class.

The speed needs to be adjusted and proportional to the number of circles.
Give some thought to this… it will come to you! :slight_smile:

Now you can work on a grid.

Have fun!

References:
learn | p5.js < Coordinates and Transformations is in there!

:)

1 Like

Brillant! Thank you very much for your answers and the references @Chrisir, @glv! :slight_smile:

2 Likes