Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
The EEGen Program
void addParticle() {
Particle p = new Particle(random(width), random(height), random(0.5, 1.5), random(5, 200)); // last is radius
Vec2D f = new Vec2D(random(-0.525, 0.525), random(-0.525, 0.525));
ConstantForceBehavior cb = new ConstantForceBehavior(f);
p.addBehavior(cb);
physics.addParticle(p);
p.pixel1 = src.pixels[floor(random(src.pixels.length - 1))];
p.pixel2 = src.pixels[floor(random(src.pixels.length - 1))];
physics.addBehavior(new AttractionBehavior(p, 50, -1f));
}
void addAttractor(int _behavior) {
Attractor a = new Attractor(new Vec2D(mouseX, mouseY), width / 3, 0, 0, _behavior);
physics.addBehavior(a);
attractors.add(a);
}
class Attractor extends AttractionBehavior {
Vec2D position;
float xNoise, yNoise, strengthNoise;
int behavior;
public Attractor(Vec2D _position, float _radius, float _strength, float _jitter, int _behavior) {
super(_position, _radius, _strength, _jitter);
position = _position;
xNoise = random(1000);
yNoise = random(1000);
strengthNoise = random(1000);
behavior = _behavior;
}
}
class Particle extends VerletParticle2D {
int pixel1, pixel2;
float radiusNoise;
float colorNoise;
float maxRadius;
public Particle(float _x, float _y, float _w, float _maxRadius) {
super(_x, _y, _w);
radiusNoise = random(1000);
colorNoise = random(1000);
maxRadius = _maxRadius;
}
}
//the whole prompt program
public class SecondApplet extends PApplet {
String[] onScreen = {" ",
"welcome to \nThe EEGen Project program",
"how are you today\n?",
"do you know why you're here\n?",
"i am going to read your \nbrain waves as you complete \na series of small tasks",
"i will instruct you along the way\nplease answer to the prompts out loud",
"please keep your head\nand body as still as possible",
"are you ready\n?",
"pay attention\n!",
"BEGINNING IN\n3",
"BEGINNING IN\n2 ",
"BEGINNING IN\n1 ",
"FOLLOW THE DOT",
"now frown\n:-(",
"blink your eyes rapidly\n@ _ @",
"blink your eyes rapidly\n - _ -",
"blink your eyes rapidly\n@ _ @",
"blink your eyes rapidly\n - _ -",
"take a deep breath\nthen exhale",
"do it again",
"one more time",
"click your teeth together rapidly\n:-D",
"click your teeth together rapidly\n:-)",
"click your teeth together rapidly\n:-D",
"click your teeth together rapidly\n:-)",
"make an angry face\n>:-(",
"gently shake your head no",
"can you read this\n?",
"wAhT aOuBt TiHs\n?",
"how about now\n?",
"and now\n?",
"can you read this, too\n????",
"TAKE A BREAK:\nrelax for a bit",
"raise your eyebrows rapidly\n |:-)",
"raise your eyebrows rapidly\n | :-)",
"raise your eyebrows rapidly\n |:-)",
"raise your eyebrows rapidly\n | :-)",
"DANCE PARTY\n(don't actually dance though)",
"close your eyes for 10 seconds\n10",
"close your eyes for 10 seconds\n9",
"close your eyes for 10 seconds\n8",
"close your eyes for 10 seconds\n7",
"close your eyes for 10 seconds\n6",
"close your eyes for 10 seconds\n5",
"close your eyes for 10 seconds\n4",
"close your eyes for 10 seconds\n3",
"close your eyes for 10 seconds\n2",
"close your eyes for 10 seconds\n1",
"say the color, not the word:\n",
"say the color, not the word:\n",
"concentrate on the dot",
"smile\n:-)",
"that's all for now\nthank you for participating",
"THE END\n:-)"};
String[] stroopWords = {"BLUE", "PURPLE", "GREEN", "RED", "PINK", "RED", "YELLOW", "GREEN", "BLUE", "ORANGE"};
int stroopIndex = 0;
int dotRad = 40;
PFont f;
int counter = 0;
int interval = 5000;
int time = 0;
int index = 0;
int xPos = 200;
int xDir = 5;
public void settings() {
//size(1000, 750);
fullScreen(2); //fit to full screen on second screen
}
public void setup() {
f = createFont("Press Start Regular", 1, true);
//Lunchtime Doubly So Regular
//DisposableDroid BB Bold
//Press Start Regular
//SF Pixelate Bold
textAlign(CENTER);
}
void draw() {
textFont(f, 48);
fill(255);
background(0, 195, 255);
//special tasks go by index, ifs and else ifs
//change interval based on how long prompt should be
if (index == 0 || index == 9 || index == 10 || index == 11) {
changeInterval(1000);
text(onScreen[index], width/2, height/2);
} else if (index == 12) {
trigger = true;
changeInterval(20000);
ballBouncing();
} else if (index == 14 || index == 15 || index == 16 || index == 17 || index == 21 || index == 22 || index == 23 || index == 24 || index == 33 || index == 34 || index == 35 || index == 36 || index == 38 || index == 39 || index == 40 || index == 41 || index == 42 || index == 43 || index == 44 || index == 45 || index == 46 || index == 47 ) {
changeInterval(1000);
text(onScreen[index], width/2, height/2);
} else if (index == 18 || index == 19 || index == 20 || index == 26 ) {
changeInterval(6000);
text(onScreen[index], width/2, height/2);
} else if (index == 27 || index == 28 || index == 29 || index == 30 || index == 31) {
reading();
} else if (index == 32) {
changeInterval(10000);
text(onScreen[index], width/2, height/2);
} else if (index == 37) {
changeInterval(8000);
dance();
} else if (index == 48) {
changeInterval(1000);
text(onScreen[index], width/2, height/3);
} else if (index == 49) {
changeInterval(5000);
textFont(f, 48);
fill(255);
text(onScreen[index], width/2, height/3);
stroop();
} else if (index == 50) {
changeInterval(12000);
dotRadius();
} else if (index == 52){
endTrig = true;
text(onScreen[index], width/2, height/2);
}else
text(onScreen[index], width/2, height/2);
//index adjuster, unless END index
//typical interval
if (index + 1 < onScreen.length) {
if (millis() > time + interval) {
index++;
time = millis();
interval = 5000; //reset interval to default
}
} else{
index = onScreen.length - 1;
println("END");
}
}
void changeInterval(int i) {
interval = i;
}
void ballBouncing() {
noStroke();
fill(255);
background(0, 195, 255);
text(onScreen[index], width/2, height/3);
ellipse(xPos, height/2, 80, 80);
xPos=xPos+xDir;
if (xPos>width-20 || xPos<20)
{
xDir=-xDir;
}
}
void reading() {
if (index == 27)
text(onScreen[index], width/2, height/2);
else if (index == 28) {
text(onScreen[index], width/2, height/2);
} else if (index == 29) {
textFont(f, 130);
text(onScreen[index], width/2, height/2);
} else if (index == 30) {
textFont(f, 14);
text(onScreen[index], width/2, height/2);
} else if (index == 31) {
textFont(f, 48);
pushMatrix();
scale(1, -1);
translate(0, -height);
text(onScreen[index], width/2, height/2);
popMatrix();
}
}
void dance() {
background(random(0), random(255), random(255));
text(onScreen[index], width/2, height/2);
delay(10);
}
void stroop() {
textFont(f, 100);
if (stroopIndex == 0 || stroopIndex == 7) {
fill(156, 26, 0);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
} else if (stroopIndex == 1 || stroopIndex == 4 || stroopIndex == 9) {
fill(4, 87, 4);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
} else if (stroopIndex == 2 || stroopIndex == 6) {
fill(86, 9, 107);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
} else if (stroopIndex == 5) {
fill(222, 203, 0);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
} else if (stroopIndex == 3) {
fill(255, 110, 194);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
} else if (stroopIndex == 8) {
fill(22, 0, 222);
text(stroopWords[stroopIndex], width/2, height/2);
delay(500);
}
stroopIndex++;
}
void dotRadius() {
noStroke();
fill(255);
background(0, 195, 255);
text(onScreen[index], width/2, height/4);
//ellipse(width/2, height/2, dotRad, dotRad);
ellipse(width/2, height/2, dotRad, dotRad);
dotRad+=5;
}
/*void mouseClicked() {
index++;
}*/
}
void pushPixel(int choice) {
if (choice == 1) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/brainbow.jpg");
println((millis()/1000.0) + " seconds: image 1, brainbow");
} else if (choice == 2) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/cancer.jpg");
println((millis()/1000.0) + " seconds: image 2, cancer");
} else if (choice == 3) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/dsi.jpg");
println((millis()/1000.0) + " seconds: image 3, dsi");
} else if (choice == 4) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/golgi.jpg");
println((millis()/1000.0) + " seconds: image 4, golgi");
} else if (choice == 5) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/golgicox.jpg");
println((millis()/1000.0) + " seconds: image 5, golgicox");
} else if (choice == 6) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/hardi.jpg");
println((millis()/1000.0) + " seconds: image 6, hardi");
} else if (choice == 7) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/hippocampal.jpg");
println((millis()/1000.0) + " seconds: image 7, hippocampal");
} else if (choice == 8) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/multi.jpg");
println((millis()/1000.0) + " seconds: image 8, multi");
} else if (choice == 9) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/nissl.gif");
println((millis()/1000.0) + " seconds: image 9, nissl");
} else if (choice == 10) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/pet.jpg");
println((millis()/1000.0) + " seconds: image 10, pet");
} else if (choice == 11) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/rois.png");
println((millis()/1000.0) + " seconds: image 11, rois");
} else if (choice == 12) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/sagittal.jpg");
println((millis()/1000.0) + " seconds: image 12, sagittal");
} else if (choice == 13) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/seg.jpg");
println((millis()/1000.0) + " seconds: image 13, seg");
} else if (choice == 14) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/surface.png");
println((millis()/1000.0) + " seconds: image 14, surface");
} else if (choice == 15) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/tau.jpg");
println((millis()/1000.0) + " seconds: image 15, tau");
} else if (choice == 16) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/tracts.jpg");
println((millis()/1000.0) + " seconds: image 16, tracts");
} else if (choice == 17) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/treated.jpg");
println((millis()/1000.0) + " seconds: image 17, treated");
} else if (choice == 18) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/tumor.jpg");
println((millis()/1000.0) + " seconds: image 18, tumor");
} else if (choice == 19) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/vessel.jpg");
println((millis()/1000.0) + " seconds: image 19, vessel");
} else if (choice == 20) {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/whitematter.jpg");
println((millis()/1000.0) + " seconds: image 20, whitematter");
} else {
src = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/color/image.jpg");
println((millis()/1000.0) + " seconds: image 0, image");
}
}
void render() {
canvas.beginDraw();
canvas.noStroke();
physics.update();
for (int i = physics.particles.size() - 1; i > 0; i--) {
Particle p = (Particle) physics.particles.get(i);
float x1 = map(p.x, 0, width, 0, canvas.width);
float y1 = map(p.y, 0, height, 0, canvas.height);
canvas.fill(lerpColor(p.pixel1, p.pixel2, noise(p.colorNoise)));
p.radiusNoise += analog[199]/150000.00; //affects ALL, change 15000.00 based on output
p.colorNoise += analog[199]/100000.00; //affects ALL, change 10000.00 based on output
float r = map(noise(p.radiusNoise), 0, 1, p.maxRadius/20, p.maxRadius);
canvas.strokeWeight(1);
canvas.ellipse(x1, y1, r, r);
}
canvas.endDraw();
}
void serialEvent(Serial myPort) {
String ardIn = myPort.readStringUntil(linefeed);
if (ardIn != null) {
ardIn = trim(ardIn);
input = float(split(ardIn, ','));
//input = round(input); //can round in next parts of program
//printArray(input[0]);
if (counter%4 == 0 && counter !=0) {
//println("DIG EV");
digitalEvent=true;
counter++;
} else {
//println("ANA EV");
analogEvent=true;
counter++;
}
delay(200);
}
}
void eventHappen() {
if (analogEvent) {
for (int j = 1; j < n; j++)
analog[j-1] = analog[j];
for (int i = 0; i < 1; i++)
analog[n-1] = input[i];
//printArray(analog);
analogEvent=false;
//println("Made it to ANALOGEVENT");
}
if (digitalEvent) {
for (int j = 1; j < n; j++)
digital[j-1] = digital[j];
for (int i = 0; i < 1; i++)
digital[n-1] = input[i];
//printArray(digital);
digitalEvent=false;
//println("Made it to DIGITALEVENT");
}
}
//The EEGen Project
//Created by Galya Oberman
//theeegenproject.wordpress.com
//Art code adapted from Chris Riebschlager
//https://github.com/riebschlager/attraction-repulsion
//The program begins with the prompt system on one screen and the art program on another. The art system will begin automatically after the prompt system cues it, after all the intro information.
//Frames begin to save after the art system begins.
//import Arduino serial and toxiclibs physics (https://bitbucket.org/postspectacular/toxiclibs/downloads/) libraries
import processing.serial.*;
import toxi.geom.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;
int linefeed = 10; //ASCII code for linefeed
float[] input = new float[1]; //temporary store for values
float[] digital = new float[200]; //array to store incoming digital pin values (frequency)
float[] analog = new float [200]; //array to store incoming analog pin values (voltage)
int n = 200; //size of arrays
int counter = 1; //keeps track of serial input to determine analog or digital filtering into arrays
boolean analogEvent = false; //used to sort incoming serial data values
boolean digitalEvent = false; //used to sort incoming serial data values
//declare serial and printwriter
Serial myPort;
PrintWriter output;
VerletPhysics2D physics;
ArrayList<Attractor> attractors = new ArrayList<Attractor>();
PImage src;
PGraphics canvas;
PImage background;
Vec2D mousePos;
//CUSTOMS - adjust based on analog input range
int randAtt = int(random(400, 575)); //choose random number for attractor addition
int randRep = int(random(400, 575)); //chooose random number for repeller addition
int randPart = int(random(400, 575)); //choose random number for particle addition
int randClear = int(random(400, 575)); //choose random number for clearing of att and rep
int randPushPix = int(random(400, 575)); //choose random number for pushPixel()
int randXNoise = (int(random(4000, 40000))); //choose random number for att/rep x noise
int randYNoise = (int(random(4000, 40000))); //choose random number for att/rep y noise
int randKeyP = int(random(0, 51)); //choose random number for number of particles
boolean firstRun = true; //initializes sketch with particles already made
boolean trigger = false; //cues art program to begin; is cued at the beginning of the activity section of the prompt program
boolean endTrig = false; //throws art program out of the draw loop; is cued at the end of the activity section of the prompt program
void settings() {
size(1000, 750); //actual window size
//fullScreen(1);
}
void setup() {
canvas = createGraphics(1920, 1080); //size of image which forms the boundaries outside the main window
canvas.beginDraw();
canvas.endDraw();
background = loadImage("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/img/background.png");
if (background.width != width || background.height != height) background.resize(width, height);
//src = loadImage("C:/Users/Galya's/Documents/Processing/attraction-repulsion-master/AttractionRepulsion/data/img/color/nissl.gif");
println ("INITIALIZE\nrandAtt = " + randAtt + "\nrandRep = " + randRep + "\nrandPart = " + randPart + "\nrandClear = " + randClear + "\nrandPushPix = " + randPushPix);
pushPixel(int(random(0, 21))); //first read in value, gives value between 1 and 20 to choose color of pixels
physics = new VerletPhysics2D();
physics.setDrag(0.75f);
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil(linefeed);
//println(Serial.list()); //use to check serial port
//random fill
for (int j = 1; j < n; j++)
analog[j] = int(random(0, 1023.1));
for (int j = 1; j < n; j++)
digital[j] = int(random(7, 32.1));
String[] args = {"TwoFrameTest"};
SecondApplet sa = new SecondApplet();
PApplet.runSketch(args, sa);
}
void draw() {
eventHappen();
src.loadPixels();
background(background);
render();
image(canvas, 0, 0, width, height);
if (endTrig)
noLoop();
if (trigger) {
if (firstRun) {
//make programs begin at same time(after intro of prompts)
for (int i = 0; i < 50; i++) {
addParticle();
}
firstRun = false;
}
for (int i = 0; i < attractors.size(); i++) {
Attractor a = attractors.get(i);
if (a.behavior == 1) a.setStrength(map(noise(a.strengthNoise), 0, 1, 0, 2)); // last number sets range
if (a.behavior == -1) a.setStrength(map(noise(a.strengthNoise), 0, 1, -2, 0)); //third number sets range
a.position.x = map(noise(a.xNoise), 0, 1, 0, width);
a.position.y = map(noise(a.yNoise), 0, 1, 0, height);
a.strengthNoise += digital[199]/1000;
a.xNoise += digital[199]/randXNoise;
a.yNoise += digital[198]/randYNoise;
if (a.behavior == 1) {
noFill();
noStroke();
}//color of attractor, fill(0, 200, 0);
if (a.behavior == -1) {
noFill();
noStroke();
}//color of repeller, fill(200, 0, 0);
strokeWeight(0.5);
ellipse(a.position.x, a.position.y, 5, 5);
}
saveFrameForVideo(); //use to record
//trigger events
if (analog[199] < randAtt + 25 && analog[199] > randAtt - 25 ) {
addAttractor(1);
randAtt = int(random(400, 575));
println((millis()/1000.0) + " seconds: attractor added");
randXNoise = (int(random(4000, 40000)));
}
if (analog[199] < randRep + 20 && analog[199] > randRep - 20) {
addAttractor(-1);
randRep = int(random(400, 575));
println((millis()/1000.0) + " seconds: repeller added");
randYNoise = (int(random(4000, 40000)));
}
if (analog[199] < randPart + 15 && analog[199] > randPart - 15) {
for (int i = 0; i < 25; i++)
addParticle();
randPart = int(random(400, 575));
println((millis()/1000.0) + " seconds: particles added");
}
if (analog[199] < randClear + 10 && analog[199] > randClear - 10) {
attractors.clear();
randClear = int(random(400, 575));
println((millis()/1000.0) + " seconds: CLEARED");
}
if (analog[199] < randPushPix + 15 && analog[199] > randPushPix - 10) {
pushPixel(int(analog[199])%21);
randPushPix = int(random(400, 575));
}
}
}
void saveFrameForVideo() {
String fileName = nf(frameCount, 5) + ".tif";
saveFrame("C:/Users/Galya's/Desktop/The EEGen Program/TheEEGenProgram/data/video/INITIALS" + fileName); //change to your own file path for frame storage
delay(100);
}