void NBodyWorldApp::pickParticle( Particle2D*& picked ){
    Particle2D* screenObjects[256];
    // mouse picking
    double rmax  = 2.0d;
    double r2max = rmax*rmax;
    Vec2d vmouse;
    vmouse.set( mouse_begin_x, mouse_begin_y );
    UINT mfound = world.map.getObjectsInRect( (float)(vmouse.x - rmax ), (float)(vmouse.y - rmax ), (float)(vmouse.x + rmax ), (float)(vmouse.y + rmax ), &(screenObjects[0]) );
    //printf( "mfound  %i \n", mfound );
    int imin = -1;
    double r2min = 1e+300;
    for( int i=0; i<mfound; i++ ){
        Particle2D* p = screenObjects[i];
        Vec2d d;
        d.set_sub( p->pos, vmouse );
        double r2 = d.norm2();
        if( r2 < r2max ){
            if( r2 < r2min ){  r2min = r2; imin = i; }
        }
        //printf( " r2 %3.3f r2max %3.3f r2min %3.3f imin %i \n", r2, r2max, r2min, imin );
    }
    if( imin >= 0 ){
        picked = screenObjects[imin];
    }else{
        picked = NULL;
    }
    //if( world.picked != NULL ) printf( " MOUSE picked (%f,%f) \n", world.picked->pos.x, world.picked->pos.y );
}
int MoleculeWorldApp::pickMol( const Vec2d& mpos ){
    int    imin  = -1;
    double r2min = 1e+300;
    for(int i=0; i<world.nMols; i++){
        Vec2d d; d.set_sub( mpos, world.pos[i] );
        double r2 = d.norm2();
        if (r2<r2min){ r2min=r2; imin=i; }
    }
    return imin;
}
TestAppSimplexGrid::TestAppSimplexGrid( int& id, int WIDTH_, int HEIGHT_ ) : AppSDL2OGL( id, WIDTH_, HEIGHT_ ) {

    grid.init( 1.0, 8 );

    shape=glGenLists(1);
	glNewList( shape, GL_COMPILE );

	glBegin   ( GL_POINTS   );
        for( int i=0; i<10000; i++ ){
            double x = randf( -5,5 );
            double y = randf( -5,5 );
            double da,db;
            UHALF   ia,ib;
            //bool s = simplexIndex( x+100, y+100, ia,ib, da, db );
            bool s = grid.simplexIndex( x, y, ia,ib, da, db );
            //printf( " (%3.3f,%3.3f) (%3.3f,%3.3f) (%i,%i) \n", x, y, da, db, ia, ib );
            s = false;
            if( s ){
                glColor3f( da, db, 1-da-db );
            }else{
                //int h = rand_hash( (ia*359) ^ (ib*353)  );
                int h = (ia*920419823) ^ (ib*941083981);
                glColor3f( (h&0x0000FF)/255.0f, (h&0x00FF00)/65535.0f, (h&0xFF0000)/16777216.0f );
            }
            glVertex3f( (float)x,(float)y, 0.0f );
        }
    glEnd();

    glColor3f(0.1f,0.1f,0.1f); Draw2D::drawSimplexGrid( 10, (float)grid.step );

    Vec2d dirHat;
    p1.set(0.9,0.6);
    p2.set(8.2,8.3);
    dirHat.set_sub( p2, p1 ); dirHat.normalize();
    nhits = grid.raster_line( dirHat, p1, p2, hits, boundaries, edges );

	glEndList();

}