This reading made me think more about my life and how I use products though I tried to make a conscious effort to analyze how Pullin’s insights might be useful to the creation of my projects in this class. The discussion of medical aids and design choices was extremely interesting, although I honestly have not reached any conclusions of whether or not I believe that “fashion” should intrude into the design of prosthetics, hearing aids, etc.. This reading probably left me with more questions than answers to some of my beliefs on design and functionality. This brings me to discuss the other aspect of product design and creation in general that Pullin touches on: the importance of functionality and how it plays into the user experience. His discussion of James Leckey and his production of furniture for children with cerebral palsy. In what he calls the flying submarine, is it better to create products that are akin to a swiss army knife? Or are we better off creating products that suit a certain purpose/different people’s needs. Is the reason that Leckey decided to stop creating furniture that served many functions because of technological limitations of creating all these complex functions, or is cognitive overload the real cause in inhibiting its proper use? Like many of the readings, it is hard for me to reach any conclusions, but as I mentioned earlier, this reading made me think a lot about design decisions I make in creating as well as how design plays a role in my life and in others’ lives.
Category: Spring 2019
Lines, Circles, and Spectacles
“Design depends largely on constraints”. This brings up an important idea in the balance between what is aesthetic and what is functional. Pullin describes the tension in medical professionals in engaging with a medical market that places objects “in fashion” or subsequently “out of fashion”.
What this tension tells us is of the significance in art and, in this case, design in creating and shifting the zeitgeist. A topic we touched upon in class, we now see that the zeitgeist is closely referenced in the medical field which attempts to make disability invisible. But as our notions of what should and shouldn’t be invisible, we see eyewear, a marker of disability, move from the realm of the invisible to visible, and s marker of something more than disability.
Here we see an intersection in the politically rooted nature of art, and the functionality of design. Spectacle designs take a stance on the nature of disabiilty and then create a specific experience with its use that exist outside of its original and inherent function. Wearing well design glasses express wealth, at some point in time is represented intelligence. These are factors influenced by design. Ultimately, someone can engineer a fantastic set of spectacles, but what purpose does it serve if the experience of an individual is out of their control.
Additionally, here is my sketch for the week using objects.
//Circles and Lines_Nisala Saheed DrawLine myLine[]; PVector center; float angle; float angle2; float radius; int numLines = 15; void setup() { size(600, 600); center = new PVector (width/2, height/2); // we need to know the center of the cirlce that we are drawing. angle = 0; angle2 = 0; radius = 100; float increment = TWO_PI/numLines; myLine = new DrawLine[numLines]; //increase i as an increment for the number of lines, until it reaches the desired number of lines for (int i=0; i<numLines; i++) { float ang = i*increment;//this is how much the angle increments by. myLine [i] = new DrawLine (ang, ang*sin(3)*4, radius); } } void draw() { //background(50); noStroke(); fill(20,30); rect(0,0, width,height); //if you want to see the center //ellipse(center.x, center.y, 10, 10); //draw the lines for (int i=0; i<numLines; i++) { myLine[i].display(); myLine[i].update(); } } class DrawLine { PVector point1; PVector point2; float angle; float angle2; float radius; float x; float y; float x2; float y2; DrawLine(float _angle, float _angle2, float _radius) { point1 = new PVector(x, y); point2 = new PVector(x2, y2); angle=_angle; angle2=_angle2; radius = _radius; } void update() { x = center.x + cos(angle)*radius; y = center.y + sin(angle)*radius; x2 = center.x- cos(angle2)*radius; y2 = center.y- sin(angle2)*radius; angle += PI/120; angle2+=PI/90; } void display() { stroke(21, 220,160); line(x, y, x2, y2); } }
Game in processing by Max
So I have decided to make a ping pong game in processing. First of all it is a multiplayer game for two people. I have made two classes one of them is the paddle and the other one is the ball. The paddles are controlled by either “w” and “s” or “up” and “down”. There is a score count and a reset button.
Here is the code:
main file:
ball ball; padle padle1, padle2; color fillVal = color(126); float move = 0; float velocity = 40; float move1 = 0; PFont f; void setup() { rectMode(CENTER); size(1280, 640); f = createFont("Arial", 16, true); ball = new ball(5, 5, 20); padle1 = new padle(width*0.05, height/2, 10, height/4); padle2 = new padle(width*0.95, height/2, 10, height/4); } void keyPressed() { println(keyCode); if (keyCode == 32) { ball.velocityX = 5; ball.ballY = height/2; ball.velocityY = 5; ball.ballX = width/2; ball.counter1 = 0; ball.counter2 = 0; } if (keyCode == 83) { if (move<=200) move+= velocity; } if (keyCode == 87) { if (move>=-200) move -= velocity; } if (keyCode == 38) { if (move1>=-200) move1-= velocity; } if (keyCode == 40) { if (move1<=200) move1+= velocity; } } void draw() { background(0); textFont(f, 32); fill(255); text(ball.counter1, width*0.33, height*0.1); text(ball.counter2, width*0.66, height*0.1); textFont(f, 14); text("'SPACE' to reset score", 5, 14); text("'W' and 'S' to move left paddle", 5, height-7); text("'UP' and 'DOWN' to move right paddle", width*0.78, height-7); drawLine(); ball.run(height/2+move-height/8, height/2+move+height/8, height/2+move1-height/8, height/2+move1+height/8); padle1.display(width*0.05, height/2+move, 10, height/4); padle2.display(width*0.95, height/2+move1, 10, height/4); } void drawLine() { stroke(255); strokeWeight(4); fill(0); line(width/2, 0, width/2, height); }
ball class:
class ball { float velocityX; float velocityY; int size; float ballX = width/2; float ballY = height/2; color fillVal = color(255, 0, 0); int counter1 = 0; int counter2 = 0; ball(float _velocityX, float _velocityY, int _size) { velocityX = _velocityX; velocityY = _velocityY; size = _size; } void update(float a, float b, float c, float d) { //println("velocityX = "+velocityX); if (ballX >= width) { ballX = width/2; ballY = height/2; velocityX = -5; velocityY = 5; counter1+=1; } if (ballX <= 0 ) { ballX = width/2; ballY = height/2; velocityX = 5; velocityY = 5; counter2+=1; } if (ballX >= width*0.94 && ballX <= width*0.96 && ballY >= c && ballY <=d || ballX >= width*0.04 && ballX <= width*0.06 && ballY >= a && ballY <=b) { velocityX*=1.1; velocityY = random(-15,15); velocityX = -velocityX; } ballX += velocityX; if (ballY >= height || ballY <= 0) { velocityY = -velocityY; } ballY += velocityY; } void display() { //ellipse(width/2, height/2, size, size); fill(fillVal); noStroke(); ellipse(ballX, ballY, size, size); } void run(float a, float b, float c, float d) { update(a, b, c, d); display(); } }
paddle class:
class padle { float x; float y; float w; float h; color fillVal = color(0, 255, 0); padle(float _x, float _y, float _w, float _h) { x = _x; y = _y; w = _w; h = _h; } void update() { } void display(float x, float y, float w, float h) { fill(fillVal); rect(x, y, w, h, 5); } void run() { update(); display(x,y,w,h); } }
Assignment: Object-Oriented Programming
For this week’s assignment I decided to create a simple game using OOP, creating a game with a player-controlled rectangle that stays at the bottom of the screen. The player is able to control the rectangle across the x-axis as well as having it jump. The goal of the game is to avoid the falling ellipses, and the player’s score increases the longer they remain in the game. The number of ellipses increases as the duration of the game increases.
I created two classes for this game, the one for the ellipses and one for the player.
There were a few problems I encountered while making the game, and I had trouble detecting collisions between the rectangle and the falling ellipses. I was not sure how to loop through the array of ellipses created and detecting their contact with the player’s rectangle. But thanks to Dan Shiffman’s helpful tutorials I was able to piece together how to detect this.
Below is a video showing the game in action:
Below is the code for the game:
float monsterSpotY = random(300, 560); float monsterSpotX = random(200, 560); float monsterRadius = 40; int gravity = 1; int counter = 0; // gamestate to detect if player is dead and in play again menu or not int gameState = 1; Player myPlayer; Monster myMonsters[]; void setup() { size(600, 600); myPlayer = new Player(); int monsterCount = 500; myMonsters = new Monster[monsterCount]; for (int i = 0; i < monsterCount; i++) { myMonsters[i] = new Monster(); } } void draw() { background(100); if (gameState == 1) { myPlayer.display(); myPlayer.update(); myPlayer.stayDown(); gameOver(); text(counter, width - 40, 30); int counterIncrement = counter /7; for (int i = 0; i < counterIncrement / 20; i+= 1) { myMonsters[i].run(); //println("i is equal to " + i); if (i == counterIncrement / 20) { i = 0; println(i); } } counter++; //increment counter to add elliipses falling } else { textAlign(CENTER); text("You Died! Your score is: " + counter, width/2, height / 2); text("Click here to play again", width / 2, height / 2 + 30); if (mousePressed == true && mouseX > 230 && mouseX < 360 && mouseY > 320 && mouseY < 340) { setup(); gameState = 1; counter = 0; } } } void keyPressed() { if (keyCode == UP && myPlayer.y == 580) { myPlayer.up = 2; } if (keyCode == DOWN) { myPlayer.down = 2; } if (keyCode == LEFT) { myPlayer.left = 2; } if (keyCode == RIGHT) { myPlayer.right = 2; } } void keyReleased() { if (keyCode == UP) { myPlayer.up = 0; myPlayer.down = gravity; } else if (keyCode == DOWN) { myPlayer.down=0; } else if (keyCode == LEFT) { myPlayer.left=0; } else if (keyCode == RIGHT) { myPlayer.right=0; } } void gameOver() { for (int i = 0; i < 30; i++) { //detect if rect is hittiing any ellipse if (myPlayer.x + 20 > myMonsters[i].monsterSpotX - 20 && myPlayer.x - 20 < myMonsters[i].monsterSpotX && myPlayer.y - 20 < myMonsters[i].monsterSpotY && myPlayer.y + 20 > myMonsters[i].monsterSpotY - 10) { gameState = 0; } else { } } }
The code for the ellipses and rectangle classes:
class Player { float x; float y; float up; float down; float left; float right; float speed; float maxJump; float side; Player() { x = 0; y = 580; up = 0; down = 0; left = 0; right = 0; speed = 4; maxJump = 200; side = 20; } void display() { fill(0); rect(x, y, side, side); } void update() { x = x + (right - left) * speed; y = y + (down - up) * speed; if (x <= 1) { x = 0; y = 580; } else if (x >= 580) { x = 580; y = 580; } else if (y <= 0) { y = 0; } else if (y >= 580) { y = 580; } } void stayDown() { if (y < maxJump) { up=0; down = gravity; } } }
class Monster { float x; float y; float radius; float ySpeed; float monsterSpotY; float monsterSpotX; color monsterColor; Monster() { radius = monsterRadius; ySpeed = random(2, 6); monsterSpotX = random(0, width); monsterSpotY = random(0,100); } void show() { monsterColor = color(map(monsterSpotY, 0, height, 0, 255), map(monsterSpotY, 0, height, 100, 150), map(monsterSpotY, 0, height, 150, 255)); fill(monsterColor); noStroke(); ellipse(monsterSpotX, monsterSpotY, monsterRadius, monsterRadius); } void fall() { monsterSpotY = monsterSpotY + ySpeed; if (monsterSpotY > height) { monsterSpotY = random(-200, 300); } } void run() { fall(); show(); } }
Response to Design Meets Disability
Before reading this, I had no idea there were so many inventions for the disabled and I did not think about the work that went into designing them. Because everyone’s situation is different, the devices that help aid them are difficult to standardize. Additionally, if that person has to use the technology for the rest of their lives, it has to be one that they enjoy and are comfortable with and because of that, for those creating the devices, design has to be up to par.
I personally like the point about simplicity because it really focuses in on what’s important and in this case, it’s to give the user a functionality they need. It should be simple enough that it’s intuitive and useful at the same time, yet there’s still a like of devices out there that are too confusing to use.
Art Using OOP: Abu Dhabi From Day to Night
For this assignment, we were asked to create a piece of art or a game using object-oriented programming (OOP). I immediately thought of re-creating some significant piece of art using processing and adding randomized, generative elements to it. When I started thinking of pieces that were predominantly geometric, I immediately thought of Piet Mondrian’s work. I thought it would be interesting to see abstractness become randomized, in a way. After this, I searched for Mondrian + Generative Art. I did not expect to find that many results. Mondrian and code, Mondrian and generative art, Mondrian and processing. There even was an entire programming language called Piet. It was way, way too overdone to the point where I couldn’t think of any way I could create my own take on it- so I had to change my idea.
So, inspired by the rainfall over the weekend, I created a rainy skyline of Abu Dhabi from day to night. First, for the sky, I had to think on paper:
Here is the final result, the “time of day” changes with the movement of the mouse:
And, here is my code:
//arrayList to hold all stars ArrayList<Star> stars = new ArrayList<Star>(); Moon moon = new Moon(); int modifier; float raindrop; int red, green, blue; void setup() { size(585,430); background(0); raindrop= 0; //generate 30 random stars for (int i = 0; i < 30; i++) { stars.add(new Star()); } } void draw() { raindrop = raindrop + 4; //speed //if raindrop falls below canvas, reset to zero if (raindrop >= height) raindrop = 0; //map mouseX to rgb values of background red = int(map(mouseX, 0, width, 83, 0)); green = int(map(mouseX, 0, width, 157, 0)); blue = int(map(mouseX, 0, width, 253, 0)); modifier = int(map(mouseX, width/2, width, 29, 0)); background(red, green, blue); if (mouseX > width/2) { for (int i = 0; i < stars.size() - modifier; i++) { Star s = stars.get(i); s.drawStar(); } } moon.update(); moon.drawMoon(); //rainfall fill(211,211,211); rect(10, raindrop, 2, 5); rect(50, raindrop+20, 2, 5); rect(80, raindrop, 2, 5); rect(110, raindrop+100, 2, 5); rect(140, raindrop+150,2, 5); rect(180, raindrop-200, 2, 5); rect(200, raindrop-150, 2, 5); rect(240, raindrop-50, 2, 5); rect(240, raindrop, 2, 5); rect(300, raindrop+20, 2, 5); rect(440, raindrop, 2, 5); rect(440, raindrop, 2, 5); rect(550, raindrop+100, 2, 5); rect(530, raindrop-250, 2, 5); rect(530, raindrop-200, 2, 5); rect(580, raindrop-300, 2, 5); rect(300, raindrop-400, 2, 5); rect(140, raindrop-350, 2, 5); rect(400, raindrop-300, 2, 5); rect(400, raindrop-250, 2, 5); rect(400, raindrop-200, 2, 5); rect(550, raindrop, 2, 5); //this part of my code uses & adapts from "skyline" by Shiwen Qin on OpenProcessing //building 1 fill(250); rect(35,255,5,55); fill(250); rect(40,250,40,60); fill(51, 51, 51); quad(80,250,80,310,95,310,95,260); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(36,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=44; x<78; x+=10){ fill(106,106,71); rect(x,y,3,3); } } //building 2 fill(51, 51, 51); rect(93,265,40,60); for (int y=270; y<300;y+=10){ for(int x=96; x<130; x+=10){ fill(165,160,102); rect(x,y,5,3); } } //building 3 fill(220,220,220); rect(150,225,15,120); fill(220,220,220); rect(164,215,10,140,6); fill(169,169,169); rect(166,218,2,140,7); fill(105,105,105); arc(170,250,70,70,-PI/2,0); rect(170,250,35,140); fill(192,192,192); arc(170,250,60,60,-PI/2,0); rect(170,250,30,140); fill(192,192,192); arc(170,250,40,40,-PI/2,0); rect(170,250,20,140); //fourth building fill(250); fill(250); rect(235,225,5,75); fill(250); rect(240,225,40,80); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(236,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=244; x<278; x+=10){ fill(106,106,71); rect(x,y,3,3); } } // fifth building fill(102, 102, 102); rect(300,185,36,120); fill (51, 51, 51); rect (295, 185, 5, 120); rect (305, 185, 5, 120); //sixth building fill(51, 51, 51); rect(376,172,2,10); rect(375,180,3,15); quad(350,206,350,316,380,316,380,190); fill(102, 102, 102); quad(375,198,375,316,405,316,405,215); fill(51, 51, 51); rect(387,215,1,115); rect(396,215,1,115); //seventh building fill(51, 51, 51); rect(430,200, 40 ,150); fill(250); rect(430,200, 40 ,5); rect(470,200, 2 ,150); //seventh building .2 fill(192,192,192); rect(490,200, 40 ,150); fill(250); rect(490,200, 40 ,5); rect(500,200, 2 ,150); //eighth building fill(51, 51, 51); rect(225,225,10,120); rect(270,225,10,120); //building 8 arc(540,190,70,70,-PI*4/6,-PI*1/6,CHORD); quad(523,159,523,325,570,325,570,172); for(int y=170;y<325 ;y+=5){ fill(106,106,71); quad(523,y,570,y+2,570,y+4,523,y+2); } //ninth building fill(51, 51, 51); quad(585,165,615,155,620,325,585,325); fill(31,30,72); triangle(614,155,622,158,619,325); for(int y=210;y<325 ;y+=5){ fill(106,106,71); quad(585,y,615,y-1,615,y+1,585,y+2); } for(int y=210;y<325 ;y+=5){ fill(64,64,34); quad(615,y-1,621,y,621,y+2,615,y+1); } //shore fill(69, 137, 163); rect(0,310,900,400); //mangroves for(int x=0;x<900;x+=20){ mangroves(x,310,10,10,3,28,5,255); //varying parameters for mangroves mangroves(x+10,305,8,8,6,41,8,255); mangroves(x+5,300,5,4,14,62,17,255); } } void cloud(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); } //sets variables they're being created in void mangroves(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); ellipse(x+5,y+5,w,h); ellipse(x-5,y-3,w,h); ellipse(x+3,y-5,w,h); ellipse(x-3,y+5,w,h); }
class Moon { int x; int y; int sizeMod = 0; Moon() { this.x = 60; this.y = 90; } void drawMoon() { int blue, green; //map mouseX to green and blue rgb values for moon green = int(map(mouseX, 0, width, 221, 250)); blue = int(map(mouseX, 0, width, 0, 205)); noStroke(); fill(255, green, blue); //map mouse X to rgb values for background/sky int bg_red = int(map(mouseX, 0, width, 83, 0)); int bg_green = int(map(mouseX, 0, width, 157, 0)); int bg_blue = int(map(mouseX, 0, width, 253, 0)); //map mouseX to variable sizeMod, starting at 0, ending at 20 sizeMod = int(map(mouseX, 0, width/6, 0, 20)); //width/6 divides canvas into 6, for each moon/sun phase if (mouseX <= width/6) { //sizeMod decreases size of moon, starts at 80, ends at 80 - 20 = 60 ellipse(x, y, 80 - sizeMod, 80 - sizeMod); } else if (mouseX > width/6 && mouseX <= 2 * (width/6)) { arc(x, y, 60, 60, HALF_PI, 3 * HALF_PI, OPEN); } else if (mouseX > 2 * width/6 && mouseX <= 3 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x + 10, y, 50, 50); } else if (mouseX > 3 * width/6 && mouseX <= 4 * width/6) { ellipse(x, y, 60, 60); //can't figure out how to flip arc, just cover with rectangle fill(bg_red, bg_green, bg_blue); rect(x - 30, y - 30, 30, 60); } else if (mouseX > 4 * width/6 && mouseX <= 5 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x - 10, y, 50, 50); } else { ellipse(x, y, 60, 60); } } void update() { x = mouseX; } }
class Star { int x; int y; Star() { //instantiate star with random x and random y values, every time you restart sketch it' random this.x = int(random(0, width)); this.y = int(random(0, height/3)); } void drawStar() { fill(255); ellipse(x, y, 1.5, 1.5); } }
Design Meets Disability: Comment
Disability is surely not a new concept that I have encountered. In fact, the course that I take right before my Intro to IM class is called “Dis/abilities in Musical Context”. However, this approach was something I had not met before: how design is crucial to suit people with needs.
Before reading this article, when debating upon the creation of devices for disabled people, I assumed that technicality would be above all else. For instance, if the hearing aid is not loud enough, it is basically useless to someone. Or if colorblind glasses do not work properly, that too would be a reason for colorblind people to neglect that product. However, by thinking this way, I diminished the importance of ‘design’.
One valuable lesson I learned is that design matters as much as technicality. If a product works, but is not fit for the person’s body, what much use is there to it? That was one question I failed to acknowledge before. And especially for disabled people, because their degrees of disability may vary (which may lead to different body shapes and sizes) it is also arduous to come up with one single design that can fit every disabled person.
I have learned, ultimately, that not only is design significant for certain aids, but it is definitely a hard task to complete as numerous obstacles are in the way.
Catching Particles
For the OOP project, I recreated the catching ball game. To make it simple, I made a rectangular bar which is essentially the basket that is suppose to catch the ellipses that are falling from the sky. Each of these balls are made from the Ball class, which has the attributes xPos, yPos, speed, and size. Every time the ball is not caught by the rectangular bar, the number of missed balls increased and the speed of the ball increases. This basically means the game gets harder at each level because the ball is moving at a random(0.1, 0.3) speed faster than before. I had trouble making the balls come down at different times and position, but I fixed it by starting each of the balls’ yPos to be between random(-width, 0), so that the balls don’t show up all at once. Once a ball reaches the bottom of the screen, I reset its x,y position to a new location on the screen, so that it looks like there’s always new balls coming from the sky.
There a 5 levels to this game. If they reach it, they win.
Every time the user catches 10 balls, it turns into a new level.
If the user misses out on 15 balls, they lose (does not reset at each level).
int level = 0; int totBall = 10; int caughtBalls = 0; int missedBalls = 0; Ball balls[] = new Ball[totBall]; Catcher catcher; void setup() { size(640, 640); catcher = new Catcher(); for (int i = 0; i < totBall; i++) { balls[i] = new Ball(random(width - 20), random(-width, 0), 1.2); } } void draw() { background(0); fill(255); if (level < 6 && missedBalls < 15) { text("Level: ", 20, 20); text(level, 60, 20); text("Caught: ", 20, 40); text(caughtBalls, 75, 40); text("Missed: ", 20, 60); text(missedBalls, 70, 60); for (int i = 0; i < totBall; i++) { balls[i].run(); if (balls[i].isTouchingBar(mouseX, height - 20)) { caughtBalls++; } else if (balls[i].yPos >= height - 10) { missedBalls++; balls[i].resetIfEnd(height - 10); } } if (caughtBalls % totBall == 0 && caughtBalls != 0) { level++; caughtBalls = 0; } catcher.display(); } else if (level > 5) { text("YOU WIN", width/2 - 20, height/2); } else if (missedBalls >= 15) { text("GAME OVER", width/2 - 20, height/2); text("LEVEL: ", width/2 - 20, height/2 + 20); text(level, width/2 + 20, height/2 + 20); } }
class Ball { float xPos, yPos, spd, size; color clr; Ball(float x, float y, float speed) { xPos = x; yPos = y; spd = speed; size = random(5, 20); clr = color(random(0, 255), random(0, 255), random(0, 255)); } void display() { fill(clr); ellipse(xPos, yPos, size, size); } void move() { yPos += spd; } void resetIfEnd(int y) { if (yPos > y) { yPos = random(-width, 0); xPos = random(width); spd = spd + random(0.1, 0.3); } } void run() { move(); resetIfEnd(height); display(); } boolean isTouchingBar(float barXPos, float barYPos) { if (xPos >= barXPos && xPos <= barXPos + 90 && yPos >= barYPos && yPos <= barYPos + 20) { resetIfEnd(height - 20); return true; } return false; } }
Code – lines pointing at mouse w/OOP
Main Sketch:
// declare an array of DirectionLines DirectionLine lines[]; void setup() { fullScreen(); //how long will each line be int lineLength = 30; //we can find out how many lines we will have //by dividing width and height by the lineLength int w = width/lineLength; int h = height/lineLength; //initialize the array with number of total lines lines = new DirectionLine[w*h]; //index to access each element of the array int i=0; //nested for loop, start at lineLength/2 to offset and center the lines on screen //increase each step through the loops by lineLength, to space the lines appropriately for (int y=lineLength/2; y<height; y+=lineLength) { for (int x=lineLength/2; x<width; x+=lineLength) { //access each DirectionLine in the way and create a new DirectionLine object //the x & y vairbales from the for loops give us the origin location of each line lines[i] = new DirectionLine(x, y, lineLength); //be sure to increase i i++; } } } void draw() { background(255); //just loop through all the lines and call run() for (int i=0; i<lines.length; i++) { lines[i].run(); } }
Class:
class DirectionLine { //variables float angle; float len; PVector origin; //constructor DirectionLine(float x, float y, float _len) { origin = new PVector(x, y); len = _len; angle=0; } //FUNCTIONS\\ //update our angle based on the mouse position void update() { //turn the mouse into a pvector in order to use the pvector functions PVector destination = new PVector(mouseX, mouseY); //subtract the origin from the destination, this is our direction PVector direction = PVector.sub(destination, origin); //get the angle of the direction angle = direction.heading(); } //draw the line void display() { pushMatrix(); //translate and rotate the line based on the angle translate(origin.x, origin.y); rotate(angle); line(0, 0, len, 0); popMatrix(); } //function to wrap up both update and display void run() { update(); display(); } }
Copying the first on screen computer art in code
For my project, I decided to copy Ben F. Laposky’s sine wave Oscillons. Laposky created his original artwork starting in 1952, using oscillators, amplifiers, and modulators with a cathode ray tube to create what is generally regarded as the first computer art.
Since the image (presented here in both black and white and original) was created by taking pictures of analogue lines on a screen, I decided to simulate the motion of the original screen.
int t, x, y, x2, y2; int a, b, b2, c, c2; int d, e, e2, f, f2; int w = 200; float speed = .03; float speed2 = .01; float granulation = .0005; float radius = 100; void setup(){ size (480,640); t = 0; } void draw(){ float frequency = (frameCount*speed) + (granulation); float fillColor = map(noise(frequency), .01, .75, 0, 255); float fillColor2 = map(sin(frequency), .01, .75, 0, 255); float fillColor3 = map(cos(sin(frequency)), .01, .75, 0, 255); fill(0,0,0,11); rectMode(CORNER); rect(-10,-10,width+20,height+20); // fade part rectMode(CENTER); //fill(100, 200, 3, fillColor); stroke(fillColor, fillColor2, 3,fillColor); strokeWeight(12); pushMatrix(); float t= frameCount*speed; float x = radius * sin(t); float y = radius * cos(t/8); float x2 = radius/2 * sin(t-3); float y2 = radius * cos(t); translate(width/2,height/2); line(x,y,x2,y2); //popMatrix(); stroke(fillColor2, fillColor, fillColor,fillColor); strokeWeight(12); //pushMatrix(); float a= frameCount*1.1*speed; float c = radius * sin(a); float b = radius * cos(a/2); float c2 = radius * sin(a*1.3); float b2 = radius * cos(a/3); //translate(width/2,height/2); line(c,b,c2,b2); stroke(fillColor3, fillColor3, fillColor2,fillColor); strokeWeight(12); //pushMatrix(); float d= frameCount*1.1*speed2; float e = radius * sin(d); float f = 20+ radius * cos(d/1.8); float e2 = radius * sin(d/3); float f2 = radius * cos(d/3); //translate(width/2,height/2); line(e,f,e2,f2); // float c = radius * sin(a(tan(a)); //float b = radius * cos(a/2); //float c2 = radius * sin(a-3)*tan(a); //float b2 = radius * cos(a/3); ////translate(width/2,height/2); // line(c,b,c2,b2); popMatrix(); }
To simulate the machine used to create the images, I decided to use bars or lines, making them mobile by having their endpoints following certain sin and cosine functions. I used a Trick Aaron taught me to blur it. The other main function of my code makes each bar change color within a certain specified range, either using noise or a sin/cos wave to change the values.
Once I figured this out, Most of what I had to do was play with where each bar was, what color it was, the speed, and blur.
int t, x, y, x2, y2; int a, b, b2, c, c2; int d, e, e2, f, f2; int w = 200; float speed = .03; float speed2 = .01; float granulation = .0005; float radius = 100; void setup(){ size (480,560); t = 0; } void draw(){ float frequency = (frameCount*speed) + (granulation); float fillColor = map(noise(frequency*2), .01, .75, 190, 255); float fillColor2 = map(sin(frequency), .01, .75, 190, 220); float fillColor3 = map(cos(sin(frequency)), .01, .75, 0, 255); fill(0,0,0,11); rectMode(CORNER); rect(-10,-10,width+20,height+20); // fade part rectMode(CENTER); //fill(100, 200, 3, fillColor); stroke(fillColor, fillColor2, random(20),fillColor); //stroke(200, 200, 3,fillColor);//test colors strokeWeight(12); pushMatrix(); float t= frameCount*speed; float x = (radius * -cos(t))+100; float y = (radius * sin(t))+100; float x2 = radius * cos(t); float y2 = radius * -sin(t); translate(width/2+20,height/2+-100); line(x,y,x2,y2); //popMatrix(); stroke(fillColor, fillColor2, 3,fillColor); strokeWeight(12); //pushMatrix(); float a= frameCount*speed; float c = (radius * -sin(a))+100; float b = (radius * cos(a))+100; float c2 = radius * sin(a); float b2 = radius * -cos(a); //translate(width/2+20,height/2-100); line(c,b,c2,b2); // stroke(fillColor3, fillColor3, fillColor2,fillColor); // strokeWeight(12); // //pushMatrix(); // float d= frameCount*1.1*speed2; // float e = radius * sin(d); // float f = 20+ radius * cos(d/1.8); // float e2 = radius * sin(d/3); // float f2 = radius * cos(d/3); // //translate(width/2,height/2); // line(e,f,e2,f2); // float c = radius * sin(a(tan(a)); //float b = radius * cos(a/2); //float c2 = radius * sin(a-3)*tan(a); //float b2 = radius * cos(a/3); ////translate(width/2,height/2); // line(c,b,c2,b2); popMatrix(); }
Finally it was time for me to begin to copy the original image.
Here in this code, I have two systems working to create the first butterfly in the image. The color fluctuates within the spectrum from red/orange to yellow/green. What I need now is a second system, and possibly a way to translate it up and down as time goes in order to get the same quality as the original.