00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#ifndef lint
00016
static char rcsid[] =
"$Header: /software/source/libraries/bicpl/Geometry/geodesic_distance.c,v 1.7 2002/11/27 22:48:11 stever Exp $";
00017
#endif
00018
00019
#include <volume_io/internal_volume_io.h>
00020
#include <bicpl/geom.h>
00021
#include <bicpl/priority_queue.h>
00022
00023
00030 public int compute_distances_from_point(
00031
polygons_struct *polygons,
00032
int n_neighbours[],
00033
int *neighbours[],
00034 Point *point,
00035
int poly,
00036 Real max_distance,
00037 BOOLEAN distances_initialized,
00038
float distances[],
00039
int *list[] )
00040 {
00041
int i, p, size, point_index, next_point_index, neigh;
00042
int n_found;
00043 Real dist;
00044
float next_dist;
00045
PRIORITY_QUEUE_STRUCT(
int ) queue;
00046
00047
if( poly == -1 )
00048 {
00049
if( !
lookup_polygon_vertex( polygons, point, &point_index ) ||
00050 !
find_polygon_with_vertex( polygons, point_index, &poly, &p ) )
00051 {
00052 print_error(
"compute_distances_from_point incorrect arguments.\n");
00053
return( 0 );
00054 }
00055 }
00056
00057 n_found = 0;
00058
00059
if( !distances_initialized )
00060 {
00061 for_less( i, 0, polygons->
n_points )
00062 distances[i] = -1.0f;
00063 }
00064
00065
INITIALIZE_PRIORITY_QUEUE( queue );
00066
00067 size =
GET_OBJECT_SIZE( *polygons, poly );
00068
00069 for_less( p, 0, size )
00070 {
00071 point_index = polygons->
indices[
00072
POINT_INDEX( polygons->
end_indices, poly, p )];
00073
00074 dist =
distance_between_points(
00075 &polygons->
points[point_index], point );
00076
00077
if( max_distance <= 0.0 || dist < max_distance )
00078 {
00079
if( list != NULL )
00080 {
00081 ADD_ELEMENT_TO_ARRAY( *list, n_found, point_index,
00082 DEFAULT_CHUNK_SIZE );
00083 }
00084
else
00085 ++n_found;
00086
00087 distances[point_index] = (
float) dist;
00088
INSERT_IN_PRIORITY_QUEUE( queue, point_index, -dist );
00089 }
00090 }
00091
00092
while( !
IS_PRIORITY_QUEUE_EMPTY( queue ) )
00093 {
00094
REMOVE_FROM_PRIORITY_QUEUE( queue, point_index, dist );
00095
00096
if( max_distance > 0.0 && (Real) distances[point_index] > max_distance )
00097
break;
00098
00099 for_less( neigh, 0, n_neighbours[point_index] )
00100 {
00101 next_point_index = neighbours[point_index][neigh];
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
if( distances[next_point_index] < 0.0f ||
00114 distances[next_point_index] > distances[point_index] )
00115 {
00116 dist = (Real) distances[point_index] +
00117
distance_between_points(
00118 &polygons->
points[point_index],
00119 &polygons->
points[next_point_index] );
00120
00121 next_dist = distances[next_point_index];
00122
00123
if( (max_distance < 0.0 || dist <= max_distance) &&
00124 (next_dist < 0.0f || (
float) dist < next_dist) )
00125 {
00126
if( next_dist < 0.0f )
00127 {
00128
if( list != NULL )
00129 {
00130 ADD_ELEMENT_TO_ARRAY( *list, n_found,
00131 next_point_index,
00132 DEFAULT_CHUNK_SIZE );
00133 }
00134
else
00135 ++n_found;
00136 }
00137
00138 distances[next_point_index] = (
float) dist;
00139
INSERT_IN_PRIORITY_QUEUE( queue, next_point_index, -dist );
00140 }
00141 }
00142 }
00143 }
00144
00145
DELETE_PRIORITY_QUEUE( queue );
00146
00147
return( n_found );
00148 }