Captivating Charm: Exploring Marseille's Hillside Villas with Our 3D Architec...
Procedural Art
1. //OLIVIA MEREDITH - 13510110 - BOND UNIVERSITY
//MMDE11-300_173 (SKETCHING WITH CODE)
//ASSIGNMENT #2 - PROCEDURAL ARTWORK
//NOTE: Minim (an audio library that provides the ability to work with sound) is utilised in this code
//for the full experience, it's recommended that this code is played with sound on
//setting up the capacity to interact with audio files
import ddf.minim.*; //imports minim library which enables interaction with audio files
Minim minim;//loading class of minim
AudioPlayer BGBeats;//similar to declaring a PImage for loading but for an audio file - the background beats
import processing.pdf.*; //imports library for print to pdf functionality
//declaring image variables (reserving space in memory)
PImage Face;//symmetrical face illustration - 1040x670
PImage ThirdEye;//single eye with triangle on top illustration - 800x800
PImage ThirdEyeTri;//eye in triangle with flowers illustration - 720x720
//background related variables
PImage TriBG;//loads the triangle background image - 1920x1080
PImage StripeyBG;//loads the pink and dark brown stripey background image formed by TriBG - 1920x1080
float BGy;//variable of type float used for TriBG's downward movement along the y-axis
float speed = 30;//larger number = TriBG to move faster + bigger little triangles between columns
color c1[] = {#88668E,#5ACA8D,#EACA44,#E8CCB4};//[0] is purple, [1] is green, [2] is yellow, [3] is cream
float ctransition = 0;//for main tree - declaring a variable of type float and assigning a value of 0 for the amount of lerp for colour transtions
int transDir = 1;//direction manager for colour lerping / transitions
float ctransition1 = 0;//for all other uses - declaring a variable of type float and assigning a value of 0 for the amount of lerp for colour transtions
int transDir1 = 1;//direction manager for colour lerping / transitions
float r1 = 0;//first round of concave and convex flashing bubbles
float r2 = 0;//second round of concave and convex flashing bubbles
float r3 = 0;//third round of concave and convex flashing bubbles
2. int iR = 0;//used for yellow 90 degree rotating "trees"
int rectangleHeight = 50;//variable of type integer to increase height of the vertical green rectangles coming down from y=0
int rectangleHeight1 = 50;//variable of type integer to increase height of the vertical cream rectangles coming down from y=0
int thirdEyeSize = 100;//variable of type integer with 100 as the starting size of the image, used for the ThirdEye growing in size
int thirdEyeTSize = 200;//variable of type integer with 200 as the starting size of the image, used for the ThirdEyeTri growing in size
int shrinkOrGrow = 0;//variable of type integer used for the pulsating effect for ThirdEye
//an array of the string data type (char), then referenced by in index and the random() function
String [] words = {"enhanced", "high", "conscious", "realisation", "slow vibration", "we are all one", "energy condensed",
"life is only a dream", "the imagination of ourselves", "keep it in mind", "dreaming again",
"grinning wide", "comforting", "warm and wild eyes", "tumbling", "rising up", "wiping the webs",
"in... out...", "stuck in my head","good to see you again", "prying open my third eye", "a trail of smoke and reason"}; //words from Tool's song "Third Eye"
void setup()
{
//size(9933, 7016, PDF, "Final.pdf");//A1 print resolution
size(1920,1080);//specifies size of canvas - 1920x1080
minim = new Minim(this);//passes this to minim so it can load files from the data directory
BGBeats = minim.loadFile("Papercut_TheBlock41.mp3");//loads an audio file and assigns it to "BGBeats" - https://soundcloud.com/otodayo/papercut-the-
block (royalty free)
BGBeats.play();//audio file will play
TriBG = loadImage("TriangleBG.png");//loads the triangle background image - 1920x1080
StripeyBG = loadImage("StripeyBG.png");//loads the pink and dark brown stripey background image formed by TriBG - 1920x1080
Face = loadImage("Face_S.png");//symmetrical face illustration - 1040x670
ThirdEye = loadImage("ThirdEye.png");//single eye with triangle on top illustration - 800x800
ThirdEyeTri = loadImage("ThirdEye_Detailed.png");//eye in triangle with flowers illustration - 720x720
//smooth(5);//anti-aliasing although a strength of 5 is the default and built into Processing v.3
//frameRate(60);//(default is 60)
beginRecord(PDF,"ProceduralArtwork.pdf");//opens a new file and begins recording the functions that follow to that file
3. image(TriBG,0,BGy);//draws the BG image as soon as the program is run (movement then occurs over the top)
}
//function for the main tree - setting up recursion
void treeBranch(float h)
{
stroke(lerpColor(c1[0],c1[1],ctransition));//colour of the lines is lerped between purple and green
strokeWeight(2);//weight or thickness of the lines
h *= 0.6;//each branch will be 2/3rds the size of the previous one
//as this is a recursive function, there must be a condition of exit otherwise the function would continue working and the program would crash
if (h > 2)//if the length of the branch is 2 pixels or less...
{
//branching off to the right
pushMatrix();//saves the position
rotate(radians(45));
line(0, 0, 0, -h);//draws the branch
translate(0, -h);//moves the coordinate system to the end of the previously drawn branch
treeBranch(h);//draws two new branches
popMatrix();//restores to previous matrix state
//same as above although branching off to the left
pushMatrix();//saves the position
rotate(radians(-45));
line(0, 0, 0, -h);
translate(0, -h);
treeBranch(h);//draws two new branches
popMatrix();//restores to previous matrix state
}
}
//function for the main tree - referenced in void draw
void drawBranches1(int xdB, int ydB)//based off Daniel Shiffman's "Recursive Tree"
{
4. pushMatrix();//saves the current coordinate system
translate(xdB,ydB);//moves the coordinate system to (xdB, ydB)
treeBranch(500);//starts the recursive branching
popMatrix();//restores the prior coordinate system
}
//function for the yellow scaled 90 degree variant
void ninetyDegree(float h)//based off Daniel Shiffman's "Recursive Tree"
{
stroke(lerpColor(c1[0],c1[2],ctransition1));//colour of the lines is lerped between purple and yellow
strokeWeight(2);//weight or thickness of the lines
h *= 0.6;//each branch will be 2/3rds the size of the previous one
//as this is a recursive function, there must be a condition of exit otherwise the function would continue working and the program would crash
if (h > 2)//if the length of the branch is 2 pixels or less...
{
//branching off to the right
pushMatrix();//saves the position
rotate(radians(90));
line(0, 0, 0, -h);//draws the branch
translate(0, -h);//moves the coordinate system to the end of the previously drawn branch
ninetyDegree(h);//draws two new branches
popMatrix();//restores to previous matrix state
//same as above although branching off to the left
pushMatrix();//saves the position
rotate(radians(-90));
line(0, 0, 0, -h);
translate(0, -h);
ninetyDegree(h);//draws two new branches
popMatrix();//restores to previous matrix state
}
}
//function for the yellow scaled 90 degree variant
5. void ninetyDegreeTree(int xdB2, int ydB2)//based off Daniel Shiffman's "Recursive Tree"
{
pushMatrix();
translate(xdB2,ydB2);
rotate(radians(45));
ninetyDegree(500);//starts the recursive branching
popMatrix();
}
void draw()//continuously loops
{
int m = millis();
println("millis = " + m);
println("frame count = " + frameCount);
if(BGy == 0 || BGy <= height)
{
BGy = BGy + speed;//adds speed to the variable to create movement on the y-axis
tint(255,127);//sets the image's alpha to be 50% transparent
image(TriBG,0,BGy);//triangles move down the y-axis to form stripey background
}
//if(frameCount >= 16 && frameCount <= 36)
if(BGy >= height)//when TriBG reaches the bottom of the canvas...
{
tint(255);//resets the alpha / opacity level back to the default of 100% (not transparent)
image(StripeyBG,0,0);//draws the stripey background image
pushMatrix();
drawBranches1(960,740);//utilises the tree function and draws one above the face
popMatrix();
image(Face,440,410);//displays face illustration at the bottom middle point of the canvas
}
if(frameCount >= 35 && frameCount <= 75)
6. {
image(StripeyBG,0,0);//draws the stripey background image
image(Face,440,410);//displays face illustration at the bottom middle point of the canvas
pushMatrix();
drawBranches1(960,740);//utilises the tree function and draws one above the face
ctransition+=0.2*transDir;//increases in 0.05 increments in the specified direction with each draw call
if(ctransition > 1) transDir = -1;//loops the lerping transition between purple and green
if(ctransition < 0) transDir = 1;//(transitions forward until it reaches the end and then goes backwards)
popMatrix();
image(Face,440,410);//displays face illustration on top of the tree pushMatrix();
}
//dense concave curves out from centered point
if(frameCount >= 58)//roughly 10300 millis
{
pushMatrix();
translate(960,400);
for(float t = 0; t < 100; t+= 0.05)
{
float sX = r1/cos(t);
float sY = r1/sin(t);
r1 += 0.02;//radius
int c = c1[(int)random(0,3)];//random colour from array
fill(c);
noStroke();
if(random(100) < 50)
ellipse(sX,sY,5,5);
else
ellipse(sX,sY,15,15);
}
popMatrix();
}
7. //circle from center (based on textspiral.pde)
if(frameCount >= 63)//12100 millis
{
pushMatrix();
translate(960,400);
for(float t = 0; t < 2*PI; t+= 0.05)
{
float sX = r1*cos(t);
float sY = r1*sin(t);
r1 += 0.02;//radius
fill(lerpColor(c1[0],c1[1],ctransition1));//colour of the lines is lerped between purple and green
ctransition1+=0.1*transDir1;//increases in 0.05 increments in the specified direction with each draw call
if(ctransition1 > 1) transDir1 = -1;//loops the lerping transition between purple and green
if(ctransition1 < 0) transDir1 = 1;//(transitions forward until it reaches the end and then goes backwards)
noStroke();
if(random(100) < 50)//if random number is less than 100...
ellipse(sX,sY,5,5);
else
ellipse(sX,sY,15,15);
}
popMatrix();
}
//second circle from center (based on textspiral.pde)
if(frameCount >= 66 && frameCount <= 78)
{
pushMatrix();
translate(960,400);
for(float t = 0; t < 50; t+= 0.05)
{
float sX1 = r2*cos(t);
float sY1 = r2*sin(t);
r2 += 0.02;
8. fill(lerpColor(c1[0],c1[1],ctransition1));//colour of the lines is lerped between purple and green
noStroke();
if(random(100) < 50)
ellipse(sX1,sY1,5,5);
else
ellipse(sX1,sY1,15,15);
}
popMatrix();
}
if(frameCount >= 78)
{
if(thirdEyeSize < 360)
{
thirdEyeSize += 10;
}
imageMode(CENTER);
image(ThirdEye, 960, 395, thirdEyeSize, thirdEyeSize);
imageMode(CORNER);
pushMatrix();
translate(960,400);
for(float t = 0; t < 2*PI; t+= 0.1)
{
float sX = r2/cos(t);
float sY = r2/sin(t);
r2 += 0.05;
int c = c1[(int)random(0,3)];
fill(c);
//noStroke();
if(random(100) < 50)
9. ellipse(sX,sY,5,5);
else
ellipse(sX,sY,15,15);
}
popMatrix();
}
if(frameCount >= 100)
{
rectangleHeight += 15;//rectangle gets 10 pixels longer with each draw call
fill(c1[1]);//green
rectMode(CENTER);//shape is placed with the specified coordinates at its center
rect(436,0,22,rectangleHeight);//left side
rect(1484,0,22,rectangleHeight);//right side
rectangleHeight1 += 20;//rectangle gets 15 pixels longer with each draw call
fill(c1[3]);//cream
noStroke();//no outline
rect(400,0,10,rectangleHeight1);
rect(1520,0,10,rectangleHeight1);
}
if(frameCount >= 116 && frameCount <= 150)
{
iR+=5;//add to the variable with each draw call, which increases the rotation
//rotating tree left
pushMatrix();
translate(350,350);
rotate(radians(iR));
scale(0.3);
ninetyDegreeTree(0,0);
popMatrix();
//rotating tree right
10. pushMatrix();
translate(1570,350);
rotate(radians(iR));
scale(0.3);
ninetyDegreeTree(0,0);
popMatrix();
}
if(frameCount >= 121 && frameCount <= 150)
{
//yellow expanding circle made from rectangles of varying lengths - left side
pushMatrix();
translate(350,350);
for(float t = 0; t < 2*PI; t+= 0.2)//t = speed
{
float sX = r3*cos(t);
float sY = r3*sin(t);
r3 += 0.05;
fill(c1[2]);
noStroke();
if(random(100) < 70)
rect(sX,sY,-60,-2.5);
if(random(100) < 35)
rect(sX,sY,-40,-2.5);
else
rect(sX,sY,-20,-2.5);
}
popMatrix();
//yellow expanding circle made from rectangles of varying lengths - right side
pushMatrix();
translate(1570,350);
for(float t = 0; t < 2*PI; t+= 0.2)//t = speed
11. {
float sX = r3*cos(t);
float sY = r3*sin(t);
r3 += 0.05;
fill(c1[2]);
noStroke();
if(random(100) < 70)
rect(sX,sY,-60,-2.5);
if(random(100) < 35)
rect(sX,sY,-40,-2.5);
else
rect(sX,sY,-20,-2.5);
}
popMatrix();
}
if(frameCount >= 140)
{
// draw the waveforms
// the values returned by left.get() and right.get() will be between -1 and 1,
// so we need to scale them up to see the waveform
//as the file is MONO, left.get() and right.get() return the same value, so left.get() has been used to simplify
for(int iA = 0; iA < BGBeats.bufferSize() - 1; iA++)
{
pushMatrix();
float yA1 = map(iA, 0, BGBeats.bufferSize(), 0, height);
float yA2 = map(iA+1, 0, BGBeats.bufferSize(), 0, height);
stroke(lerpColor(c1[0],c1[3],ctransition1));
strokeWeight(2);
line(87.5 + BGBeats.left.get(iA)*50, yA1, 87.5 + BGBeats.left.get(iA+1)*50, yA2);//far left
line(1832.5 + BGBeats.left.get(iA)*50, yA1, 1832.5 + BGBeats.left.get(iA+1)*50, yA2);//far right
popMatrix();
}
12. }
if(frameCount >= 150)
{
stroke(c1[2]);//yellow
strokeWeight(5);
line(370,0,370,1080);//left side
line(1550,0,1550,1080);//right side
}
if(frameCount >= 172 && frameCount <= 196)
{
float t2 = (frameCount % 100) * 0.01;//animated at 1% of the frame count
float xBL2 = bezierPoint(960,736,185,185,t2);//left curve - middle - x-coordinates
float yBL2 = bezierPoint(590,-153,195,1080,t2);//left curve - middle - y-coordinates
float xBL3 = bezierPoint(960,694,316,311,t2);//left curve - bottom - x-coordinates
float yBL3 = bezierPoint(590,13,349,1080,t2);//left curve - bottom - y-coordinates
float xBR2 = bezierPoint(960,1184,1736,1736,t2);//right curve - middle - x-coordinates
float yBR2 = bezierPoint(590,-153,195,1080,t2);//right curve - middle - y-coordinates
float xBR3 = bezierPoint(960,1227,1610,1610,t2);//right curve - bottom - x-coordinates
float yBR3 = bezierPoint(590,13,349,1080,t2);//right curve - bottom - y-coordinates
pushMatrix();
fill(c1[3]);//fills shapes and makes text a cream colour
textSize(noise(random(50))*50); //perlin noise text size (scaled by 50)
textAlign(CENTER);//text is drawn with the specified coordinates at its center
int index = int(random(words.length));//same as int(random(10))
text(words[index], xBL2, yBL2);//places random words from a predefined string at coordinates along the middle-left bezier
text(words[index], xBR2, yBR2);//places random words from a predefined string at coordinates along the middle-right bezier
fill(c1[2]);//fills shapes and makes text a yellow colour
ellipse(xBL3,yBL3,20,20);//places an ellipse that follows the coordinates of the bottom-left bezier
13. ellipse(xBR3,yBR3,20,20);//places an ellipse that follows the coordinates of the bottom-right bezier
popMatrix();
}
if(frameCount >= 183 && frameCount <= 196)
{
//pulsating
pushMatrix();
translate(960,395);
if (thirdEyeSize > 360) {
shrinkOrGrow = 0;
} else if (thirdEyeSize < 360) {
shrinkOrGrow = 1;
}
if (shrinkOrGrow == 1) {
thirdEyeSize += 1;
} else if (shrinkOrGrow == 0) {
thirdEyeSize -= 1;
}
tint(lerpColor(c1[0],c1[3],ctransition1), 157);
imageMode(CENTER);
image(ThirdEye, 0, 0, thirdEyeSize, thirdEyeSize);
imageMode(CORNER);
popMatrix();
for(int iA = 0; iA < BGBeats.bufferSize() - 1; iA++)
{
pushMatrix();
float yA1 = map(iA, 0, BGBeats.bufferSize(), 0, height);
float yA2 = map(iA+1, 0, BGBeats.bufferSize(), 0, height);
stroke(lerpColor(c1[0],c1[3],ctransition1));
strokeWeight(2);
line(262.5 + BGBeats.left.get(iA)*30, yA1, 262.5 + BGBeats.left.get(iA+1)*30, yA2);//inner left
line(1657.5 + BGBeats.left.get(iA)*30, yA1, 1657.5 + BGBeats.left.get(iA+1)*30, yA2);//inner right
popMatrix();
14. }
}
if(frameCount >= 200)
{
if(thirdEyeTSize < 450)//growth of image will continue until it is 450x450px
{
thirdEyeTSize += 40;//increases by 40px each draw loop
}
tint(255);//fully opaque
imageMode(CENTER);//draw based on the coordinates at the image's center
image(ThirdEyeTri, 950, 365, thirdEyeTSize, thirdEyeTSize);//solid image beneath to cover anything behind
tint(c1[0], 127);//purple tint at 50% opacity
image(ThirdEyeTri, 950, 365, thirdEyeTSize, thirdEyeTSize);//tinted semi-transparent image
imageMode(CORNER);//reverts image placement back to the default
}
//timer for testing purposes
/*pushMatrix();
textSize(24);
text("millis = " + m, 100,50);
text("frame count = " + frameCount, 100, 150);
popMatrix();*/
}
void keyPressed()//simple function based off week 9 practical practice question #10
{
if(key == 's')//if the "s" key is pressed...
{
endRecord();//the process of recording to a PDF will be completed and the file will be closed
}
}