Created
September 28, 2017 03:30
-
-
Save anonymous/7e001586b0204260649a38ad1f04497c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
DRAW ME - FINAL CODE | |
Enna Kim, Mika Hirata, Vivian Wong | |
Professor Kate Hartman | |
DIGF 2004 - Atelier I | |
September 27, 2017 | |
This sketch includes all of the technical code which controls | |
Arduino Firmata through Processing. It allows the user to interact | |
with a touch textile grid connected to two separate capacitive sensors, | |
one for X, and one for Y. The user can control where certain features appear | |
when interacting with different locations on the grid. In addition, a | |
pressure-sensor is used to control the shade of the colour on screen, mimicking | |
pen-pressure sensitivity used in drawing tablets. | |
This current sketch only includes technical code, as a result it can only | |
display ellipses as it's output to test the functionality. When combined with | |
"DRAW ME Visual Code," the user can control the on-screen position of a variety | |
of interesting and unique visual outputs. | |
Note: This sketch can only run after standardFirmata has been uploaded to the Arduino | |
through the Arduino IDE once. If run on a different computer from the original, please | |
use Processing File>Examples>ArduinoInput to identify which port the Arduino is connected | |
to. Then replace "[1]" with the correct value that corresponds to the port. | |
VISUAL REFERENCES: | |
/* Reference Codes | |
https://processing.org/reference/millis_.html | |
https://py.processing.org/tutorials/p3d/ | |
https://www.openprocessing.org/sketch/153224 | |
https://www.openprocessing.org/sketch/218641 | |
http://p5aholic.hatenablog.com/entry/2015/06/15/194250\ | |
http://p5aholic.hatenablog.com/entry/2015/12/11/000000 | |
TECHNICAL REFERENCES: | |
https://stackoverflow.com/questions/2788159/turn-javascript-local-variable-into-global-variable | |
https://processing.org/reference/map_.html | |
https://processing.org/examples/map.html | |
http://playground.arduino.cc/Interfacing/Processing | |
https://processing.org/examples/mousepress.html | |
http://processingjs.org/reference/for_/ | |
http://resistor.cherryjourney.pt/ used to identify the resistance of resistors | |
https://github.com/plusea/CODE/tree/master/EXAMPLE%20CODE/Resistive%20Sensors/LOCATION | |
https://www.youtube.com/watch?v=PAViBKCWrlg the guy talking about the matrix on the fabric | |
http://www.instructables.com/id/Analog-Fabric-Joypad/ analog fabric joypad (our first insipration) | |
https://www.youtube.com/watch?v=vuu3XORygbY grid made with conductive thread | |
https://www.youtube.com/watch?v=oecwY5hkXzw grid made with conductive tape(copper tape) | |
*/ | |
// import all necessary libraries | |
import processing.serial.*; | |
import cc.arduino.*; | |
import org.firmata.*; | |
import processing.sound.*; | |
///////////////////////// ON-SCREEN STUFF //////////////////////// | |
SoundFile soundFile; // name for sound file | |
int sceneCounter = 0; // setting a counter to switch the scenes | |
Timer t1; // declaring the class method "Timer" in the main sketch | |
Timer t2; // declaring the class method for the orbs | |
Line lines; // declaring the class method "Lines" in the main sketch | |
Letter[] letters; // declaring the class method "Letter" in the main sketch | |
Sein sein; // create Sein objects | |
Orb[] orbs = new Orb[500]; //create array with size of 500 orbs | |
int totalOrbs = 0; // set variable for number of total orbs | |
float speed2 = 1.0; //speed for animation two | |
int numberX; // the number of characters in x axis direction for animation one | |
int numberY; // the number of characters in y axis direction for animation one | |
int size; // the size of the character | |
float x; | |
float y; | |
float y2; | |
float radius = 200; // set radius as 300 for the green sphere (second animation) | |
float ellipse_size = 0.0; // size of yellow ellipse at the end of the film credit (seventh animation) | |
int[] xpos = new int[50]; // create array for xPos | |
int[] ypos = new int[50]; // create array for yPos | |
float rot = 0; // float variable for rotation | |
float velocity = 0; // the value to add on t | |
float acceleration = 0.05; //the number to add velocity | |
color c; // declare variable c as color | |
color c2; | |
///////////////////////// ARDUINO STUFF //////////////////////// | |
Arduino a1; // initialize Arduino as a1 | |
int[] pin = new int[12]; // create new pin array with 12 items | |
int drawPosX; // initialize integer variable for drawPosX | |
int drawPosY; // initialize integer variable for drawPosY | |
int sensor1 = 2; // set sensor1 as analog pin 2 | |
Serial myPort; // Name serial port: | |
// set up size of sketch and background | |
void setup() { | |
size(800, 800, P3D); // set size of sketch to be 800 by 800 pixels | |
background(0); // set background colour to black | |
/////////////// ON-SCREEN SETUP /////////////// | |
soundFile = new SoundFile(this, "background.mp3"); //the name of the music file | |
soundFile.play(); //play the music | |
t1 = new Timer(8000); // setting up the timer with 8 sec interval | |
t2 = new Timer(20); // setting up the timer with 0.2 sec interval for animation four | |
lines = new Line(); // setting up line class (third animation) | |
sein = new Sein(); // setting up sein class (fourth animation) | |
t2.start(); // starting the timer for fourth animation(orbs) | |
textAlign(CENTER, CENTER); // centering the text for the title page | |
size = 20; | |
textSize(size); // size of the text | |
numberX = width/size; // the number of text that goes to x axis | |
numberY = height/size; // the number of text that goes to y axis | |
letters = new Letter[numberX * numberY]; // creating new letters for each x and y axis | |
//loop structure to create the letters costantly when the mouse is on the canvas | |
for (int x = 0; x < numberX; x++) { | |
for (int y = 0; y < numberY; y++) { | |
letters[x*numberY+y] = new Letter(x*size+size/2, y*size+size/2); | |
} | |
} | |
/////////////// ARDUINO SETUP ////////////// | |
a1 = new Arduino (this, Arduino.list()[1], 57600); // create new item a1 for Arduino, set to port [1] | |
// for integer i equal to 2, i less than 12, increment i by one | |
for (int i = 2; i < 12; i++) { | |
pin[i] = i; // set pin[i] equal to the value of i | |
a1.pinMode(pin[i], Arduino.INPUT); // set pin[i] as input (Pins 2-12 set as input) | |
println(pin[i]); // print pin[i] to test if forloop worked | |
} | |
printArray(Serial.list()); // list all the available serial ports | |
} | |
void draw() { | |
///////////// ON-SCREEN DRAW //////////// | |
checkTime(); //time checker | |
if (sceneCounter == 0 || sceneCounter == 1 ) { //16 sec interval | |
checkPosition1(); //loading animation | |
} else if (sceneCounter == 2 || sceneCounter == 3 ) { //16 sec interval | |
background(128, 240, 190); //background color | |
noCursor(); //not to show the cursor on canvas | |
//drawing the characters for the title page | |
for (int i = 0; i < letters.length; i++) { | |
letters[i].display(); | |
title(); | |
} | |
} else if (sceneCounter == 4 || sceneCounter == 5 ) { //16sec interval | |
checkPosition2(); //first animation | |
} else if (sceneCounter == 6 || sceneCounter == 7 ) { //16sec interval | |
checkPosition3(); //second animation | |
} else if (sceneCounter == 8 || sceneCounter == 9 ) { //16sec interval | |
four(); //third animation | |
} else if (sceneCounter == 10 || sceneCounter == 11) { //16sec interval | |
five(); //fourth animation | |
} else if (sceneCounter >= 11 ) { // after all the animation | |
six(); //last animation | |
} | |
//////////// ARDUINO DRAW ////////////// | |
checkPositionAll(); // call checkPositionAll function | |
colourChange(); // call colourChange function | |
} | |
void checkPosition1() { | |
checkPositionX(); // call checkPositionX function | |
checkPositionY(); // call checkPositionY function | |
one(); | |
} | |
void checkPositionTitle() { | |
checkPositionX(); // call checkPositionX function | |
checkPositionY(); // call checkPositionY function | |
title(); | |
} | |
void checkPosition2() { | |
checkPositionX(); // call checkPositionX function | |
checkPositionY(); // call checkPositionY function | |
//two(); | |
colourChange2(); | |
} | |
void checkPosition3() { | |
checkPositionX(); // call checkPositionX function | |
checkPositionY(); // call checkPositionY function | |
three(); | |
} | |
// Function which combines checkPosition functions for X and Y axis and drawScreen | |
void checkPositionAll() { | |
checkPositionX(); // call checkPositionX function | |
checkPositionY(); // call checkPositionY function | |
//drawScreen(); // call drawScreen function | |
} | |
void colourChange2() { | |
two(); | |
} | |
// Function which checks position of X-axis with capacitive sensor X | |
void checkPositionX() { | |
// for integer j equal to 2, j less than 7, increment j by 1 | |
for (int j = 2; j < 7; j++) { | |
pin[j] = j; // set pin[j] equal to j | |
if (a1.digitalRead(pin[j]) == Arduino.LOW) { // check if value of checked pin is LOW | |
drawPosX = pin[j-2]; // set drawPosX equal to j-2 | |
println("Pin " + pin[j-2] + " is ON" + " drawPosX x-axis: " + drawPosX); // print which pin is ON | |
} else { | |
println("Pin " + pin[j-2] + " is OFF"); // print which pin is off | |
} | |
} | |
} | |
////////// ON-SCREEN FUNCTIONS ///////////// | |
void title() { | |
noStroke(); | |
text("DRAW ME!", width/2, height/2); | |
text("By", width/2, height/2+40); | |
text("Enna Kim, Vivian Wong, Mika Hirata", width/2, height/2+80); | |
} | |
//Loading page at the beggining | |
void one() { | |
background(255); //background color | |
noCursor(); //not to show the cursor | |
fill (0); //fill with black | |
text("LOADING...", width/2, height/2); | |
translate(drawPosX*100+200, drawPosY*50, 0); //the circle moves with the location of cursor | |
rotateX(frameCount*0.01); //rotate in x direction | |
rotateY(frameCount*0.01); //rotate in y direction | |
//remember the previous corrdinate of x and y axis | |
float lastX = 0, lastY = 0, lastZ = 0; | |
float radius = 200; | |
float s = 0, t = 0; | |
while (s <= 180) { | |
float radianS = radians(s); | |
float radianT = radians(t); | |
// renew the present corrdinate of x and y axis | |
float x = radius * sin(radianS) * cos(radianT); | |
float y = radius * sin(radianS) * sin(radianT); | |
float z = radius * cos(radianS); | |
stroke(245, 195, 175); //color of the sphere | |
if (lastX != 0) { | |
strokeWeight(0.5); | |
//draw a line from the previous corrdinate to the present corrdinate | |
line(x/2, y/2, z/2, lastX, lastY, lastZ); | |
} | |
strokeWeight(7); | |
point(X+4, y+4, z+4); | |
point(x, y, z); | |
//renew the last corrdinate | |
lastX = x; | |
lastY = y; | |
lastZ = z; | |
//renew s and t at the same time | |
s++; | |
t += velocity; | |
} | |
//adding velocity to the acceleration | |
velocity += acceleration; | |
} | |
//first animation (circle) | |
void two() { | |
noCursor(); //not to show the cursor | |
background(71, 149, 242); // background color | |
//if(mousePressed == true) { | |
translate(drawPosX*100+120, drawPosY*190-850); //translate mousex and mousey into the center of the canvas | |
rotateX(frameCount*0.02); // rotate the sphere around x-axis | |
rotateZ(frameCount*0.03); // rotate the sphere around y-axis | |
for (int i = 0; i <= 180; i += 1) { | |
float radianS = radians(i); | |
float z = radius * cos(radianS); //declaring z value | |
for (int t = 0; t < 360; t += 3) { | |
float radianT = radians(t); | |
float x = radius * sin(radianS) * cos(radianT); // declaring x value | |
float y = radius * sin(radianS) * sin(radianT); // declaring y value | |
//stroke(0, 0, 0, random(255)); //stroke color: white | |
stroke(c); | |
strokeWeight(2); //thickness of the circles | |
point(x, y, z); | |
} | |
} | |
} | |
//animation two (lines) | |
void three() { | |
noCursor(); //not to show the cursor | |
//background(232, 148, 63); //background color | |
background(c2); | |
lines.display(); //class Line | |
fill(random(200, 255)); | |
x+=speed2; | |
if (x== 410) { | |
speed2 = 0; //stop moving the font when it hits 410 | |
} | |
} | |
//animation three (orbs) | |
void four() { | |
background(0); | |
anim1(); | |
circle2(0); // unique duo colour achieved by overlaying circle2() on Sein() | |
sein(); | |
} | |
//animation four | |
void five() { | |
//create an ellipse which is a transition | |
fill(87, 107, 201); | |
ellipse(width/2, height/2, ellipse_size, ellipse_size); //sizr and location of the ellipse) | |
ellipse_size = ellipse_size + 5.0; //the size of the ellpise increases by 5.0 | |
} | |
//last scene | |
void six() { | |
fill(255); | |
text("Thank you for your time! ", width/2, height/2); | |
} | |
// main Sein object, that will be called at the beginning | |
// different Seins had to be called because they will move differently | |
void sein() { | |
noCursor(); // Hides cursor, replaced by Sein | |
sein.move(drawPosX*150+50, drawPosY*170-600); | |
sein.display(); | |
xpos[xpos.length - 1] = drawPosX*150+50; // original, xPos corresponds to xPos of cursor | |
ypos[ypos.length - 1] = drawPosY*170-600; // original, yPos corresponds to yPos of cursor | |
} | |
// animation of orbs floating upwards | |
void anim1() { | |
if (t2.isFinished() == true) { // when timer reaches 30 milliseconds | |
orbs[totalOrbs] = new Orb(); // display new orb | |
totalOrbs++; // increment number of orbs | |
t2.start(); // reset time | |
if (totalOrbs >= orbs.length) { | |
totalOrbs = 0; // reset number of orbs to 0 if there are over 500 orbs | |
} | |
} | |
for (int i = 0; i < totalOrbs; i++) { // for loop calls each class function for each orb | |
orbs[i].move(); // move property of orbs | |
orbs[i].display(); // display property of orbs | |
orbs[i].lightOnTouch(sein); // give each orb the property to be lit up if touched by Sein | |
} | |
} | |
void circle2(int colour) { | |
for (int s = 0; s < xpos.length - 1; s++) { | |
xpos[s] = xpos[s+1]; | |
ypos[s] = ypos[s+1]; | |
} | |
for (int s = 0; s < xpos.length - 1; s++) { | |
xpos[s] = xpos[s+1]; | |
ypos[s] = ypos[s+1]; | |
} | |
xpos[xpos.length - 1] += 1; // set previous xPos to xPos + 1 | |
ypos[ypos.length - 1] += 1; // set previous yPos to yPos + 1 | |
for (int k = 0; k < xpos.length; k++) { | |
// choose between blue glow (calm mode) | |
if (colour == 0) { | |
fill(random(50, 70), random(50, 70), random(220, 255), 250); | |
} | |
// or purple glow when calling function (attacking mode) | |
if (colour == 1) { | |
fill(192, 135, random(220, 255), 250); | |
} | |
ellipse(xpos[k], ypos[k], k/2, k/2); // draw ellipse | |
} | |
} | |
void checkTime() { | |
if (t1.isFinished()) { | |
sceneCounter = sceneCounter+1; //when the timer hits 5.5 sec the sceneCounter will increase by 1 | |
t1.start(); //start the timer again | |
} | |
} | |
void mousePressed() { | |
sceneCounter++; //when the mouse is pressed the sceneCounter will increase by 1 | |
//if the mouse if pressed, sceneCounter will be increated by one and pass it to next scene | |
} | |
////////// ARDUINO FUNCTIONS ///////////// | |
// Function which checks position of X-axis with capacitive sensor Y | |
void checkPositionY() { | |
// for integer j equal to 7, j less than 11, increment j by 11 | |
for (int j = 7; j < 11; j++) { | |
pin[j] = j; // set pin[j] equal to j | |
if (a1.digitalRead(pin[j]) == Arduino.LOW) { // check if value of checked pin is LOW | |
drawPosY = pin[j-2]; // set drawPosX equal to j-2 | |
println("Pin " + pin[j-2] + " is ON" + " drawPosX y-axis: " + drawPosY); // print which pin is ON | |
} else { | |
println("Pin " + pin[j-2] + " is OFF"); // print which pin is off | |
} | |
} | |
} | |
// Function for pressure sensor colour-changing mechanic | |
// Changes from light green to navy blue | |
void colourChange () { | |
float val = a1.analogRead(sensor1); // set float value equal to analog value of sensor1 (textile pressure sensor) | |
float valA = map(val, 500, 1000, 75, 255); // map value to value A | |
float valB = map(val, 500, 1000, 10, 25); // map value to value B | |
// if val is less than or equal to 800 | |
if (val <= 800) { | |
c = color(valA*5, valA*10, valB*20, valB*10); // change fill colour to specified values relevant to ValA and ValB | |
c2 = color(valA*5, valA*5, valB*25, valB*10); | |
//rect(0, 0, height, width); // draw a 200 by 200 rectangle at 100 px right, 200 px down | |
} | |
//println(int(val), int(valA), int(valB)); // used to check values of valA and valB | |
// drawing function, currently with mouse, replace with pressure sensor | |
} | |
// Function for controlling the on-screen drawing process | |
//void drawScreen() { | |
// noStroke(); // remove stroke | |
// ellipse(drawPosX*100+200, drawPosY*80, 20, 20); // draw an ellipse depending on touch sensor location detected | |
//} | |
//Thank you for your time! Mika Hirata, Vivian Wong, Enna Kim |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Letter { | |
char c; // the characters to show | |
int x, y; // x-axis and y-axis | |
int gray = 255; //color | |
Letter(int x, int y) { | |
this.x = x; | |
this.y = y; | |
// setting what kind of fcharacter to show as the shadow | |
c = char(int(random(97, 0))); | |
} | |
void display() { | |
// calculating the distance of the mouse | |
float distance = dist(drawPosX*200, drawPosY*200-900, x, y); | |
// draw in black within 100px | |
if (distance <= 100) { | |
gray = 0; | |
} | |
// resetting the character in 10% probability | |
if (random(100) < 10) { | |
c = char(int(random(97, 200))); | |
} | |
// draw the characters | |
fill(gray); | |
text(c, x, y); | |
// fade the character into white color in the 4.0 pace | |
gray += 4; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//class for lines | |
class Line{ | |
int step1 = 10; | |
int x1 = 100; | |
int x2 = 100; | |
int y1 = 50; | |
int y2 = 50; | |
int y3 = 10; | |
int move = 50; | |
void display(){ | |
if(x1 > 100 || x2 < 10){ | |
move = move*40; | |
} | |
if(x2> 250 || x2 < 10){ | |
move = move*40; | |
} | |
x1+=move; | |
y1+=move; | |
y2-=move; | |
x1 -= move; | |
float xFactor = map(drawPosX*100/2, drawPosY*100/2, width, 1.5, 8.0); | |
float yFactor = map(drawPosY*100/2, drawPosY*100/2, height, 2.5, 2.0); | |
for(int i = 0; i < width; i+=step1){ | |
//setting for the lines | |
stroke(255, 31, 83, random(0,100)); | |
strokeWeight(1); | |
//how do the line move | |
line(i, i*xFactor, width + i*xFactor, height - i*xFactor*yFactor); | |
line(i, i*xFactor, width - i*xFactor, height + i*xFactor*yFactor); | |
line(i, i*xFactor, width + i*xFactor, height - i*xFactor*yFactor); | |
line(width, i*xFactor, width - i*xFactor, height + i*xFactor*yFactor); | |
line(width+ i, i*xFactor, i*xFactor, height + i*xFactor*yFactor); | |
line(width- i, i*xFactor, i*xFactor, height - i*xFactor*yFactor); | |
line(i, i*xFactor, i*xFactor, height + i*xFactor*yFactor); | |
line(i, i*xFactor, i*xFactor, height - i*xFactor*yFactor); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// glowing orbs are a signficant image in Ori and the Blind Forest | |
class Orb { | |
color c; | |
float size; | |
float x; | |
float y; | |
float speed; | |
Orb() { | |
x = random(width); | |
y = height; | |
size = random(30,60); | |
speed = 0.05 * size; | |
c = color (100, 237, random(150, 255), random(100)); | |
} | |
void move() { | |
y -= speed; | |
} | |
void display() { | |
noStroke(); | |
fill(c); | |
ellipse(x, y, size, size); | |
} | |
boolean checkIntersect(Sein s) { | |
float distance = dist(x, y, s.x, s.y); | |
float myRadius = size/2; | |
float otherRadius = s.size/2; | |
if (distance <= myRadius + otherRadius) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
// function allowing opacity to increase randomly if orb is touched by Sein object | |
void lightOnTouch(Sein s) { | |
if (checkIntersect(s) == true) { | |
c = color(100, 237, random(150, 255), random(200, 255)); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// create Sein object, Sein is a creature of blue light | |
class Sein { | |
float size; | |
color c; | |
float x; | |
float y; | |
Sein() { | |
size = 10; | |
c = color (100, 230, 250, 10); | |
} | |
void move(float _x, float _y) { | |
x = _x; | |
y = _y; | |
// for loop to calculate the position depending on length of xpos - 1 | |
for (int s = 0; s < xpos.length - 1; s++) { | |
xpos[s] = xpos[s+1]; | |
ypos[s] = ypos[s+1]; | |
} | |
for (int s = 0; s < xpos.length - 1; s++) { | |
xpos[s] = xpos[s+1]; | |
ypos[s] = ypos[s+1]; | |
} | |
} | |
void display() { | |
strokeWeight(4); | |
fill(c); | |
ellipse(x, y, size, size); | |
for (int k = 0; k < xpos.length; k++) { | |
noStroke(); | |
fill(10, 235, random(220, 255), k); | |
ellipse(xpos[k], ypos[k], k/2, k/2); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// class for Timer | |
class Timer { | |
int timeStarted; | |
int interval; | |
Timer(int _totalTime) { | |
timeStarted = _totalTime; | |
} | |
void start() { | |
interval = millis(); | |
} | |
boolean isFinished() { | |
int elapsedTime = millis()- timeStarted; | |
if (elapsedTime > interval) { | |
return true; | |
}else { | |
return false; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment