2013-04-23 6 views
0

В настоящее время я нахожусь на курсе BA в области изобразительного искусства, и недавно я начал изучать программирование, прочитав «Делающие вещи» Грега Боренштейна.Kinect. Как я могу работать с несколькими центрами масс без их влияния друг на друга в функциях?

Часть, которую я разрабатываю, является попыткой отслеживать множество центров масс, когда зрители перемещаются по галерее с помощью 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); 
    } 
    } 
} 

И это класс Hotpoint часть ...

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; 
    } 
} 

Любая помощь будет оценена очень!


EDIT:

Спасибо вам большое за ваше время и ответ @ 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) {', я бы хотел, чтобы это работало для всех, а затем в части трейла, должен быть новый массив трейлов, чтобы каждый раз, когда новый человек вошел в view Я бы использовал 'void onNewUser (int userId) {' или что-то ...?

+0

К сожалению, я забыл включить класс Hotpoint, так что это было отредактировано сейчас! – basicallyright

ответ

0

Насколько я могу судить, вам необходимо создать список пользователей, который уже предоставлен вам SimpleOpenNI, и создать новый экземпляр вашего класса HotPoint для каждого нового пользователя (или удалить его для каждый пользователь, который исчезает) ...

вы почти там, как вы правильно перебор по списку известных пользователей ...

вы должны добавить ArrayList из HotPoints, который изменяет размер в соответствии с количество найденных пользователей ... затем создайте новый экземпляр точки, когда будет найден новый пользователь. То, как вы это делаете прямо сейчас, у вас только один экземпляр, так что, если есть два пользователя, он будет их подключать - вот что вы видите.

Обязательно удалите элементы из массива 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... 
+0

в принципе - это работает для вас? –

+0

Большое спасибо за ваш ответ @ jesses.co.tt Это определенно обнадеживает, хотя мне все еще сложно понять все это. Я отредактировал вопрос, надеюсь, сломать свои проблемы еще немного ... Было бы так здорово, если бы вы могли помочь! – basicallyright