Urgent question on collision *detection* between shape and images

edited November 2015 in Kinect

I have been stuck at one point for a little while, which is how to do collision detection with ellipses and images.

I'm trying to make a kinect game with skeleton calibration. With six boxes on both sides, changing color, user has to put any of left,right hand or left, right foot to extend to the colored boxes on the side to finish each round.

I've attached two photos of screenshot for a better understanding.

I believe most of the functional stuff is done here but I just can't find out how I can make ellipses(on LRhand,LRfoot) to detect the buttons on both sides. Once it detects all color-changed buttons being collided with ellipses(LRhand,LRfoot), it needs to be able to up the round by 1 and followed by the next round buttons.

I've tried using dist() but it doesn't seem to work well or maybe I'm just not too expert enough to do it.

EVEN A LITTLE BIT OF HELP WILL BE VERY APPRECIATED! THANKS!

To get a better idea, the following is my code:

import SimpleOpenNI.*;
SimpleOpenNI kinect;
PFont font;
String time = "60";
int t;
int interval = 60;
int stage = 1;

void setup() {
  size(640, 480);
  kinect = new SimpleOpenNI(this);
  kinect.enableDepth();
  // turn on user tracking
  kinect.enableUser();
  font = createFont("Arial", 30);
  PImage depth = kinect.depthImage();
  fill(0);
}

void draw() {
  kinect.update();
  PImage depth = kinect.depthImage();
  image(depth, 0, 0);
  // make a vector of ints to store the list of users
  IntVector userList = new IntVector();
  // write the list of detected users into our vector
  kinect.getUsers(userList);
  // if we found any users
  if (userList.size() > 0) {
    // get the first user
    int userId = userList.get(0);
    // if we’re successfully calibrated
    if (stage == 1) {
      if (kinect.isTrackingSkeleton(userId) == false){
      text("ARE YOU FLEXIBLE ENOUGH?!", width/2 - 100, height/2 - 200);
      text("please calibrate to start the game!", width/2 - 100, height/2);
      }
    }
    if ( kinect.isTrackingSkeleton(userId) == true && stage == 1){
      stage = 2;
    }

    if(stage == 2){
    t = interval-int(millis()/1000);
    time = nf(t , 3);
    fill(255);
    if(t <= 10){
      fill(255,0,0);
    }
    if(t == 0){
      text("GAMEOVER", width/2 - 100, height/2 - 150);
      println("GAME OVER");
      noLoop();
    interval+=60;}
    text(time, width/2, height/2 - 130);

    }

    float dL = 100;
  float dR = 100;

  // check if the skeleton is being tracked
  if (kinect.isTrackingSkeleton(1))
  {   
    drawLHand(1);
    drawRHand(1);
    drawRFoot(1);
    drawLFoot(1);

    // get the distance between joints
    PVector pL = new PVector(-500, 0, 1000);
    PVector pR = new PVector(500, 0, 1000); 

    float handDistanceL = getJointDistance(1, SimpleOpenNI.SKEL_LEFT_HAND, pL);
    float handDistanceR = getJointDistance(1, SimpleOpenNI.SKEL_LEFT_HAND, pR);

    dL = map(handDistanceL, 0, 2000, 0, height);
    dR = map(handDistanceR, 0, 2000, 0, height);
  }

  println(dL + ", " + dR);
    int round = 0;
    int score = 0;
    PImage button1,button1p,button2,button2p,button3,button3p,button4,button4p;
    button1 = loadImage("button1.jpg");
    button1p = loadImage("button1p.jpg");
    button2 = loadImage("button2.jpg");
    button2p = loadImage("button2p.jpg");
    button3 = loadImage("button3.jpg");
    button3p = loadImage("button3p.jpg");
    button4 = loadImage("button4.jpg");
    button4p = loadImage("button4p.jpg");
    if (kinect.isTrackingSkeleton(1) == true){
    round = 1;
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    score += 0;
    text("score:  " + score, 30, 10);
    text("round:  " + round, 30, 40);
    }
    if(round == 2){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4p,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    score += 20;
    }
    if(round == 3){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3p,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    score += 40;
    }
    if(round == 4){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4p,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4p,width/2 + 220, height/2 +76);
    score += 40;
    }
    if(round == 5){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1p,width/2 - 320, height/2 +76);
    image(button4,width/2 + 220, height/2 -190);
    image(button2p,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    score += 60;
    }
    if(round == 6){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4p,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4p,width/2 + 220, height/2 +76);
    score += 60;
    }
    if(round == 7){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1p,width/2 - 320, height/2 +76);
    image(button4p,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4p,width/2 + 220, height/2 +76);
    score += 80;
    }
    if(round == 8){
    image(button1p,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1p,width/2 - 320, height/2 +76);
    image(button4p,width/2 + 220, height/2 -190);
    image(button2p,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    score += 100;
    }

    if ( kinect.isTrackingSkeleton(userId) == false) {
    image(button1,width/2 - 320, height/2 -190);
    image(button3,width/2 - 320, height/2 -57);
    image(button1,width/2 - 320, height/2 +76);
    image(button4,width/2 + 220, height/2 -190);
    image(button2,width/2 + 220, height/2 -57);
    image(button4,width/2 + 220, height/2 +76);
    }
    if ( kinect.isTrackingSkeleton(userId)) {
      drawSkeleton(userId);
      stage = 2;
    }
  }
}

// draw the skeleton with the selected joints
void drawSkeleton(int userId)
{  
  // draw limbs  
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);

  kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);

  kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);

  kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);

  kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);

  kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
  kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT);
}


// Event-based Methods

void onNewUser(SimpleOpenNI curContext, int userId)
{
  println("onNewUser - userId: " + userId);
  println("\tstart tracking skeleton");

  curContext.startTrackingSkeleton(userId);
}

void onLostUser(SimpleOpenNI curContext, int userId)
{
  println("onLostUser - userId: " + userId);
}
void drawRHand( int userID) {
  PVector leftHand = new PVector();
  float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_HAND, leftHand);
  PVector convertedLeftHand = new PVector();
  kinect.convertRealWorldToProjective(leftHand, convertedLeftHand);
  fill(255,0,0);
  float ellipseSizee = map(convertedLeftHand.z, 700, 2500, 50, 1);
 ellipse(convertedLeftHand.x, convertedLeftHand.y, ellipseSizee, ellipseSizee);
}

void drawLHand(int userID) {
  // make a vector to store the left hand
  PVector rightHand = new PVector();
  // put the position of the left hand into that vector
  float confidencee = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_HAND, rightHand);
  // convert the detected hand position to "projective" coordinates that will match the depth image
  PVector convertedRightHand = new PVector();
  kinect.convertRealWorldToProjective(rightHand, convertedRightHand);
  // and display it
  fill(255, 100, 0);

  float ellipseSize = map(convertedRightHand.z, 700, 2500, 50, 1);
 ellipse(convertedRightHand.x, convertedRightHand.y, ellipseSize, ellipseSize);

}

void drawRFoot( int userID) {
  PVector leftFoot = new PVector();
  float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_FOOT, leftFoot);
  PVector convertedLeftFoot = new PVector();
  kinect.convertRealWorldToProjective(leftFoot, convertedLeftFoot);
  fill(255,0,0);
  float ellipseSizeee = map(convertedLeftFoot.z, 700, 2500, 50, 1);
 ellipse(convertedLeftFoot.x, convertedLeftFoot.y, ellipseSizeee, ellipseSizeee);
}

void drawLFoot( int userID) {
  PVector rightFoot = new PVector();
  float confidence = kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_FOOT, rightFoot);
  PVector convertedRightFoot = new PVector();
  kinect.convertRealWorldToProjective(rightFoot, convertedRightFoot);
  fill(255,0,0);
  float ellipseSizeee = map(convertedRightFoot.z, 700, 2500, 50, 1);
 ellipse(convertedRightFoot.x, convertedRightFoot.y, ellipseSizeee, ellipseSizeee);
}


// prints out the distance between any two joints 
float getJointDistance(int userId, int joint1Id, PVector v)
{
  float d = 0;   // to store final distance value

  // two PVectors to hold the position of two joints
  PVector joint1 = new PVector();

  // get 3D position of both joints
  kinect.getJointPositionSkeleton(userId, joint1Id, joint1);

  d = distance3D(joint1, v);    // calculate the distance between the two joints

  return d;
}


// calculate the distance between any two points in 3D space and return it as a float
float distance3D(PVector point1, PVector point2)
{
  float diff_x, diff_y, diff_z;    // to store differences along x, y and z axes
  float distance;                  // to store final distance value

    // calculate the difference between the two points
  diff_x = point1.x - point2.x;
  diff_y = point1.y - point2.y;
  diff_z = point1.z - point2.z;

  // calculate the Euclidean distance between the two points
  distance = sqrt(pow(diff_x, 2)+pow(diff_y, 2)+pow(diff_z, 2)); 

  return distance;  // return the distance as a float
}

12305899_10207651128934703_521450298_n 12319470_10207651129054706_588445544_n

Answers

  • have you try using a regular webcam rather then the kinect ?

  • edited December 2015 Answer ✓

    I've tried using dist() but it doesn't seem to work

    if you want to see whether a point is within a rectangle then it's just a case of

    // pseudocode
    if (point.x >= box.left && point.x <= box.right
        && point.y >= box.bottom && point.y <= box.top) {
        // point is within the box
    }
    

    you know the positions and sizes of the boxes and you know the positions of the foot / hand...

  • button1 = loadImage("button1.jpg");

    DON'T load images within draw(). draw executes 60 times a second. do it in setup().

Sign In or Register to comment.