working with a tracker class / It creates a new tracker to the top left corner

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

is it possible that you have trackers that have an x/y position of NULL/NULL, and you’re trying to draw them?

NULL generally equals 0, which would explain why it snaps to the top left.

to fix this, you could check for whether x == NULL before drawing the circle.

Right!!!
Now it makes me wonder if it is worth putting it in the tracker0 struct then remove_if… I’ll amend my post when I improve. Thank you.