28. September 2012
Flubi ist ein interaktiver "Gummiball" welcher über 4 Infrarot-Distanz-Messer gesteuert wird. Durch schnellere Handbewegungen richtung Flubi wird er Physikalisch im Raum herumgeschleudert. Durch feine Bewegungen kann er verformt werden. Mit mehreren Personen kann er sogar zusammengedrückt werden bis er blau wird und keine Luft mehr bekommt. Die Farben ändern sich je nach Beschleunigung oder Presswerte.
Die Schwierigkeit bei dieser Aufgabe lag darin die schwankenden Werte zu regulieren. Auch das kleine Spektrum der Sensoren sind schwierig zu kontrollieren und führten Anfangs immer zu Fehlern
CODE
import processing.serial.*; // Import the Processing Serial Library for communicating with arduino Serial myPort; // The used Serial Port int left, right, front, back; int sizeX = 1024; int sizeY = 786; int coords[] = new int[4]; int coordsOld[] = new int[4]; int distanceX[] = new int[4]; int distanceY[] = new int[4]; int distanceXOld[] = new int[4]; int distanceYOld[] = new int[4]; PVector position = new PVector(0, 0); PVector positionOld = new PVector(0, 0); PVector movement = new PVector(0,0); //Bewegung über den Bildschirm int flubberWidth; int flubberHeight; float newMulti = 0.05; float oldMulti = 0.95; float magnetStrength = 0.4; void setup() { size(sizeX, sizeY); background(255); //println(Serial.list()); // Prints the list of serial available devices (Arduino should be on top of the list) myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud //frameRate(20); randomSeed(millis() * 1024 ^ 16); positionOld.x = position.x = sizeX/2; positionOld.y = position.y = sizeY/2; } void draw() { navigate(); flubber(); } void navigate() { int coordsChange[] = new int[4]; //Veraenderung der Koordinatenposition flubberWidth = coords[1] + coords[0] - 20; flubberHeight = coords[3] + coords[2] - 20; println(flubberWidth); coordsChange[0] = coordsOld[0] - coords[0]; if(coordsChange[0] <= 2) coordsChange[0] = 0; coordsChange[1] = coordsOld[1] - coords[1]; if(coordsChange[1] <= 2) coordsChange[1] = 0; coordsChange[2] = coordsOld[2] - coords[2]; if(coordsChange[2] <= 2) coordsChange[2] = 0; coordsChange[3] = coordsOld[3] - coords[3]; if(coordsChange[3] <= 2) coordsChange[3] = 0; /*** Magnet ***/ if(coordsChange[0] == 0 && coordsChange[1] == 0 && coordsChange[2] == 0 && coordsChange[3] == 0) { if(position.x < sizeX/2) position.x += magnetStrength; else position.x -= magnetStrength; if(position.y < sizeY/2) position.y += magnetStrength; else position.y -= magnetStrength; } movement.add(6 * (coordsChange[0] - coordsChange[1]), 6 * (coordsChange[2] - coordsChange[3]), 0); movement.mult(oldMulti); position = PVector.add(position, movement); if(position.x - flubberWidth/2 < 0) { movement.x *= -1; position.x = flubberWidth/2; } else if(position.x + flubberWidth/2 > sizeX) { movement.x *= -1; position.x = sizeX - flubberWidth/2; } if(position.y - flubberHeight/2 < 0) { movement.y *= -1; position.y = flubberHeight/2; } else if(position.y + flubberHeight/2 > sizeY) { movement.y *= -1; position.y = sizeY - flubberHeight/2; } //position = PVector.add(PVector.mult(position, newMulti), PVector.mult(positionOld, oldMulti)); /*position.x = sizeX/2; position.y = sizeY/2;*/ } void flubber() { /*left = coords[0]; right = coords[1]; front = coords[2]; back = coords[3];*/ int distanceWidth = 1; int distanceTilt = int(random(0, 20)); distanceX[0] = distanceTilt; distanceX[1] = distanceTilt; distanceX[2] = coords[2] * distanceWidth; distanceX[3] = coords[3] * distanceWidth; if(distanceXOld[0] != 0) distanceX[0] = int(distanceX[0] * newMulti + distanceXOld[0] * oldMulti); if(distanceXOld[1] != 0) distanceX[1] = int(distanceX[1] * newMulti + distanceXOld[1] * oldMulti); if(distanceXOld[2] != 0) distanceX[2] = int(distanceX[2] * newMulti + distanceXOld[2] * oldMulti); if(distanceXOld[3] != 0) distanceX[3] = int(distanceX[3] * newMulti + distanceXOld[3] * oldMulti); distanceXOld[0] = distanceX[0]; distanceXOld[1] = distanceX[1]; distanceXOld[2] = distanceX[2]; distanceXOld[3] = distanceX[3]; distanceY[0] = coords[0] * distanceWidth; distanceY[1] = coords[1] * distanceWidth; distanceY[2] = distanceTilt; distanceY[3] = distanceTilt; if(distanceYOld[0] != 0) distanceY[0] = int(distanceY[0] * newMulti + distanceYOld[0] * oldMulti); if(distanceYOld[1] != 0) distanceY[1] = int(distanceY[1] * newMulti + distanceYOld[1] * oldMulti); if(distanceYOld[2] != 0) distanceY[2] = int(distanceY[2] * newMulti + distanceYOld[2] * oldMulti); if(distanceYOld[3] != 0) distanceY[3] = int(distanceY[3] * newMulti + distanceYOld[3] * oldMulti); distanceYOld[0] = distanceY[0]; distanceYOld[1] = distanceY[1]; distanceYOld[2] = distanceY[2]; distanceYOld[3] = distanceY[3]; fill(0, 0, 100, 90); rect(0, 0, sizeX, sizeY); noStroke(); pushMatrix(); translate(position.x, position.y); /*rotate(radians(45)); translate(-sizeX/2,-sizeY/2);*/ colorMode(HSB, 100); fill(((coords[0] + coords[1] + coords[2] + coords[3]) / 5 + 50) % 100, 100, 50); beginShape(); vertex(0, -coords[2]); bezierVertex(distanceX[2], -coords[2] + distanceY[2], coords[1] - distanceX[1], -distanceY[1], coords[1], 0); bezierVertex(coords[1] + distanceX[1], distanceY[1], distanceX[3], coords[3] + distanceY[3], 0, coords[3]); bezierVertex(-distanceX[3], coords[3] - distanceY[3], -coords[0] + distanceX[0], distanceY[0], -coords[0], 0); bezierVertex(-coords[0] - distanceX[0], -distanceY[0], -distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]); endShape(); /*line(0, -coords[2], distanceX[2], -coords[2] + distanceY[2]); line(coords[1] - distanceX[1], -distanceY[1], coords[1], 0); line(coords[1], 0, coords[1] + distanceX[1], distanceY[1]); line(distanceX[3], coords[3] + distanceY[3], 0, coords[3]); line(0, coords[3], -distanceX[3], coords[3] - distanceY[3]); line(-coords[0] + distanceX[0], distanceY[0], -coords[0], 0); line(-coords[0], 0, -coords[0] - distanceX[0], -distanceY[0]); line(-distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);*/ coordsOld[0] = coords[0]; coordsOld[1] = coords[1]; coordsOld[2] = coords[2]; coordsOld[3] = coords[3]; popMatrix(); } void serialEvent(Serial myPort) // Is called everytime there is new data to read { if (myPort.available() > 0) { String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return if (completeString != null) // If there is valid data insode the String { trim(completeString); // Remove whitespace characters at the beginning and end of the string String seperateValues[] = split(completeString, ";"); // Split the string everytime a delimiter is received //println(seperateValues.length); for(int j = 0; j < seperateValues.length-1; j++) { if(j < 4) coords[j] = round(1.5 * int(seperateValues[j])); //println(j); } //if(seperateValues.length == 4) println(coords[0] + " " + coords[1] + " " + coords[2] + " " + coords[3]); } } } boolean sketchFullScreen() { return true; }
import processing.serial.*; // Import the Processing Serial Library for communicating with arduino Serial myPort; // The used Serial Port int left, right, front, back; int sizeX = 1024; int sizeY = 786; int coords[] = new int[4]; int coordsOld[] = new int[4]; int distanceX[] = new int[4]; int distanceY[] = new int[4]; int distanceXOld[] = new int[4]; int distanceYOld[] = new int[4]; PVector position = new PVector(0, 0); PVector positionOld = new PVector(0, 0); PVector movement = new PVector(0,0); //Bewegung über den Bildschirm int flubberWidth; int flubberHeight; float newMulti = 0.05; float oldMulti = 0.95; float magnetStrength = 0.4; void setup() { size(sizeX, sizeY); background(255); //println(Serial.list()); // Prints the list of serial available devices (Arduino should be on top of the list) myPort = new Serial(this, Serial.list()[0], 9600); // Open a new port and connect with Arduino at 9600 baud //frameRate(20); randomSeed(millis() * 1024 ^ 16); positionOld.x = position.x = sizeX/2; positionOld.y = position.y = sizeY/2; } void draw() { navigate(); flubber(); } void navigate() { int coordsChange[] = new int[4]; //Veraenderung der Koordinatenposition flubberWidth = coords[1] + coords[0] - 20; flubberHeight = coords[3] + coords[2] - 20; println(flubberWidth); coordsChange[0] = coordsOld[0] - coords[0]; if(coordsChange[0] <= 2) coordsChange[0] = 0; coordsChange[1] = coordsOld[1] - coords[1]; if(coordsChange[1] <= 2) coordsChange[1] = 0; coordsChange[2] = coordsOld[2] - coords[2]; if(coordsChange[2] <= 2) coordsChange[2] = 0; coordsChange[3] = coordsOld[3] - coords[3]; if(coordsChange[3] <= 2) coordsChange[3] = 0; /*** Magnet ***/ if(coordsChange[0] == 0 && coordsChange[1] == 0 && coordsChange[2] == 0 && coordsChange[3] == 0) { if(position.x < sizeX/2) position.x += magnetStrength; else position.x -= magnetStrength; if(position.y < sizeY/2) position.y += magnetStrength; else position.y -= magnetStrength; } movement.add(6 * (coordsChange[0] - coordsChange[1]), 6 * (coordsChange[2] - coordsChange[3]), 0); movement.mult(oldMulti); position = PVector.add(position, movement); if(position.x - flubberWidth/2 < 0) { movement.x *= -1; position.x = flubberWidth/2; } else if(position.x + flubberWidth/2 > sizeX) { movement.x *= -1; position.x = sizeX - flubberWidth/2; } if(position.y - flubberHeight/2 < 0) { movement.y *= -1; position.y = flubberHeight/2; } else if(position.y + flubberHeight/2 > sizeY) { movement.y *= -1; position.y = sizeY - flubberHeight/2; } //position = PVector.add(PVector.mult(position, newMulti), PVector.mult(positionOld, oldMulti)); /*position.x = sizeX/2; position.y = sizeY/2;*/ } void flubber() { /*left = coords[0]; right = coords[1]; front = coords[2]; back = coords[3];*/ int distanceWidth = 1; int distanceTilt = int(random(0, 20)); distanceX[0] = distanceTilt; distanceX[1] = distanceTilt; distanceX[2] = coords[2] * distanceWidth; distanceX[3] = coords[3] * distanceWidth; if(distanceXOld[0] != 0) distanceX[0] = int(distanceX[0] * newMulti + distanceXOld[0] * oldMulti); if(distanceXOld[1] != 0) distanceX[1] = int(distanceX[1] * newMulti + distanceXOld[1] * oldMulti); if(distanceXOld[2] != 0) distanceX[2] = int(distanceX[2] * newMulti + distanceXOld[2] * oldMulti); if(distanceXOld[3] != 0) distanceX[3] = int(distanceX[3] * newMulti + distanceXOld[3] * oldMulti); distanceXOld[0] = distanceX[0]; distanceXOld[1] = distanceX[1]; distanceXOld[2] = distanceX[2]; distanceXOld[3] = distanceX[3]; distanceY[0] = coords[0] * distanceWidth; distanceY[1] = coords[1] * distanceWidth; distanceY[2] = distanceTilt; distanceY[3] = distanceTilt; if(distanceYOld[0] != 0) distanceY[0] = int(distanceY[0] * newMulti + distanceYOld[0] * oldMulti); if(distanceYOld[1] != 0) distanceY[1] = int(distanceY[1] * newMulti + distanceYOld[1] * oldMulti); if(distanceYOld[2] != 0) distanceY[2] = int(distanceY[2] * newMulti + distanceYOld[2] * oldMulti); if(distanceYOld[3] != 0) distanceY[3] = int(distanceY[3] * newMulti + distanceYOld[3] * oldMulti); distanceYOld[0] = distanceY[0]; distanceYOld[1] = distanceY[1]; distanceYOld[2] = distanceY[2]; distanceYOld[3] = distanceY[3]; fill(0, 0, 100, 90); rect(0, 0, sizeX, sizeY); noStroke(); pushMatrix(); translate(position.x, position.y); /*rotate(radians(45)); translate(-sizeX/2,-sizeY/2);*/ colorMode(HSB, 100); fill(((coords[0] + coords[1] + coords[2] + coords[3]) / 5 + 50) % 100, 100, 50); beginShape(); vertex(0, -coords[2]); bezierVertex(distanceX[2], -coords[2] + distanceY[2], coords[1] - distanceX[1], -distanceY[1], coords[1], 0); bezierVertex(coords[1] + distanceX[1], distanceY[1], distanceX[3], coords[3] + distanceY[3], 0, coords[3]); bezierVertex(-distanceX[3], coords[3] - distanceY[3], -coords[0] + distanceX[0], distanceY[0], -coords[0], 0); bezierVertex(-coords[0] - distanceX[0], -distanceY[0], -distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]); endShape(); /*line(0, -coords[2], distanceX[2], -coords[2] + distanceY[2]); line(coords[1] - distanceX[1], -distanceY[1], coords[1], 0); line(coords[1], 0, coords[1] + distanceX[1], distanceY[1]); line(distanceX[3], coords[3] + distanceY[3], 0, coords[3]); line(0, coords[3], -distanceX[3], coords[3] - distanceY[3]); line(-coords[0] + distanceX[0], distanceY[0], -coords[0], 0); line(-coords[0], 0, -coords[0] - distanceX[0], -distanceY[0]); line(-distanceX[2], - coords[2] - distanceY[2], 0, -coords[2]);*/ coordsOld[0] = coords[0]; coordsOld[1] = coords[1]; coordsOld[2] = coords[2]; coordsOld[3] = coords[3]; popMatrix(); } void serialEvent(Serial myPort) // Is called everytime there is new data to read { if (myPort.available() > 0) { String completeString = myPort.readStringUntil(10); // Read the Serial port until there is a linefeed/carriage return if (completeString != null) // If there is valid data insode the String { trim(completeString); // Remove whitespace characters at the beginning and end of the string String seperateValues[] = split(completeString, ";"); // Split the string everytime a delimiter is received //println(seperateValues.length); for(int j = 0; j < seperateValues.length-1; j++) { if(j < 4) coords[j] = round(1.5 * int(seperateValues[j])); //println(j); } //if(seperateValues.length == 4) println(coords[0] + " " + coords[1] + " " + coords[2] + " " + coords[3]); } } } boolean sketchFullScreen() { return true; }VIDEO