00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include <volume_io/internal_volume_io.h>
00016
#include <bicpl/data_structures.h>
00017
#include <bicpl/geom.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Data_structures/point_bintree.c,v 1.9 2000/02/06 15:30:11 stever Exp $";
00021
#endif
00022
00023
private void recursive_find_closest_point(
00024 Point *point,
00025
bintree_node_struct *node,
00026
range_struct *range,
00027
object_struct *object,
00028
int *obj_index,
00029 Real *closest_dist,
00030 Point *closest_point );
00031
private Real
get_point_range_dist(
00032 Point *point,
00033
range_struct *range );
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 public Real
find_closest_point_in_bintree(
00053 Point *point,
00054
bintree_struct_ptr bintree,
00055
object_struct *object,
00056
int *obj_index,
00057 Point *point_on_object )
00058 {
00059 Real dist;
00060
00061 dist = 1.0e60;
00062
00063
if( obj_index != (
int *) NULL )
00064 *obj_index = -1;
00065
00066
recursive_find_closest_point( point, bintree->
root, &bintree->
range,
00067 object, obj_index, &dist, point_on_object );
00068
00069
return( sqrt( dist ) );
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 private void recursive_find_closest_point(
00091 Point *point,
00092
bintree_node_struct *node,
00093
range_struct *range,
00094
object_struct *object,
00095
int *obj_index,
00096 Real *closest_dist,
00097 Point *closest_point )
00098 {
00099
int i, n_objects, *object_list, axis_index;
00100
int n_to_search;
00101
bintree_node_struct *children[2], *tmp_node;
00102
range_struct children_ranges[2], tmp_range;
00103 Real children_distances[2];
00104 Real dist;
00105 Point object_point;
00106 Real left_limit, right_limit;
00107
00108
if(
bintree_node_is_leaf( node ) )
00109 {
00110 n_objects =
get_bintree_leaf_objects( node, &object_list );
00111
00112 for_less( i, 0, n_objects )
00113 {
00114 dist =
get_point_object_distance_sq( point, object, object_list[i],
00115 &object_point );
00116
00117
if( dist < *closest_dist )
00118 {
00119 *closest_dist = dist;
00120 *closest_point = object_point;
00121 *obj_index = object_list[i];
00122 }
00123 }
00124 }
00125
else
00126 {
00127 axis_index =
get_node_split_axis( node );
00128
00129 n_to_search = 0;
00130
00131
if(
get_bintree_left_child( node, &children[n_to_search] ) )
00132 {
00133 left_limit =
get_node_split_position( children[n_to_search] );
00134 children_ranges[n_to_search] = *range;
00135 children_ranges[n_to_search].
limits[axis_index][1] =
00136 (
float) left_limit;
00137 children_distances[n_to_search] =
get_point_range_dist( point,
00138 &children_ranges[n_to_search] );
00139
00140
if( children_distances[n_to_search] <= *closest_dist )
00141 ++n_to_search;
00142 }
00143
00144
if(
get_bintree_right_child( node, &children[n_to_search] ) )
00145 {
00146 right_limit =
get_node_split_position( children[n_to_search] );
00147 children_ranges[n_to_search] = *range;
00148 children_ranges[n_to_search].
limits[axis_index][0] =
00149 (
float) right_limit;
00150 children_distances[n_to_search] =
get_point_range_dist( point,
00151 &children_ranges[n_to_search] );
00152
00153
if( children_distances[n_to_search] <= *closest_dist )
00154 ++n_to_search;
00155 }
00156
00157
if( n_to_search == 2 && children_distances[1] < children_distances[0] )
00158 {
00159 tmp_range = children_ranges[0];
00160 children_ranges[0] = children_ranges[1];
00161 children_ranges[1] = tmp_range;
00162 tmp_node = children[0];
00163 children[0] = children[1];
00164 children[1] = tmp_node;
00165 }
00166
00167 for_less( i, 0, n_to_search )
00168 {
00169
recursive_find_closest_point( point, children[i],
00170 &children_ranges[i],
00171 object, obj_index,
00172 closest_dist, closest_point );
00173 }
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 private Real
get_point_range_dist(
00192 Point *point,
00193
range_struct *range )
00194 {
00195
int c;
00196 Real min_plane, max_plane, point_pos, dist, sum;
00197
00198 sum = 0.0;
00199
00200 for_less( c, 0, N_DIMENSIONS )
00201 {
00202 min_plane = (Real) range->
limits[c][0];
00203 max_plane = (Real) range->
limits[c][1];
00204 point_pos = (Real) Point_coord(*point,c);
00205
00206
if( point_pos < min_plane )
00207 dist = min_plane - point_pos;
00208
else if( point_pos > max_plane )
00209 dist = point_pos - max_plane;
00210
else
00211 dist = 0.0;
00212
00213 sum += dist * dist;
00214 }
00215
00216
return( sum );
00217 }
00218
00219
private void recursive_find_closest_vertex(
00220 Point *point,
00221
bintree_node_struct *node,
00222
range_struct *range,
00223
object_struct *object,
00224 Real *closest_dist,
00225
int *closest_vertex );
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 public Real
find_closest_vertex_in_bintree(
00244 Point *point,
00245
bintree_struct_ptr bintree,
00246
object_struct *object,
00247
int *vertex_on_object )
00248 {
00249 Real dist;
00250
00251 dist = 1.0e30;
00252
00253
recursive_find_closest_vertex( point, bintree->
root, &bintree->
range,
00254 object, &dist, vertex_on_object );
00255
00256
return( dist );
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 private void recursive_find_closest_vertex(
00277 Point *point,
00278
bintree_node_struct *node,
00279
range_struct *range,
00280
object_struct *object,
00281 Real *closest_dist,
00282
int *closest_vertex )
00283 {
00284
int i, n_objects, *object_list, axis_index;
00285
int n_to_search;
00286
bintree_node_struct *children[2], *tmp_node;
00287
range_struct children_ranges[2], tmp_range;
00288 Real children_distances[2];
00289 Real dist;
00290
int object_vertex;
00291 Real left_limit, right_limit;
00292
00293
if(
bintree_node_is_leaf( node ) )
00294 {
00295 n_objects =
get_bintree_leaf_objects( node, &object_list );
00296
00297 for_less( i, 0, n_objects )
00298 {
00299 dist =
get_point_object_vertex_distance( point, object,
00300 object_list[i], &object_vertex );
00301
00302
if( dist < *closest_dist )
00303 {
00304 *closest_dist = dist;
00305 *closest_vertex = object_vertex;
00306 }
00307 }
00308 }
00309
else
00310 {
00311 axis_index =
get_node_split_axis( node );
00312
00313 n_to_search = 0;
00314
00315
if(
get_bintree_left_child( node, &children[n_to_search] ) )
00316 {
00317 left_limit =
get_node_split_position( children[n_to_search] );
00318 children_ranges[n_to_search] = *range;
00319 children_ranges[n_to_search].
limits[axis_index][1] =
00320 (
float) left_limit;
00321 children_distances[n_to_search] =
get_point_range_dist( point,
00322 &children_ranges[n_to_search] );
00323
00324
if( children_distances[n_to_search] <=
00325 *closest_dist * *closest_dist )
00326 ++n_to_search;
00327 }
00328
00329
if(
get_bintree_right_child( node, &children[n_to_search] ) )
00330 {
00331 right_limit =
get_node_split_position( children[n_to_search] );
00332 children_ranges[n_to_search] = *range;
00333 children_ranges[n_to_search].
limits[axis_index][0] =
00334 (
float) right_limit;
00335 children_distances[n_to_search] =
get_point_range_dist( point,
00336 &children_ranges[n_to_search] );
00337
00338
if( children_distances[n_to_search] <=
00339 *closest_dist * *closest_dist )
00340 ++n_to_search;
00341 }
00342
00343
if( n_to_search == 2 && children_distances[1] < children_distances[0] )
00344 {
00345 tmp_range = children_ranges[0];
00346 children_ranges[0] = children_ranges[1];
00347 children_ranges[1] = tmp_range;
00348 tmp_node = children[0];
00349 children[0] = children[1];
00350 children[1] = tmp_node;
00351 }
00352
00353 for_less( i, 0, n_to_search )
00354 {
00355
recursive_find_closest_vertex( point, children[i],
00356 &children_ranges[i],
00357 object,
00358 closest_dist, closest_vertex );
00359 }
00360 }
00361 }