struct kdres *kd_nearest_rangef(struct kdtree *kd, const float *pos, float range) { static double sbuf[16]; double *bptr, *buf = 0; int dim = kd->dim; struct kdres *res; if(dim > 16) { #ifndef NO_ALLOCA if(dim <= 256) bptr = buf = alloca(dim * sizeof *bptr); else #endif if(!(bptr = buf = malloc(dim * sizeof *bptr))) { return 0; } } else { bptr = buf = sbuf; } while(dim-- > 0) { *bptr++ = *pos++; } res = kd_nearest_range(kd, buf, range); #ifndef NO_ALLOCA if(kd->dim > 256) #else if(kd->dim > 16) #endif free(buf); return res; }
struct kdres *kd_nearest_range2(struct kdtree *tree, double x, double y, double range) { double pos[2]; pos[0] = x; pos[1] = y; return kd_nearest_range(tree, pos, range); }
/** * vu_get_tz_at_location: * * @vc: Position for which the time zone is desired * * Returns: TimeZone string of the nearest known location. String may be NULL. * * Use the k-d tree method (http://en.wikipedia.org/wiki/Kd-tree) to quickly retreive * the nearest location to the given position. */ gchar* vu_get_tz_at_location ( const VikCoord* vc ) { gchar *tz = NULL; if ( !vc || !kd ) return tz; struct LatLon ll; vik_coord_to_latlon ( vc, &ll ); double pt[2] = { ll.lat, ll.lon }; gdouble nearest; if ( !a_settings_get_double(VIK_SETTINGS_NEAREST_TZ_FACTOR, &nearest) ) nearest = 1.0; struct kdres *presults = kd_nearest_range ( kd, pt, nearest ); while( !kd_res_end( presults ) ) { double pos[2]; gchar *ans = (gchar*)kd_res_item ( presults, pos ); // compute the distance of the current result from the pt double dist = sqrt( dist_sq( pt, pos, 2 ) ); if ( dist < nearest ) { //printf( "NEARER node at (%.3f, %.3f, %.3f) is %.3f away is %s\n", pos[0], pos[1], pos[2], dist, ans ); nearest = dist; tz = ans; } kd_res_next ( presults ); } g_debug ( "TZ lookup found %d results - picked %s", kd_res_size(presults), tz ); kd_res_free ( presults ); return tz; }
struct kdres *kd_nearest_range3f(struct kdtree *tree, float x, float y, float z, float range) { double buf[3]; buf[0] = x; buf[1] = y; buf[2] = z; return kd_nearest_range(tree, buf, range); }
struct kdres *kd_nearest_range3(struct kdtree *tree, double x, double y, double z, double range) { double buf[3]; buf[0] = x; buf[1] = y; buf[2] = z; return kd_nearest_range(tree, buf, range); }
int main(int argc, char **argv) { int i, num_pts = DEF_NUM_PTS; void *ptree; char *data, *pch; struct kdres *presults; double pos[3], dist; double pt[3] = { 0, 0, 1 }; double radius = 10; if(argc > 1 && isdigit(argv[1][0])) { num_pts = atoi(argv[1]); } if(!(data = malloc(num_pts))) { perror("malloc failed"); return 1; } srand( time(0) ); /* create a k-d tree for 3-dimensional points */ ptree = kd_create( 3 ); /* add some random nodes to the tree (assert nodes are successfully inserted) */ for( i=0; i<num_pts; i++ ) { data[i] = 'a' + i; assert( 0 == kd_insert3( ptree, rd(), rd(), rd(), &data[i] ) ); } /* find points closest to the origin and within distance radius */ presults = kd_nearest_range( ptree, pt, radius ); /* print out all the points found in results */ printf( "found %d results:\n", kd_res_size(presults) ); while( !kd_res_end( presults ) ) { /* get the data and position of the current result item */ pch = (char*)kd_res_item( presults, pos ); /* compute the distance of the current result from the pt */ dist = sqrt( dist_sq( pt, pos, 3 ) ); /* print out the retrieved data */ printf( "node at (%.3f, %.3f, %.3f) is %.3f away and has data=%c\n", pos[0], pos[1], pos[2], dist, *pch ); /* go to the next entry */ kd_res_next( presults ); } /* free our tree, results set, and other allocated memory */ free( data ); kd_res_free( presults ); kd_free( ptree ); return 0; }
// Finds the set of nodes with max cost GSList *opttree_find_nodes_in_ball (opttree_t *self, state_t *state, double ball_radius) { GSList *nodes_in_ball = NULL; kdres_t *kdres = kd_nearest_range (self->kdtree, optsystem_get_state_key (self->optsys, state), ball_radius); nodes_in_ball = opttree_kdtree_to_gslist (state, kdres); kd_res_free (kdres); return nodes_in_ball; }