I have been working with a tracker class and I’m not able to discover why when there is less than 3 fingers on the screen. It creates a new tracker to the top left corner “0”…
I had hoped that the remove_if / energyIsLow or notFountThisFrame would do the trick and fade from the screen completely when there are no touches.
I’ve gone back to look at previous code I’ve used this tracker in and discovered it did the same with a finger finder but didn’t when I used it with blobs centroids.
Is it the way I’m making the class?
Thank you.
http://vimeo.com/33633625
this is testApp.h
#pragma once
#include "ofMain.h"
#include "ofxiPhone.h"
#include "ofxiPhoneExtras.h"
#include "ofxVectorMath.h"
#include "tracker.h"
class testApp : public ofxiPhoneApp {
public:
void setup();
void update();
void draw();
void exit();
void touchDown(int x, int y, int id);
void touchMoved(int x, int y, int id);
void touchUp(int x, int y, int id);
void touchDoubleTap(int x, int y, int id);
void lostFocus();
void gotFocus();
void gotMemoryWarning();
void deviceOrientationChanged(int newOrientation);
//tracker---------_
bool bDeBug;
float touchMoved_x, touchMoved_y;
int touchDownId, touchMovedId, touchId;
tracker touchTracker;
ofPoint touching[10];
//-----tracker----_
};
this is testApp.mm
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
// register touch events
ofxRegisterMultitouch(this);
ofxiPhoneSetOrientation(OFXIPHONE_ORIENTATION_LANDSCAPE_RIGHT);
// initialize the accelerometer
ofxAccelerometer.setup();
//iPhoneAlerts will be sent to this.
ofxiPhoneAlerts.addListener(this);
bDeBug = true;
//tracker---------_
touchTracker.setup();
touchId = touchDownId = touchMovedId = 0;
for(int i=0; i<10; i++){
touching[i].x = touching[i].y = 0;
}
touchMoved_x = touchMoved_y = 0;
//----tracker-----_
}
//--------------------------------------------------------------
void testApp::update() {
ofBackground(80,80,80);
//tracker---------_
touchTracker.update(0.50f, 0.95f);//(float newCatchUpSpeed, float newSetTrackerEnergy)
touchTracker.tracking_XY(touching);
touchTracker.tracking();
//----tracker-----_
}
//--------------------------------------------------------------
void testApp::draw() {
//tracker---------_
touchTracker.draw();
//----tracker-----_
for(int i=0; i<10; i++){
ofDrawBitmapString("id:" + ofToString(i), touching[i].x,touching[i].y-60);
}
}
//--------------------------------------------------------------
void testApp::exit() {
printf("exit()\n");
}
//--------------------------------------------------------------
void testApp::touchDown(int x, int y, int id){
//tracker---------_
touchDownId = 1 + id;
//touchTracker.tracking_Num(touchDownId);
//touchTracker.tracking();
//----tracker-----_
}
//--------------------------------------------------------------
void testApp::touchMoved(int x, int y, int id){
//tracker---------_
touchMovedId = 1 + id;
touchMoved_x = x;
touchMoved_y = y;
for(int i=0; i<10; i++){
touching[id].x = x;
touching[id].y = y;
}
touchTracker.tracking_Num(touchMovedId);
touchTracker.tracking_XY(touching);
touchTracker.tracking();
//----tracker-----_
}
//--------------------------------------------------------------
void testApp::touchUp(int x, int y, int id){
for(int i=0; i<10; i++){
touching[id].x = NULL;
touching[id].y = NULL;
}
}
//--------------------------------------------------------------
void testApp::touchDoubleTap(int x, int y, int id){
//tracker---------_
touchTracker.clear();
//----tracker-----_
}
//--------------------------------------------------------------
void testApp::lostFocus() {
}
//--------------------------------------------------------------
void testApp::gotFocus() {
}
//--------------------------------------------------------------
void testApp::gotMemoryWarning() {
}
//--------------------------------------------------------------
void testApp::deviceOrientationChanged(int newOrientation){
}
this is track
#ifndef _TRACKER_H
#define _TRACKER_H
#include "ofMain.h"
//track-----------------------------
typedef struct {
ofPoint pos;
ofPoint posSmooth;
//float width;
float widthSmooth;
float energy;
int nFramesAlive;
bool bFoundThisFrame;
int whoThisFrame;
int id;
} tracker0;
//---------------track--------------
class tracker{
public:
void setup();
void update(float newCatchUpSpeed, float newSetTrackerEnergy);
void tracking_Num(int newNumToTrack);
void tracking_XY(ofPoint touchingMy[10]);
void tracking();
void draw();
void clear();
int x;
int y;
//int z;
//tracker---------------_
// this will store all trackers...
vector < tracker0 > trackerObjects;
int idCount;
bool bIsAGoodFinger0;
int fTOj_size, myId;
int nBlobsFoundThisFrame, numToTrack;
int trackerObjSize, whoAmI;
float tDistance;
float catchUpSpeed, setTrackerEnergy;
float track_x, track_y;
ofPoint track_xy;
ofPoint testXY[10];
//-------tracker--------_
bool yes;
};
#endif
#include "tracker.h"
//fade out non found blobs
bool energyIsLow(tracker0 t){
return ((t.energy < 0.1) && (t.nFramesAlive > 3));
}
bool notFountThisFrame(tracker0 t){
return !t.bFoundThisFrame;
}
//-----------------------------------------------------------------
void tracker::setup(){
catchUpSpeed = 0.8;
setTrackerEnergy = 0.95f;
}
//-----------------------------------------------------------------
void tracker::update(float newCatchUpSpeed, float newSetTrackerEnergy){
catchUpSpeed = newCatchUpSpeed;
setTrackerEnergy = newSetTrackerEnergy;
}
//-----------------------------------------------------------------
void tracker::tracking_Num(int newNumToTrack){
numToTrack = newNumToTrack;
}
//-----------------------------------------------------------------
void tracker::tracking_XY(ofPoint touchingMy[10]){
for (int k = 0; k < numToTrack; k++){
testXY[k] = touchingMy[k];
}
}
//-----------------------------------------------------------------
void tracker::tracking(){
for (int i = 0; i < trackerObjects.size(); i++){
trackerObjects[i].bFoundThisFrame = false;
}
// b) for all blobs this frame, let's see if we can match them to the trackers.
int nBlobsFoundThisFrame = numToTrack; //was fingerBlobs[k]->nGoodFinger
// assume that none have been found:
bool bAmIFoundThisFrame[nBlobsFoundThisFrame];
if (nBlobsFoundThisFrame > 0){
for (int i = 0; i < nBlobsFoundThisFrame; i++){
bAmIFoundThisFrame[i] = false;
}
// now, look through every tracker, and see how far away they are from this blob.
// find the minimum distance, and see if this is reasonable.
for (int i = 0; i < nBlobsFoundThisFrame; i++){
float minDistance = 100000;
int minIndex = -1;
for (int j = 0; j < trackerObjects.size(); j++){
trackerObjSize = trackerObjects.size();
if (trackerObjects[j].bFoundThisFrame == false){
float dx = trackerObjects[j].pos.x - testXY[i].x;
float dy = trackerObjects[j].pos.y - testXY[i].y;
float distance = sqrt(dx*dx + dy*dy);
if (distance < minDistance){
minDistance = distance;
minIndex = j;
}
}
}
if (minIndex != -1 && minDistance < 30){ // 100 = just a guess.
trackerObjects[minIndex].pos.x = testXY[i].x;
trackerObjects[minIndex].pos.y = testXY[i].y;
trackerObjects[minIndex].posSmooth.x = catchUpSpeed * trackerObjects[minIndex].posSmooth.x +
(1-catchUpSpeed) * trackerObjects[minIndex].pos.x;
trackerObjects[minIndex].posSmooth.y = catchUpSpeed * trackerObjects[minIndex].posSmooth.y +
(1-catchUpSpeed) * trackerObjects[minIndex].pos.y;
trackerObjects[minIndex].energy += 0.1f;
if (trackerObjects[minIndex].energy > 1) trackerObjects[minIndex].energy = 1;
trackerObjects[minIndex].whoThisFrame = i;
trackerObjects[minIndex].bFoundThisFrame = true;
trackerObjects[minIndex].nFramesAlive ++;
bAmIFoundThisFrame[i] = true; // we got one !
}
}
}
// c) for all non found blobs, add a tracker.
if (nBlobsFoundThisFrame > 0){
for (int i = 0; i < nBlobsFoundThisFrame; i++){
if (bAmIFoundThisFrame[i] == false){
tracker0 temp;
temp.energy = 0;
temp.pos = testXY[i];
temp.posSmooth = temp.pos;
temp.nFramesAlive = 0;
temp.whoThisFrame = i;
temp.bFoundThisFrame = true;
temp.id = idCount;
trackerObjects.push_back(temp);
idCount ++;
}
}
}
// d) fade out non found blobs, kill ones that go below a certain value
// remove_if sorts to the end via a boolean value,
// [http://en.wikipedia.org/wiki/Erase-remove-idiom](http://en.wikipedia.org/wiki/Erase-remove-idiom)
for (int i = 0; i < trackerObjects.size(); i++){
if(trackerObjects[i].bFoundThisFrame == false){
trackerObjects[i].nFramesAlive++;
trackerObjects[i].energy *= setTrackerEnergy;
}
}
trackerObjects.erase( remove_if(trackerObjects.begin(), trackerObjects.end(), energyIsLow), trackerObjects.end() );//energyIsLow or notFountThisFrame
}
//-----------------------------------------------------------------
void tracker::draw(){
ofEnableAlphaBlending();
if(trackerObjects.size()>0){
if(trackerObjects.size() > 0){
for(int i = 0; i < trackerObjects.size(); i++){
ofSetColor(242,119,0, trackerObjects[i].energy * 255);
ofLine(trackerObjects[i].posSmooth.x, trackerObjects[i].posSmooth.y, trackerObjects[i].posSmooth.x+15, trackerObjects[i].posSmooth.y-30);
ofEllipse(trackerObjects[i].posSmooth.x,trackerObjects[i].posSmooth.y, 30,30);
ofSetColor(0, 255, 0);
whoAmI = trackerObjects[i].whoThisFrame;
myId = trackerObjects[i].id;
ofDrawBitmapString("id:" + ofToString(myId), trackerObjects[i].posSmooth.x,trackerObjects[i].posSmooth.y-40);
}
}
}
ofDisableAlphaBlending();
}
//-----------------------------------------------------------------
void tracker::clear(){
trackerObjects.clear();
}