Question

I've successfully written code that takes the (x,y) position of one of my fingers measured by my Leap Motion controller (infrared scanning device that tracks finger and hand movements), and draws a point with similar (x,y) coordinates using OpenGL. Basically, you move your finger, you move the point displayed on the screen.

What I'd like to do now is display the last 100 locations recorded - so, instead of seeing a single point move around, you see a serpentine collection of points that snakes around and follows the movement of your fingertip.

I tried to do this using two vectors - one to hold the x and y position during a given frame, and one to hold a bunch of the previously mentioned vectors. By popping off the first element in the vector after its size goes beyond 100, I figured I could loop through all those points and draw them within my display method.

It compiles fine, but after drawing a few points, I get a runtime error saying "vector iterator not incrementable." Not sure how to deal with that.

Code:

#include <iostream>
#include <fstream>
#include "Leap.h"
#include <math.h>
#include "GL/glut.h"
#include <deque>

using namespace Leap;
using namespace std;

bool one = true;

double x = 10, y = 100;
double screenWidth = 480, screenHeight = 480;
double time, timeDisplayed = 5.0 * (pow(10.0, 9.0));

vector < double > entry, *temp;
vector < vector< double > > collection;

class SampleListener : public Listener {
  public:
      int firstFrame, firstTime;
      bool first;
    virtual void onInit(const Controller&);
    virtual void onConnect(const Controller&);
    virtual void onExit(const Controller&);
    virtual void onFrame(const Controller&);
};

void SampleListener::onInit(const Controller& controller){
    cout << "Initialized.\n";
    first = true;
}

void SampleListener::onConnect(const Controller& controller){
    cout << "Connected.\n";
    controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
}

void SampleListener::onExit(const Controller& controller){
    cout << "Exited.\n";
}

void SampleListener::onFrame(const Controller& controller) {
    const Frame frame = controller.frame();

    //some initial frame processing/file writing
    if (first){
        first = !first;
        firstFrame = frame.id();
        firstTime = frame.timestamp();
    }
    else {

    //record hand information
        if (!frame.hands().isEmpty()){
            const Hand hand = frame.hands().frontmost();
            const Finger track = hand.fingers().frontmost();
            x = track.tipPosition().x;
            y = track.tipPosition().y;
            time = frame.timestamp() - firstTime;
            entry.push_back(x);
            entry.push_back(y);
            entry.push_back(time);
            collection.push_back(entry);
            entry.clear();
            while (collection.size() > 100 && !collection.empty()){
                collection.erase(collection.begin());
            }
        }
    }

}

// Create a sample listener and controller
SampleListener listener;
Controller controller;

void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_POINTS);
    for (auto i = collection.begin(); i != collection.end(); *i++){
    cout << collection.size() << endl;
        glVertex2f(i->at(0), i->at(1));
    }

    glEnd();

    glFlush();
    glutSwapBuffers();
}

void init(){
    cout << "in init" << endl;
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glColor3f(1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-screenWidth/2, screenWidth/2, 0, screenHeight);
    glViewport(0, 0, screenWidth, screenHeight);
    glPointSize(3.0f);
    cout << "leaving init" << endl;

}


void idle(void){
    glutPostRedisplay();
}

//<<<<<<<<<<<<<<<<<<<<<<< myKeys >>>>>>>>>>>>>>>>>>>>>>>>
void myKeys(unsigned char key, int x, int y)
{

    switch(key)  
    {
        case 'q':   // Quit
        // Remove the sample listener when done
        controller.removeListener(listener);

            exit(0);
    }
}

int main (int argc, char** argv) {

    listener.first = true;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(800, 100);
    glutCreateWindow("test");
    init();
    glutDisplayFunc(display);
    glutKeyboardFunc(myKeys);
    glutIdleFunc(idle);

    controller.addListener(listener);

    glutMainLoop();


  return 0;

}
Était-ce utile?

La solution

If this is threaded, then your collection.erase() in SampleListener::onFrame() would invalidate the iterator in display(). You need a mutex there. Heck, the push_back() could invalidate your iterator. Seems like you want a fixed-length structure with head/tail pointers rather than this dynamic vector.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top