mouseX rotates and changes the size of the hypocycloid (thicker lines, filled shape). mouseY corresponds with n, which essentially determines the complexity of the curves. it took me a while to finish this because I was having too much fun spacing out while playing with it…
// jaden luscher
// jluscher@andrew.cmu.edu
// section a
// project 07: composition with curves
// HYPOCYCLOID PEDAL CURVE + ROSE CURVE
// INITIALIZING VARIABLES
var nPoints = 250;
var n;
var a;
var q;
function setup() {
createCanvas(400, 400);
background(200);
frameRate(30);
}
function draw() {
background("orange");
noFill();
q = constrain((mouseX / width), 0.1, 1.0);
p = constrain((mouseY / height), 0.1, 1.0);
n = int(p * 100); // n corresponds to the curves' complexity
a = int(width * p * 10); // "radius" of rose curve increades with mouseY
var c = 155 + (q * 100); // fill color for hypocycloid
translate (width/2, height/2);
strokeWeight(q *20); // stroke of hypocycloid corresponds to mouseX
stroke("white");
fill(c, 0, c, 5);
for (i = 0; i < nPoints/10; i++) {
drawHypocycloid();
a = a *sqrt(q) - width*q; // sqaure root causes many curve sizes to "cross"
}
a = int(width * p * 10); // "radius" of rose curve increades with mouseY
stroke("white");
strokeWeight(0.5);
rotate(PI * q); // rose curve spins with mouseX
drawRoseCurve();
}
function drawHypocycloid() {
// hypocycloid pedal curve:
// https://mathworld.wolfram.com/HypocycloidPedalCurve.html
push();
var x;
var y;
var r;
beginShape();
for (var i = 0; i < nPoints; i++) {
var t = map(i, 0, nPoints, 0, TWO_PI);// sweep theta from 0 to two pi
// hypocycloid:
r = q * (n-2) * ((sin * (n / (n-2))) * (t + PI/2));
x = a * (((n-1) * cos(t) + cos((n-1) * t)) / n);
y = a * (((n-1) * sin(t) + sin((n-1) * t)) / n);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
function drawRoseCurve() {
// rose curve
// https://mathworld.wolfram.com/RoseCurve.html
push();
var x;
var y;
var r;
beginShape();
for (var i = 0; i < nPoints; i++) {
var t = map(i, 0, nPoints, 0, TWO_PI);// sweep theta from 0 to two pi
r = a * p * cos(n * t);
// pasted from hypercycloid
x = r * cos(t);
y = r * sin(t);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
In Stefanie Posavec’s piece “art.park.data” she combines the unpredictability of childhood experience and nature with statistical/graphical representation. Each child was given a “Raspberry Pi” device, which aided in recording various data sets in the park: temperature, humidity, types of plants spotted, sounds heard, emotions, and others. The children were then tasked to supply this data per each latitude/longitude coordinate in order to create the mural.
The artwork, a 32.5m long data visualization displayed for the East London Canvas, is impressive to me because it effectively incorporates an aspect of the human experience with statistics. It also presents the data in an aesthetically pleasing way, with complimenting colors and shapes. While data is often confined to graphs or charts, this artwork offers a new perspective into data presentations, encouraging the observer to connect with outside ideas more effectively.
A project that I find interesting is the Dall-E mini software that became vary popular this year. The way that it works is using AI software to generate images from any prompt. Many people used this for comedy, because the software is able to make any image typed, even if it’s impossible to actually occur. Randomness is involved in the way that the photos compile themselves with the AI software. The programming works in order to generate prompts with information that developers have given to the website. I really admire this project because it’s quite fun to compile images into something that isn’t actually possible to create something impossible, which is creative and unique design. Many of my friends have made amusing things with it, and I find it so interesting that computing was used in order to randomly generate any prompt that someone may think of into a picture.
//dvargas David vargas
var starX=[] //x position of stars
var starY=[]//y position of stars
var starB=[]//brightness value of stars
var hourV = {x:0,y:0,diam:50,c:'orange'} //array w/values for orange (hours) circle
var minuteV = {x:0,y:0,diam:30,c:'lightgreen'}//array w/ values for green (minutes) circle
var secondV = {x:0,y:0,diam:10,c:'lightblue'} //array w/ values for blue (seconds) circle
var orbitV ={hX:300,hY:300,mX:0,mY:0,sX:0,sY:0,hD:180,mD:150,sD:75} //array w/ values for 'orbit rings'
var noiseOffset=0 //perlin noise offset
function setup() {
createCanvas(600, 600);
background(255);
for (var i=0;i<80;i++){ //creates random stars
starX[i]=random(0,width)
starY[i]=random(0,height)
}
}
function draw() {
background(0);
var theTime=currentTime() //the time represented by a value between 0 & 12
for(var i=0;
Bauer’s random art generator utilizes pseudo-random numbers to construct a mathematical formula. This formula is responsible for each pixel color and sequence of random choices. I really admire the semi formed appearance of Bauer’s pieces. Though random, his series have a particular look and create distinct, colorful visuals. His generator is able to transform into completely new and unique pieces with one word change in the program. I appreciate the versatility. For example, this particular piece, can be interpreted in many different ways; for me, it looks like a stingray.The artist uses an acyclic directed graph coded in the python coding language and implemented in ocaml.
I was inspired by Tyler Hobbs’s watercolor paintings that I found in his article “How to Hack a Painting.” I specifically looked at his piece Linear II (Welcome Back) which looks like watercolor. I thought his piece was really cool because he had to use a lot of intentional layering and calculations to get that watercolor effect but he also used a bit of randomness to keep it interesting.
His artistic senses are really shown because watercolor is very flowy. This contrasts from coding on a computer where everything is defined and it seems hard to get it flowly. However, watercolor is usually slightly random because the paint flows and spreads based on the water and the paper.
For the main shape, he makes rough edges by including very tiny details. So, it appears to be textured. Combining these with a low opacity, it creates the edges that give the signature watercolor effect.
It is interesting because he described how there is, “a lot of carefully applied randomness in these [pieces].” So, he artfully sprinkles randomness in his paintings so that we would see something different each time.
Here is the link to the piece: Linear II (Welcome Back), 2017, Tyler Hobbs
Anders Hoff’s “Impossible Architecture” (2018) is an experiment in morphing a 2D, outline of a rectangle to create a completely random “floor plan”. These insane-looking pseudo-floor plans are mostly impossible to construct, but as we look at them we attempt to make sense of them. They look convincing, with the addition of more randomly generated elements – circles, line arrays, and thick lines that we perceive as columns, stairs, and thickened walls, respectively.
He explains this recursive process on his website: a randomly selected segment of a line is extruded to a random distance, which essentially adds 3 line segments to the outline. The selected line segment is then deleted, and the process repeats. This recursion speaks for Hoff’s principles of creating “interesting and complex behavior” from systems with simple rules. He takes inspiration from nature, geometry, writing systems, and – as is obvious from this experiment – architecture.
// jaden luscher
// jluscher@andrew.cmu.edu
// section a
// project-06: abstract clock
// EGG CLOCK
// the egg clock counts hours as eggs cracked in the pan,
// months as eggs in the carton, and minutes as the rotation of the pan.
// INITIATING VARIABLES
var xYolk = 0; // first yolk starts north-facing
var yYolk = 40; // distance between yolk and center of pan
var hr;
var mo;
function setup() {
createCanvas(400, 300);
noStroke();
angleMode(DEGREES);
frameRate(10);
}
function draw() {
background(240);
translate(150, 150); // center of pan
hr = hour() % 12; // convert 24 hour clock to 12
mo = month();
stovetop();
// EGG WHITE
fill(255);
ellipse(0, 0, randomGaussian(110,1));
// EGG YOLK
push();
for (var i = 0; i <= hr; i++) {
eggYolk(xYolk, yYolk);
rotate(360 / hr);
}
pop();
// EGG CARTON
eggcarton();
monthcounter();
}
function stovetop() {
// SHADOWS
push();
fill(220);
rect(90, 90, -15, -240);
rect(-90, 90, -15, -240);
rect(90, 90, -240, -15);
// GRATES
noFill();
strokeWeight(4);
stroke(120);
line(-150, 90, 90, 90);
line(-150, 0, 90, 0);
line(-150, -90, 90, -90);
line(90, 90, 90, -150);
line(0, 90, 0, -150);
line(-90, 90, -90, -150);
pop();
// PAN
push();
fill(150); // grey for pan
rotate(minute()*6);
minutecounter();
ellipse(0, 0, 140); // pan outer circle
fill(120);
ellipse(0, 0, 130); // pan inner circle
pop();
}
function eggYolk(xYolk, yYolk) {
fill(255, 180, 0);
ellipse(xYolk + noise(-1, 1), yYolk + noise(-1, 1), random (18, 20));
}
// PAN HANDLE ROTATES 360 DEGREES BY THE HOUR
function minutecounter() {
push();
fill(220, 20, 20);
rect(-8, -80, 16, -50);
ellipse(0, -130, 16);
pop();
rect(-6, 0, 12, -80);
}
function eggcarton() {
push();
fill(240, 230, 210); // light grey
rect(145, -95, 70, 190);
fill(220, 220, 210); // darker grey
rect(215, -95, 35, 190);
translate(165, -75);
var x = 0;
var y = 0;
// EMPTY EGG CARTON (GREY DOTS)
for (var j = 0; j < 2; j++) {
for (var i = 0; i < 6; i++) {
ellipse(x, y, 28);
y += 30;
}
y = 0;
x += 30;
}
pop();
}
function monthcounter() {
push();
translate(165, -75);
fill(255);
var x = 0;
var y = 0;
// EGGS FOR JANUARY TO JUNE
for (var j = 0; j < constrain(mo, 0, 6); j++) {
ellipse(x, y, 22);
y += 30;
}
// EGGS FOR MONTHS JULY TO DECEMBER
y = 0;
x += 30;
for (var j = 6; j < mo; j++) {
ellipse(x, y, 22);
y += 30;
}
pop();
}
I really like June Lee’s Cubic Tower, and I found randomness in their design. The reason why I admire their work on using randomness in computational design (this time is Grasshopper), while the randomness is still controllable. For example, they use boundaries and populate geometry to get computed random points inside the extruded square base using seeds, then they are able to create smaller cubes with only 3 different sizes using the Octree functions, which creates cubes by determining how dense the points are in the area, to be the components of the tower. Even after creating the randomness (that is inside a boundary), they are still able to add details afterward by using functions that turn the mess into individual components. Even after creating the cluster of computer generated randomness, they are still able to split the randomness randomly to add different materials towards the final product. I was really amazed by their ability to fully control the randomness even after already initializing the random points.
/*
* Andrew J Wang
* ajw2@andrew.cmu.edu
* Section A
* Project-05
*
* This program draws clock
*/
//set randam numbers for the wavy lines of reflection of the sun
var rando = 0;
//set sin values for waving reed
var drR=0;
function setup() {
createCanvas(480,480);
background(255);
}
function draw() {
//get dates for hours, minutes, seconds,and miliseconds
var dt = new Date();
//get location for ducks (MINUTES)
var dx=480-dt.getMinutes()*8-dt.getSeconds()*8/60;
//get location for the sun (HOURS)
var dy=(18-dt.getHours()-dt.getMinutes()*1/60-dt.getSeconds()*1/3600)*300/12;
//background
background(80,50,180);
//create reflection of the sun
if (dy>-125 & dy<425)
{
sunReflection (dy);
push();
//hiding the additional parts above sea level
fill (80,50,180);
rect(100,200,280,100);
pop();
}
//show moon between 6PM to 6AM
if (dy<62)
{
moon (300+dy,125);
}
else if (dy>238)
{
moon ((dy-300),125);
}
//create moutains and their reflections
moutain(-50,300,150,100);
moutainReflection(-50,300,150,75);
moutain(50,300,110,50);
moutainReflection(50,300,110,37.5);
moutain(350,300,250,50);
moutainReflection(350,300,250,37.5);
//gradiant sky and sea
gradiantScreen (0,300);
gradiantScreenReverse (300,600);
//draw horizon
stroke(255);
strokeWeight(1);
line (0,300,width,300);
//set sun between 6AM to 6PM
if (dy>-125 & dy<425)
{
sun(dy,125);
}
//creating lands
land2(-100,480,500,50);
land(-200,480,400,75);
//creating clouds (SECONDS)
clouds();
//creating ducks
duck(dx,350);
duck(dx+480,350);
duck(dx-480,350);
//creating reeds
reed2();
reed();
}
//gradiant sky
function gradiantScreen (y1,y2)
{
//for loop changing alpha values for small rectangles
for (var k=0; k<(y2-y1); k++)
{
noStroke();
fill (255,220,220,150/(y2-y1)*k);
rect (0,y1+k,width,1);
}
}
//gradiant sea but the same as gradiant sky but in reverse
function gradiantScreenReverse (y1,y2)
{
for (var k=0; k<(y2-y1); k++)
{
noStroke();
fill (255,220,220,180/(y2-y1)*k);
rect (0,y2-k,width,1);
}
}
//creating sun
function sun (y,r)
{
fill(255,255,180);
//outline of the sun
strokeWeight(5);
stroke(255,255,230,50);
var angle = acos((300-y)/(r/2));
//make arc if parts of the sun is below horizon
if (300-y<=r/2)
{
arc (width/2,y,r,r,-(Math.PI/2-angle)+Math.PI ,2*Math.PI + (Math.PI/2-angle),OPEN);
}
//dont make arc if it is not
else
{
circle(width/2,y,r);
}
}
//creating moon same as sun but having a different arc/circle for the missing piece
function moon (y,r)
{
fill(255,255,180);
strokeWeight(0);
stroke(255,255,230,50);
var anglem1 = acos((300-y)/(r/2));
var anglem2 = acos((300-y+20/Math.sqrt(2))/(r/2-20));
if (Math.abs(300-y)<r/2)
{
arc (width/2,y,r,r,-(Math.PI/2-anglem1)+Math.PI ,2*Math.PI + (Math.PI/2-anglem1),OPEN);
//the missing piece
if (300-y+20/Math.sqrt(2)<=(r/2-20))
{
push();
fill(80,50,180);
arc (width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40,r-40,-(Math.PI/2-anglem2)+Math.PI ,2*Math.PI + (Math.PI/2-anglem2),OPEN);
pop();
}
else
{
push();
fill(80,50,180);
circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
pop();
}
}
else
{
circle(width/2,y,r);
push();
fill(80,50,180);
//the missing piece
circle(width/2+20/Math.sqrt(2),y-20/Math.sqrt(2),r-40);
pop();
}
}
//mountain reflection using bezier
function moutainReflection(mx,y,w,h)
{
fill(0,0,255);
strokeWeight(0);
bezier(mx,y,mx,y+h,mx+w,y+h*2,mx+w,y);
}
//mountaini using benzier
function moutain(mx,y,w,h)
{
fill(0,0,255);
stroke(255,255,230,50);
strokeWeight(2);
bezier(mx,y,mx,y-h,mx+w,y-h*2,mx+w,y);
}
//making clouds
function clouds()
{
fill(255,255,255,75);
//getting seconds and milliseconds
var dt = new Date();
var x=dt.getSeconds()*8+dt.getMilliseconds()*0.008;;
var y=480;
push()
translate (0,30);
//original moving clouds
rect(-50+x,120,200,30,15);
rect(-70+x,155,150,20,10);
rect(-100+x,100,150,16,8);
//clones to make the animation look smooth
rect(-50+x+y,120,200,30,15);
rect(-70+x+y,155,150,20,10);
rect(-100+x+y,100,150,16,8);
rect(-50+x-y,120,200,30,15);
rect(-70+x-y,155,150,20,10);
rect(-100+x-y,100,150,16,8);
//original moving clouds
rect(200+x,20,250,30,15);
rect(350+x,50,150,20,10);
//clones to make the animation look smooth
rect(200+x-2*y,20,250,30,15);
rect(350+x-2*y,50,150,20,10);
rect(200+x-y,20,250,30,15);
rect(350+x-y,50,150,20,10);
//seconds indicator circles
fill(255);
circle(0+x,120,20);
circle(0+x-y,120,20);
circle(0+x+y,120,20);
pop();
}
//create reflection of the sun using noice function to make it expand
function sunReflection (y)
{
rando+=0.01;
push()
fill (255,255,255,180);
strokeWeight(0);
stroke (255,255,255,180);
rectMode(CENTER);
rect(width/2,300+(300-y)/2,noise(rando)*50+125,4,2);
rect(width/2,300+(300-y)/2+8,noise(rando*2)*50+75,4,2);
rect(width/2,300+(300-y)/2-8,noise(rando-1)*50+75,4,2);
rect(width/2,300+(300-y)/2+16,noise(rando-0.5)*50+40,4,2);
rect(width/2,300+(300-y)/2-16,noise(rando+0.5)*50+40,4,2);
pop()
}
//land darker
function land(mx,y,w,h)
{
fill(30,30,130);
noStroke();
bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//land lighter
function land2(mx,y,w,h)
{
fill(75,75,190);
noStroke();
bezier(mx,y,mx,y-h*2,mx+w,y-h,mx+w,y);
}
//duck
function duck(x,y)
{
fill(30,30,130,180);
triangle (x-5,y,x-10,y+5,x-5,y+5);
triangle (x+5,y+5,x+5,y+10,x+35,y+10);
arc (x,y,10,10,Math.PI,2*Math.PI);
rect (x-5,y,10,10);
arc (x+15,y+10,40,25,0,PI,OPEN);
}
//reed
function reed()
{
//moving based on sin function
var dr = Math.sin(Math.PI*drR);
drR+=0.002;
push();
translate(100,500);
rotate(dr/20);
fill(180,120,30);
rect(-0,-200,10,80,5);
rect(3,-120,4,120);
fill(190,130,60);
rect(-40,-190,10,80,5);
rect(-37,-110,4,120);
fill(210,110,80);
rect(-20,-160,10,80,5);
rect(-17,-80,4,120);
pop();
}
//second types of reed (blue)
function reed2()
{
var dr = Math.sin(Math.PI*drR);
drR+=0.002;
push();
translate(50,500);
rotate(-dr/20);
fill(50,60,100);
rect(-0,-200,10,80,5);
rect(3,-120,4,120);
fill(30,70,100);
rect(-40,-190,10,80,5);
rect(-37,-110,4,120);
pop();
}