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