0

我目前正在攻读美术学士学位课程,最近我开始尝试通过阅读 Greg Borenstein 的“让事物看到”来学习编程。

我正在开发的作品是试图在观众使用 Kinect 在画廊空间中移动时跟踪多个质心。我希望观众在屏幕上留下足迹,当他们靠近某些区域时,他们的接近度会用一条线或其他东西来说明。我设法找到了一条线索,但只要另一个人出现,他们的观点就会突然联系起来。“接近线”似乎也只适用于当前用户,而不适用于以前的用户。

我想我的问题真的归结为如何隔离每个新用户,以便我可以创建适用于所有用户但不会相互干扰的函数或类..?

这是到目前为止的程序...

import processing.opengl.*;
import SimpleOpenNI.*;
import peasy.*;

PeasyCam cam;
SimpleOpenNI kinect;

ArrayList<PVector> trails;

Hotpoint piece;

PVector currentPosition;
PVector previousPosition;

int pieceX = 0;
int pieceY = 0;
int pieceZ = 2000;
int pieceSize = 500;

void setup() {
  size(1280, 680, OPENGL);
  kinect = new SimpleOpenNI(this);
  kinect.enableDepth();
  kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_NONE);
  kinect.setMirror(true);

  trails = new ArrayList();

  piece = new Hotpoint(pieceX, pieceY, pieceZ, pieceSize);

  cam = new PeasyCam(this, 0, 0, 0, 1000);
}

void draw() {
  background(255);
  kinect.update();
  rotateX(radians(180));

  lights();

  stroke(0);
  strokeWeight(3);

  IntVector userList = new IntVector();
  kinect.getUsers(userList);

  piece.draw();

  for (int i=0; i<userList.size(); i++) {
    int userId = userList.get(i);

    PVector positionCenter = new PVector();
    kinect.getCoM(userId, positionCenter);

    trails.add(positionCenter);

    createTrail();

    piece.check(positionCenter);

    if(piece.check(positionCenter) == true) {
      stroke(255, 0, 0);
      line(positionCenter.x, positionCenter.y, positionCenter.z,
           pieceX, pieceY, pieceZ);
      stroke(0);
    }
  }
}

void createTrail() {
  for (int e=1; e < trails.size(); e++) {
    currentPosition = trails.get(e);
    previousPosition = trails.get(e-1);
    if (currentPosition.z < 1) {
      trails.clear();
    } 
    else {
      stroke(0);
      line(previousPosition.x, previousPosition.y, previousPosition.z, 
      currentPosition.x, currentPosition.y, currentPosition.z);
    }
  }
}

这是热点类部分......

class Hotpoint {
  PVector center;
  color fillColor;
  color strokeColor;
  int size;
  int pointsIncluded;
  int maxPoints;
  boolean wasJustHit;
  int threshold;


  Hotpoint(float centerX, float centerY, float centerZ, int boxSize) {
    center = new PVector(centerX, centerY, centerZ);
    size = boxSize;
    pointsIncluded = 0;
    maxPoints = 1000;
    threshold = 0;

    strokeColor = color(random(255), random(255), random(255));
    fillColor = 0;
  }

  void setThreshold( int newThreshold ){
    threshold = newThreshold;
  }

  void setMaxPoints( int newMaxPoints ){
    maxPoints = newMaxPoints;
  }

  void setColor(float red, float blue, float green){
    fillColor = strokeColor = color(red, blue, green);
  }

  boolean check(PVector point) {
    boolean result = false;

    if (point.x > center.x - size/2 && point.x < center.x + size/2) {
      if (point.y > center.y - size/2 && point.y < center.y + size/2) {
        if (point.z > center.z - size/2 && point.z < center.z + size/2) {
          result = true;
          pointsIncluded++;
        }
      }
    }

    return result;
  }

  void draw() {
    pushMatrix();
      translate(center.x, center.y, center.z);
      shapeMode(LINES);
      noFill();
      stroke(red(strokeColor), blue(strokeColor), green(strokeColor), 255);
      box(size);
    popMatrix();
  }


  float percentIncluded() {
    return map(pointsIncluded, 0, maxPoints, 0, 1);
  }


  boolean currentlyHit() {
    return (pointsIncluded > threshold);
  }


  boolean isHit() {
    return currentlyHit() && !wasJustHit;
  }

  void clear() {
    wasJustHit = currentlyHit();
    pointsIncluded = 0;
  }
}

任何帮助将不胜感激!


编辑:

非常感谢您的时间和您的回答@jesses.co.tt,但我一直无法理解它......例如,userList 上的循环与用户数组不同吗?我担心我一次问不止一件事,所以我把它分解了,首先尝试理解在没有人被链接的情况下绘制多条路径。

import processing.opengl.*;
import SimpleOpenNI.*;
import peasy.*;

SimpleOpenNI kinect;
PeasyCam cam;

ArrayList<PVector> trails1;
ArrayList<PVector> trails2;

PVector currentPosition;
PVector previousPosition;

void setup() {
  size(1280, 800, OPENGL);

  kinect = new SimpleOpenNI(this);
  kinect.enableDepth();
  kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_NONE);
  kinect.setMirror(true);

  trails1 = new ArrayList();
  trails2 = new ArrayList();

  cam = new PeasyCam(this, 0, 0, 0, 1000);
}

void draw() {
  kinect.update();
  rotateX(radians(180));
  background(255);

  IntVector userList = new IntVector();
  kinect.getUsers(userList);

  //println(userList);

  for (int i=0; i<userList.size(); i++) {
    int userId = userList.get(i);
    //println(userId);
    PVector positionCenter = new PVector();
    kinect.getCoM(userId, positionCenter);

    stroke(0);
    strokeWeight(10);
    point(positionCenter.x, positionCenter.y, positionCenter.z);

    if (userId == 1) {

      trails1.add(positionCenter);
      createTrail1();
    } 
    else if (userId == 2) {
      trails2.add(positionCenter);
      createTrail2();
    }
  }
}

void createTrail1() {
  for (int e=1; e < trails1.size(); e++) {
    currentPosition = trails1.get(e);
    previousPosition = trails1.get(e-1);
    if (currentPosition.z < 1) { // [possibly x or y or all?]
      trails1.clear();
    } 
    else {
      // if (currentPosition.x != 0 || previousPosition.x != 0) { // [not working]
      stroke(0);
      line(previousPosition.x, previousPosition.y, previousPosition.z, 
      currentPosition.x, currentPosition.y, currentPosition.z);
      //trails.clear();
    }
  }
}

void createTrail2() {
  for (int e=1; e < trails2.size(); e++) {
    currentPosition = trails2.get(e);
    previousPosition = trails2.get(e-1);
    if (currentPosition.z < 1) { // [possibly x or y or all?]
      trails2.clear();
    } 
    else {
      // if (currentPosition.x != 0 || previousPosition.x != 0) { // [not working]
      stroke(0);
      line(previousPosition.x, previousPosition.y, previousPosition.z, 
      currentPosition.x, currentPosition.y, currentPosition.z);
      //trails.clear();
    }
  }
}

所以,这适用于两个人,我可以编写一个非常长的程序来为有限数量的人工作,但我真正想要的是它是动态的......它在哪里'if(userId = = 1) {',我希望它对每个人都有效,然后在路径部分,需要有一个新的路径数组,以便每次看到一个新人时我都会使用 'void onNewUser(int userId) {' 什么的..?

4

1 回答 1

0

据我所知,您需要制作一个可调整大小的用户列表(SimpleOpenNI 已经提供给您)并为您找到的每个新用户创建一个 HotPoint 类的新实例(或为每个消失的用户删除它)...

您快到了,因为您正在正确地遍历已知用户列表...

您需要添加一个根据找到的用户数量调整大小的 HotPoints ArrayList...然后在找到新用户时创建一个新的 point 实例。你现在拥有它的方式,你只有一个实例,所以如果有两个用户,它将连接他们 - 这就是你所看到的。

确保根据需要从 ArrayList 中删除项目!

你真的很接近...... ;-)

所以...

// Global Variables
ArrayList users;

然后,在你的用户循环中......

// Add a new HotPoint if we have more users than Points
if(i > users.size()) {
  users.add(new HotPoint(...));
}
// Delete From ArrayList if we have too many... 
else if(users.size() > userList.size()) {
  users.remove(...);
} 

// Cast and call methods
HotPoint piece = (HotPoint) users.get(i);
piece.check(positionCenter);
piece.draw();
etc...
于 2013-04-24T15:14:53.647 回答