Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

GDB Aufgabe 05 – Interaktion – letzter Stand

8. Dezember 2011

Dies ist ein letzter Stand vor der Abschlusspräsentation, mit funktionierender Kinect-Integration.
  • Neue Funktionen
    • 'q' to toggle input (Mouse or Kinect)
Der Code vom Bouncing-Ball Beispiel ist immer noch vorhanden, hat aber ausser dem Drag-Effekt keine Auswirkungen mehr auf das Programm. Mit dem Code wollte ich eigentlich noch eine Physik-Funktion einbauen, aber ich bin nicht mehr so weit gekommen.
/* --------------------------------------------------------------------------
* Graphic Design Basics - Mouse Animation / Interaktion
* --------------------------------------------------------------------------
* prog:  Beni Achermann (based on Max Rheiner's examples 🙂
* date:  17/11/2011
* ----------------------------------------------------------------------------
*/


// Importieren der Fullscreen-Library
import fullscreen.*;

// Initialisieren der HandCapture / simpleOpenNI Klasse
HandCapture   handCapture;
boolean       drawFlag=false;

FullScreen fullScreen;

ArrayList zeichen = new ArrayList(); // erstellen einer neuen ArrayList

// PVector variables for the function that allows moving signs around
PVector      p1Move = new PVector();
PVector      p2Move = new PVector();

// PVector variables for the animations caused by moving the cursor
PVector p1 = new PVector();
PVector p2 = new PVector();

boolean drag = false;

boolean infoPanel = true;

int gridSize = 7; // 7*7 creates a grid of 49 signs

int rand;
int randInitial;
int formNumber = 1;

boolean inputToggle = false;


void setup()
{
size(1024,768);
smooth();
rectMode(CENTER);
ellipseMode(CENTER);
frameRate(20);

// Kinect / OpenNI
handCapture = new HandCapture(this);


randInitial = 70;
rand = randInitial;

noCursor();
loop();  // interesting effects if turned off!

// Populate the zeichen array
for (int i=0; i<gridSize*gridSize;i++)
{
zeichen.add(new Zeichen(0, 0));
}

fullScreen = new FullScreen(this);
fullScreen.enter();

} // end of setup

void draw()
{

//  pushStyle();            // visual help for fullscreen mode
//    rectMode(CORNER);
//    noFill();
//    stroke(255,0,0);
//    strokeWeight(3);
//    rect(0,0,width,height);
//  popStyle();

float trackerX;
float trackerY;
float trackerZ;

// Kinect / OpenNI

handCapture.update();

pushMatrix();
PVector handPos = handCapture.handPos();
float handX = map(handPos.x,0,640,0,width);
float handY = map(handPos.y,0,480,0,height);
float handZ = map(handPos.z,0,480,0,height);
popMatrix();

if(inputToggle) {
trackerX = mouseX;
trackerY = mouseY;
trackerZ = 0;
pushStyle();
fill(255);
text("Mouse", width-100,30);
popStyle();
} else {
trackerX = handX;
trackerY = handY;
trackerZ = handZ;
pushStyle();
fill(255);
text("Kinect", width-100,30);
//text(handZ, width-200,60);
popStyle();
//    if(handCapture.isHandTracked())
//    {
//        // draw a red dot at the position of Die Hand
//
//       pushStyle();
//        stroke(255,0,0);
//        strokeWeight(8);
//        point(handX,handY);
//      popStyle();
//    }
}




float   xStep;
float   yStep;
xStep = (width - 2 * rand) / (float)(gridSize-1);
yStep = (height - 2 * rand) / (float)(gridSize-1);

// ghosting
pushStyle();
rectMode(CORNER);
fill(0, 0, 0, 40);
noStroke();
rect(0, 0, width, height);
popStyle();

if (drag)
{ // zeichne die abschussrichtung
pushStyle();
stroke(0, 255, 0);
line(p1Move.x, p1Move.y, p2Move.x, p2Move.y);
popStyle();
}

// zeichne die Zeichen 🙂

pushMatrix();
translate(rand, rand);
for (int i=0; i<gridSize;i++)
{
pushMatrix();
for (int j=0; j<gridSize;j++)
{

// Start of stuff needed for cursor animation
float adjustedMouseX = trackerX - width / 4;
float adjustedMouseY = trackerY - height / 4;

float posX = j * xStep+rand;
float posY = i * yStep+rand;
float distValueAdj = sqrt(sq((adjustedMouseX-posX))+sq((adjustedMouseY-posY)));
float distValue = sqrt(sq((trackerX-posX))+sq((trackerY-posY)));
//float angleMouse = atan2(mouseVect.y - matrix[i].y, mouseVect.x - matrix[i].x);
float distValueZ = sqrt(sq((trackerZ-posX))+sq((trackerZ-posY)));

p1.set (posX, posY, 0);
p2.set (adjustedMouseX, adjustedMouseY, 0);
PVector dir = PVector.sub(p2, p1);
// end of stuff needed for cursor animation
//


Zeichen ball = (Zeichen) zeichen.get(j);
ball.draw(0, 0, distValue, distValueAdj, distValueZ);
translate(xStep, 0.0f);
}
popMatrix();
translate(0.0f, yStep);
}
popMatrix();

displayInfoPanel();
}

void mousePressed()
{
drag = true;
p1Move.set(mouseX, mouseY, 0);
p2Move.set(mouseX, mouseY, 0);
}

void mouseDragged()
{
p2Move.set(mouseX, mouseY, 0);
}

void displayInfoPanel()
{
if (infoPanel)
{
pushMatrix();
pushStyle();
// background / shadow (grey rectangle)
fill(60);
strokeJoin(ROUND);
stroke(60);
strokeWeight(12);
rect(width/2+3, height/2+3, width/2, height/4);
// foreground / background for text (white rectangle)
fill(255);
strokeJoin(ROUND);
stroke(255);
strokeWeight(12);
rect(width/2, height/2, width/2, height/4);
infoPanelText(width/2,height/2 - 80);


popMatrix();
popStyle();
}
else {

}
}


void infoPanelText(int textX, int textY)
{
String[] textInfo =  {
"move the cursor to trigger animations",
"'i' to hide or display this panel",
"'w' and 'e' to switch forms",
" ",
"'a' and 'd' to change distance between signs",
"'r' to reset distance to initial value",
" ",
"'s' to save a screenshot",
"'q' to toggle input (Mouse or Kinect)",
" ",
"Distance: " + rand,
"Form: " + formNumber,
};

String superText = "";

for(int i = 0; i < textInfo.length; i++)
{
superText += textInfo[i]+"\r\n";
}
fill(0);
textAlign(CENTER);
text(superText, textX, textY);

} // end of infoPanelText

void mouseReleased()
{
drag = false;

// abschuss staerke berechnen
PVector dir = PVector.sub(p2Move, p1Move);
// laenge verkuerzen
dir.mult(.09);

// der ball wird neu ausgerichtet
Zeichen temp = new Zeichen(100, 100);
temp.set(p1Move, dir, .993);
//  zeichen.add(temp);
}



// KEYBOARD FUNCTIONS
void keyPressed()
{
switch(key)
{
case 's':
saveFrame("screenshot-####.png");      // Speichern eines Screenshots auf Druck von S
println("Saved screenshot-##.png");
redraw();
break;
case 'd':
rand+=40;
if (rand > 390) {   // If rand ist bigger than %
rand = randInitial;        //...set it back to 10
}
println("Increased distance from rand to " + rand);

redraw();
break;
case 'a':
rand-=40;
if (rand < randInitial) {   // If rand ist smaller than 10
rand = 390;              //...set it back to %
}
println("Increased rand to " + rand);
redraw();
break;

case 'w':
formNumber++;
if (formNumber > 7) {   // If formNumber ist bigger than 6
formNumber = 1;        //...set it back to 1
}
println("Form: " + formNumber);
redraw();
break;

case 'e':
formNumber--;
if (formNumber < 1) {   // If formNumber is smaller than 1
formNumber = 6;        //...set it back to 6
}
println("Form: " + formNumber);
redraw();
break;

case 'i':
if (infoPanel)
{
infoPanel = false;
println("Hiding information screen");
}
else {
infoPanel = true;
println("Displaying information screen");
}

redraw();
break;

case 'r':
rand = randInitial;
redraw();
break;
case 'q':
if (inputToggle)
{
inputToggle = false;
println("Switched to Kinect input");
}
else {
inputToggle = true;
println("Switched to Mouse input");
}

redraw();
break;
}
}


// hand events

void onCreateHands(int handId,PVector pos,float time)
{
handCapture.onCreateHands(handId,pos,time);
}

void onUpdateHands(int handId,PVector pos,float time)
{
handCapture.onUpdateHands(handId,pos,time);
}

void onDestroyHands(int handId,float time)
{
handCapture.onDestroyHands(handId,time);
}

void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
handCapture.onRecognizeGesture(strGesture,idPosition,endPosition);
}

void onProgressGesture(String strGesture, PVector position,float progress)
{
handCapture.onProgressGesture(strGesture,position,progress);
}

import SimpleOpenNI.*;

class HandCapture
{
  import SimpleOpenNI.*;

class HandCapture
{
SimpleOpenNI  _context;
boolean       _drawFlag=false;
PVector       _handVec = new PVector();
String        _lastGesture = "";
PVector       _screenPos = new PVector();
PApplet       _parent;
boolean       _handsTrackFlag = false;

HandCapture(PApplet parent)
{
_parent = parent;

_context = new SimpleOpenNI(_parent);

// mirror is by default enabled
_context.setMirror(true);

// enable depthMap
_context.enableDepth();

// enable camera
_context.enableRGB();

_context.enableHands();
_context.enableGesture();

_context.addGesture("RaiseHand");

// align depth data to image data
_context.alternativeViewPointDepthToImage();

}

boolean isHandTracked() { return _handsTrackFlag; }

PVector handPos() { return _screenPos; }
PVector handPos3d() { return _handVec; }

PImage depthImage() { return _context.depthImage(); }
PImage rgbImage() { return _context.rgbImage(); }


int width() { return _context.depthWidth(); }
int height() { return _context.depthHeight(); }

void update()
{
_context.update();

_context.convertRealWorldToProjective(_handVec,_screenPos);
}

void onCreateHands(int handId, PVector pos, float time)
{
_handsTrackFlag = true;
_handVec = pos;
}

void onUpdateHands(int handId, PVector pos, float time)
{
_handVec = pos;
}

void onDestroyHands(int handId, float time)
{
_handsTrackFlag = false;
_context.addGesture(_lastGesture);
}

void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
_lastGesture = strGesture;
_context.removeGesture(strGesture);
_context.startTrackingHands(endPosition);
}

void onProgressGesture(String strGesture, PVector position, float progress)
{
}
}



/* --------------------------------------------------------------------------
* Zeichenklasse
* --------------------------------------------------------------------------
* prog:  Beni Achermann
* date:  24/11/2011
* ----------------------------------------------------------------------------
*/

class Zeichen
{
PVector _pos;
PVector _dir;
float   _dampV;
int     _w;
int     _h;
int formSize = 90;

float dist;


float distValueGlobal;
float distValueZ;
float distValueAdjGlobal;
float scaler;

// konstruktor
Zeichen(int x, int y)
{
_pos = new PVector(width/2, height/2);
_dir = new PVector(0, 0);
_dampV = 1;
}

// setzt die neue pos + richtung + daempfung
void set(PVector pos, PVector dir, float dampV)
{
_pos = pos.get();
_dir.add(dir);
_dampV = dampV;
}

// erneuert die aktuelle position
void calcPos()
{
// aktuelle position verschieben
_pos.add(_dir);

// bewegungs vektor veraendert
_dir.mult(_dampV);

// teste horizontal
if (_pos.x + _w/2 > width)
{
_dir.x *= -1;
_pos.x = width - _w/2;
}
else if (_pos.x - _w/2 < 0)
{
_dir.x *= -1;
_pos.x = _w/2;
}

// teste vertikal
if (_pos.y + _h/2 > height)
{
_dir.y *= -1;
_pos.y = height - _w/2;
}
else if (_pos.y - _h/2 < 0)
{
_dir.y *= -1;
_pos.y = _h/2;
}
}

// zeichnet die Zeichen
void draw(int x, int y, float _distValue, float _distValueAdj, float _distValueZ)
{
distValueGlobal = _distValue;
distValueZ = _distValueZ;
distValueAdjGlobal = _distValueAdj;

calcPos();

switchingZeichen(x, y);
}


// CODE FOR CONSTRUCTING THE BASIC FORMS

void switchingZeichen(float x, float y)
{
if (formNumber == 1)
{
// white ellipse & with smaller black one in it, innit.
drawSign1(x, y);
}
if (formNumber == 2)
{
// the symbol from aufgabe 04
drawSign2(x, y);
}
if (formNumber == 3)
{
// very small ellipses (dots) in a grid
pushMatrix();
drawSign3(x-formSize/2, y-formSize/2);      // x/y - formSize/2 because all other forms are automatically centered
popMatrix();
}
if (formNumber == 4)
{
// ellipse with outline
drawSign4(x, y);
}
if (formNumber == 5)
{
// lineament =======
drawSign5(x-formSize/2, y-formSize/2);
}
if (formNumber == 6)
{
// geknicktes Lineament \/\/\/\/\/\/\/
drawSign6(x-formSize/2, y-formSize/2);
}
if (formNumber == 7)
{
//very small ellipses (dots) in a grid
drawSign7(x-formSize/2, y-formSize/2);
}
}


void drawSign1(float x, float y)
{
// white ellipse & with smaller black one in it, innit.
dist = map(distValueGlobal, 0, width, 0, 100); // mouse animation
scaler = map(distValueGlobal, 0, width, 0, 1.5); // mouse animation
pushMatrix();
scale(scaler); // mouse animation
pushStyle();
fill(255);
ellipse(0, 0, formSize, formSize);
fill(0);
noStroke();
translate(map(distValueGlobal, 0, width, -10, 10),map(distValueGlobal, 0, width, -5, 5));
ellipse(0, 0, formSize/3, formSize/3);
popStyle();
popMatrix();
}


void drawSign2(float x, float y)
{
// the symbol from aufgabe 04
pushStyle();
scale(map(distValueGlobal, 0, width, 0.1, 2.0));
circleFilledWhiteOutlineBlack(x, y, 1.0, 0.0, 4);
popStyle();
pushStyle();
rotate(map(distValueGlobal, 0, width, 1, 30));
circleFilledBlack(x+formSize/2, y, 1.0, 0.0, 0);
popStyle();
pushStyle();
scale(map(distValueGlobal, 0, width, -2.0, 2.0));
circleFilledBlack(x, y, 0.5, 0.0, 0);
popStyle();
pushStyle();
rotate(map(distValueGlobal, 0, width, 1, 30));
circleFilledWhite(x+7, y, 0.5, 0.0, 0);
popStyle();
}

void drawSign3(float x, float y)
{
//very small ellipses (dots) in a grid
dist = map(distValueGlobal, 0, width, 0, 5);
for (int i = 1; i < 9; i++)
{
pushMatrix();
for (int j = 1; j < 9; j++)
{
pushStyle();
fill(255);
noStroke();
ellipse(x, y, 4, 4);
popStyle();
scale(dist);
}
popMatrix();
translate(15, 15);
}
}

void drawSign4(float x, float y)
{
// ellipse with outline
dist = map(distValueGlobal, 0, width * 1.41, 0, 100);
pushStyle();
stroke(2);
fill(255);
ellipse(x, y, dist, formSize);
scale(map(distValueGlobal, 0, width, -3, 2.1));
ellipse(x, y, dist/2, formSize/2);
popStyle();
}

void drawSign5(float x, float y)
{
// lineament =======
dist = map(distValueGlobal, 0, width * 1.41, 0, 15);
pushMatrix();
for (int i = 1; i <= 9; i++)
{
// lines
pushStyle();
stroke(255);
strokeWeight(1);
line(x, y, formSize/2, y);
translate(0, dist);
popStyle();
}
popMatrix();
}

void drawSign6(float x, float y)
{
// geknicktes Lineament \/\/\/\/\/\/\/

// map nimmt den eingehenden Wert (distValueGlobal), welcher sich in einem Range zwischen
// 0 und der Weite des Dokuments befindet.
// Dieser Wert wird dann in den Range zwischen 0 und 100 umgerechnet.
float distX;
float distY;
distX = map(distValueGlobal, 0, width, -formSize/3, formSize/3);
distY = map(distValueGlobal, 0, width, -30, 30);
pushMatrix();
for (int i = 1; i <= 9; i++)
{
pushStyle();
stroke(255);
strokeWeight(1);
line(x, y, distX, y+distY);
line(distX, y+distY, formSize/2, y);
translate(0, 10);
popStyle();
}
popMatrix();
}

void drawSign7(float x, float y)
{
//very small ellipses (dots) in a grid
//rect(x,y,formSize,formSize);
dist = map(distValueGlobal, 0, width * 3, 1, 10);
for (int i = 1; i < 9; i++)
{
pushMatrix();
for (int j = 1; j < 9; j++)
{
pushStyle();
fill(255);
noStroke();
ellipse(x, y, 2, 2);
popStyle();
translate(0, dist);
}
popMatrix();
translate(dist, 0);
}
}

void circleFilledWhite (float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue)
{
pushMatrix();
translate(translateX, translateY);
scale(scaleValue);
rotate(rotateValue);
noStroke();
fill(255);
ellipse(0, 0, formSize, formSize);
popMatrix();
}

void circleFilledWhiteOutlineBlack(float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue)
{
pushMatrix();
translate(translateX, translateY);
scale(scaleValue);
rotate(rotateValue);
fill(0);
strokeWeight(strokeWeightValue);
fill(255);
ellipse(0, 0, formSize, formSize);
popMatrix();
}

void circleFilledBlack (float translateX, float translateY, float scaleValue, float rotateValue, int strokeWeightValue)
{
pushMatrix();
translate(translateX, translateY);
scale(scaleValue);
rotate(rotateValue);
fill(0);
noStroke();
ellipse(0, 0, formSize, formSize);
popMatrix();
}
} // end of class