Project 2: time + Space

Visualising a stoic concept through perlin noise, push/pop matrices and geometry

Anushka Sharma

INTD 350

Sympatheia

  • Influence through time/space:

    • said by Marcus Aurelius in Book Six of Meditations  "everything connects to everything else"- impetus (from project 1)

  • Visual elements:

    • Circle - "everything connects"

    • "Blue Marble" Earth (1972) that changed man's perspective on himself

Chosen concept:

Daily Stoic, "Sympatheia Medallion"

Exploring Perlin Noise

  • I followed a code tutorial and tried to understand how Perlin Noise works - although I learnt the concepts and could follow to a certain extent, it's still quite high concept for me.
    • ​Following this, I messed around with the code until I was happy with the visual.
let particles = [];
const num = 1000;

const noiseScale = 0.01/2;

function setup() {
  createCanvas(400, 400);
  for(let i = 0; i < num; i ++) {
    particles.push(createVector(random(width), random(height)));
  }
  
  stroke(255);
  // For a cool effect try uncommenting this line
  // And comment out the background() line in draw
  // stroke(255, 10);
}

function draw() {
  background(0, 10);
  for(let i = 0; i < num; i ++) {
    let p = particles[i];
    point(p.x, p.y);
    let n = noise(p.x * noiseScale, p.y * noiseScale, frameCount * noiseScale);
    let a = TAU * n;
    p.x += cos(a);
    p.y += sin(a);
    if(!onScreen(p)) {
      p.x = random(width);
      p.y = random(height);
    }
  }
}

function mouseReleased() {
  noiseSeed(millis());
}

function onScreen(v) {
  return v.x >= 0 && v.x <= width && v.y >= 0 && v.y <= height;
}

Exploring Noise + Geometry

  • I found a similar tutorial that inspired me to create the layout I wanted for my final project.
  • Taking what I learnt about geometry / trig functions in code from my last project, I was comfortable with messing around with this tutorials' code after I used it to structure my code.
  • Key difference from Project 1's Geometry: this tutorial used arc, rather than ellipses, and this code was based on p5's web editor.
let pointNum = 50;
let rectSize = 550;
function setup() {
  createCanvas(windowWidth, windowHeight);
}

function draw() {
  background("black");
  noCursor();
  noStroke();
  fill("white");
  circle(mouseX, mouseY, 5);


  //title subtitle
  push();
  translate(width / 2, height - 50);
  textFont("Arial");
  textSize(10);
  stroke("gold");
  textAlign(CENTER, CENTER);
  text("Sympatheia.", 0, -10);
  text(
    "the belief in mutual interdependence among everything in the universe: that we are all one.",
    0,
    5
  );
  textAlign(CENTER, CENTER);
  text("Marcus Aurelius", 0, -470);
  pop();

  //square border
  push();
  translate(width / 2, height / 2);
  noFill();
  stroke("gold");
  strokeWeight(2);
  rectMode(CENTER);
  rect(0, 0, rectSize, rectSize);

  //random noise in background
  stroke("gold");
  strokeWeight(1);
  for (let i = 0; i < pointNum; i++) {
    point(
      random(-rectSize / 2, rectSize / 2),
      random(-rectSize / 2, rectSize / 2)
    );
  }
  pop();
}

Exploratory Research:

More perlin noise

These were some of the tutorials I watched trying to understand the Noise function. I find Flow Fields and Perlin Noise beautiful, especially for generative art, but it's still super high concept for me.

End result:

let particles = []; // creating array for particles
const num = 800; // number of particles
let rectSize = 550;
let gap = 20;
let cirNum = 20;
let cirSize = 20;
let angle = 0;
let pointNum = 50;

const noiseScale = 0.05; // scale down values picking at n for more zoomed in visual

function setup(){
  createCanvas(windowWidth,windowHeight);
  for(let i = 0; i < num; i ++) { // placing particles randomly on screen w for x, h for y
    particles.push(createVector(random(width), random(height)));
  } 
  stroke("gold");
  strokeWeight(1.5);
  angleMode(degrees);
}

function draw() {
  background(0,12); // fade to show overlay 
  for(let i = 0; i <num; i ++) { // draw dot on screen at point of vector rather than push a new vector
    let p = particles[i];
    point(p.x, p.y);
    // get noise value and then convert to an angle
    let n = noise(p.x * noiseScale, p.y*noiseScale);
    let a = TAU * 1/n;// TAU = 2Pi N=n+5 looks like rain / water
    p.x += cos(a);
    p.y += sin(a); // convert angle into x and y
    if(!onScreen(p)){ // if particle isn't on screen, random position = once its off screen randomly generates new ones
      p.x = random(width); // particle coords
      p.y = random(height);
    }
  }

  push();
  translate(width/2, height/2);
  fill(0,150);
  stroke("gold");
  strokeWeight(3);
  rectMode(CENTER);
  rect(0,0,rectSize, rectSize);
  pop();


  push();
  translate(width/2, height/2);
  textFont("Courier New");
  textSize(12);
  stroke('gold');
  strokeWeight(0.7);
  fill("white");
  textAlign(CENTER, CENTER);
  text("Sympatheia.", 0, 300);
  text(
    "the belief in mutual interdependence among everything in the universe: that we are all one.",
    0,
    325
  );
  textAlign(CENTER,CENTER);
  text("Marcus Aurelius", 0,-325);
  text("Book Six of Meditations",0,-300);
  pop();


  //main graph circles
  push();
  translate(width / 2, height / 2);
  //rotate(angle);
  //angle = map(mouseX,0,width,-90,90);
  angle = angle + map(mouseX, 0, width, -0.03, 0.03);
  noFill();
  stroke("gold");
  strokeWeight(1);
  for (let i = 0; i < cirNum; i++) {
    arc(0, 0, cirSize + gap * i, cirSize + gap * 8, angle * 2, 180 + i * angle);
  }
  pop();

}


function mouseReleased(){
noiseSeed(millis()); // goes to new noise when pressed
}


//check if vector is off screen - i don't really know how this
function onScreen(v) {
  return v.x >= 0 && v.x <= width && v.y >= 0 && v.y <= height;
}

frankenstein-ed both codes + tweaked them into my specific vision