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/geom.h>
00017
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Geometry/path_surface.c,v 1.7 2000/02/06 15:30:15 stever Exp $";
00020
#endif
00021
00022
private void follow_path(
00023
int polygon1,
00024
int polygon2,
00025
int end_indices[],
00026
int neighbours[],
00027
int distances[],
00028
int path_length,
00029
int path[] );
00030
00031 #define INVALID_DISTANCE -1
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 public void find_path_between_polygons(
00054
int polygon1,
00055
int polygon2,
00056
int n_polygons,
00057
int end_indices[],
00058 Smallest_int visibilities[],
00059
int neighbours[],
00060 BOOLEAN *path_exists,
00061
int *path_length,
00062
int *path[] )
00063 {
00064 BOOLEAN found_polygon1;
00065
int start_index, end_index, neighbour;
00066
int i, n, *distances, distance, curr_index, prev_index;
00067
int n_step[2], n_step_alloced[2], *step_list[2];
00068
00069 ALLOC( distances, n_polygons );
00070
00071 for_less( i, 0, n_polygons )
00072 distances[i] =
INVALID_DISTANCE;
00073
00074 n_step[0] = 0;
00075 n_step[1] = 0;
00076 n_step_alloced[0] = 0;
00077 n_step_alloced[1] = 0;
00078 prev_index = 0;
00079 curr_index = 1;
00080
00081 ADD_ELEMENT_TO_ARRAY_WITH_SIZE( step_list[curr_index],
00082 n_step_alloced[curr_index], n_step[curr_index],
00083 polygon2, DEFAULT_CHUNK_SIZE );
00084 distances[polygon2] = 0;
00085
00086 distance = 0;
00087
00088 found_polygon1 = (polygon1 == polygon2);
00089
00090
while( !found_polygon1 && n_step[curr_index] > 0 )
00091 {
00092 ++distance;
00093 curr_index = 1 - curr_index;
00094 prev_index = 1 - prev_index;
00095
00096 n_step[curr_index] = 0;
00097
00098 for_less( i, 0, n_step[prev_index] )
00099 {
00100 start_index =
START_INDEX( end_indices,
00101 step_list[prev_index][i] );
00102 end_index = end_indices[step_list[prev_index][i]];
00103
00104 for_less( n, start_index, end_index )
00105 {
00106 neighbour = neighbours[n];
00107
00108
if( neighbour >= 0 &&
00109 (visibilities == (Smallest_int *) 0 ||
00110 visibilities[neighbour]) &&
00111 distances[neighbour] ==
INVALID_DISTANCE )
00112 {
00113
if( neighbour == polygon1 )
00114 {
00115 found_polygon1 =
TRUE;
00116
break;
00117 }
00118
else
00119 {
00120 ADD_ELEMENT_TO_ARRAY_WITH_SIZE( step_list[curr_index],
00121 n_step_alloced[curr_index], n_step[curr_index],
00122 neighbour, DEFAULT_CHUNK_SIZE );
00123 distances[neighbour] = distance;
00124 }
00125 }
00126 }
00127
00128
if( found_polygon1 )
00129
break;
00130 }
00131 }
00132
00133
if( n_step_alloced[0] > 0 )
00134 {
00135 FREE( step_list[0] );
00136 }
00137
00138
if( n_step_alloced[1] > 0 )
00139 {
00140 FREE( step_list[1] );
00141 }
00142
00143
if( found_polygon1 )
00144 {
00145 *path_exists =
TRUE;
00146
00147 *path_length = distance + 1;
00148
00149 ALLOC( *path, *path_length );
00150
00151
follow_path( polygon1, polygon2, end_indices,
00152 neighbours, distances, *path_length, *path );
00153 }
00154
else
00155 {
00156 *path_exists =
FALSE;
00157 }
00158
00159 FREE( distances );
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 private void follow_path(
00182
int polygon1,
00183
int polygon2,
00184
int end_indices[],
00185
int neighbours[],
00186
int distances[],
00187
int path_length,
00188
int path[] )
00189 {
00190
int n, start_index, end_index, path_index, neighbour, current_polygon;
00191
00192 path[0] = polygon1;
00193 path[path_length-1] = polygon2;
00194
00195 current_polygon = polygon1;
00196
00197 for_less( path_index, 1, path_length-1 )
00198 {
00199 start_index =
START_INDEX( end_indices, current_polygon );
00200 end_index = end_indices[current_polygon];
00201
00202 for_less( n, start_index, end_index )
00203 {
00204 neighbour = neighbours[n];
00205
00206
if( neighbour >= 0 &&
00207 distances[neighbour] == path_length - path_index - 1 )
00208 {
00209
break;
00210 }
00211 }
00212
00213
if( n == end_index )
00214 handle_internal_error(
"follow_path" );
00215
00216 current_polygon = neighbour;
00217 path[path_index] = current_polygon;
00218 }
00219 }