Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

lines.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 1993,1994,1995 David MacDonald, 00004 McConnell Brain Imaging Centre, 00005 Montreal Neurological Institute, McGill University. 00006 Permission to use, copy, modify, and distribute this 00007 software and its documentation for any purpose and without 00008 fee is hereby granted, provided that the above copyright 00009 notice appear in all copies. The author and McGill University 00010 make no representations about the suitability of this 00011 software for any purpose. It is provided "as is" without 00012 express or implied warranty. 00013 ---------------------------------------------------------------------------- */ 00014 00015 #include <volume_io/internal_volume_io.h> 00016 #include <bicpl/objects.h> 00017 #include <bicpl/geom.h> 00018 00019 #ifndef lint 00020 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Objects/lines.c,v 1.19 2000/02/06 15:30:43 stever Exp $"; 00021 #endif 00022 00023 /* ----------------------------- MNI Header ----------------------------------- 00024 @NAME : initialize_lines 00025 @INPUT : col 00026 @OUTPUT : lines 00027 @RETURNS : 00028 @DESCRIPTION: Initializes the lines to empty. 00029 @METHOD : 00030 @GLOBALS : 00031 @CALLS : 00032 @CREATED : 1993 David MacDonald 00033 @MODIFIED : 00034 ---------------------------------------------------------------------------- */ 00035 00036 public void initialize_lines( 00037 lines_struct *lines, 00038 Colour col ) 00039 { 00040 ALLOC( lines->colours, 1 ); 00041 00042 lines->colour_flag = ONE_COLOUR; 00043 lines->colours[0] = col; 00044 00045 lines->line_thickness = 1.0f; 00046 lines->n_points = 0; 00047 lines->n_items = 0; 00048 00049 lines->bintree = (bintree_struct_ptr) NULL; 00050 } 00051 00052 public void initialize_lines_with_size( 00053 lines_struct *lines, 00054 Colour col, 00055 int size, 00056 BOOLEAN closed ) 00057 { 00058 int i, n_indices; 00059 00060 initialize_lines( lines, col ); 00061 00062 if( closed ) 00063 n_indices = size + 1; 00064 else 00065 n_indices = size; 00066 00067 lines->n_points = size; 00068 ALLOC( lines->points, size ); 00069 00070 lines->n_items = 1; 00071 ALLOC( lines->end_indices, 1 ); 00072 lines->end_indices[0] = n_indices; 00073 00074 ALLOC( lines->indices, n_indices ); 00075 00076 for_less( i, 0, n_indices ) 00077 lines->indices[i] = i % size; 00078 } 00079 00080 00081 /* ----------------------------- MNI Header ----------------------------------- 00082 @NAME : delete_lines 00083 @INPUT : lines 00084 @OUTPUT : 00085 @RETURNS : 00086 @DESCRIPTION: Frees up memory associated with the lines. 00087 @METHOD : 00088 @GLOBALS : 00089 @CALLS : 00090 @CREATED : 1993 David MacDonald 00091 @MODIFIED : 00092 ---------------------------------------------------------------------------- */ 00093 00094 public void delete_lines( lines_struct *lines ) 00095 { 00096 free_colours( lines->colour_flag, lines->colours, lines->n_points, 00097 lines->n_items ); 00098 00099 if( lines->n_points > 0 ) 00100 FREE( lines->points ); 00101 00102 if( lines->n_items > 0 ) 00103 FREE( lines->end_indices ); 00104 00105 if( lines->n_items > 0 ) 00106 FREE( lines->indices ); 00107 00108 delete_bintree_if_any( &lines->bintree ); 00109 } 00110 00111 /* ----------------------------- MNI Header ----------------------------------- 00112 @NAME : start_new_line 00113 @INPUT : lines 00114 @OUTPUT : 00115 @RETURNS : 00116 @DESCRIPTION: Creates a new line in the structure of size 0, in preparation 00117 for adding points to the line. 00118 @METHOD : 00119 @GLOBALS : 00120 @CALLS : 00121 @CREATED : 1993 David MacDonald 00122 @MODIFIED : 00123 ---------------------------------------------------------------------------- */ 00124 00125 public void start_new_line( lines_struct *lines ) 00126 { 00127 int n_indices; 00128 00129 n_indices = NUMBER_INDICES( *lines ); 00130 00131 ADD_ELEMENT_TO_ARRAY( lines->end_indices, lines->n_items, 00132 n_indices, DEFAULT_CHUNK_SIZE ); 00133 } 00134 00135 /* ----------------------------- MNI Header ----------------------------------- 00136 @NAME : add_point_to_line 00137 @INPUT : lines 00138 point 00139 @OUTPUT : 00140 @RETURNS : 00141 @DESCRIPTION: Adds a point to the line. 00142 @METHOD : 00143 @GLOBALS : 00144 @CALLS : 00145 @CREATED : 1993 David MacDonald 00146 @MODIFIED : 00147 ---------------------------------------------------------------------------- */ 00148 00149 public void add_point_to_line( 00150 lines_struct *lines, 00151 Point *point ) 00152 { 00153 if( lines->n_items == 0 ) 00154 start_new_line( lines ); 00155 00156 ADD_ELEMENT_TO_ARRAY( lines->indices, lines->end_indices[lines->n_items-1], 00157 lines->n_points, DEFAULT_CHUNK_SIZE ); 00158 00159 ADD_ELEMENT_TO_ARRAY( lines->points, lines->n_points, 00160 *point, DEFAULT_CHUNK_SIZE ); 00161 } 00162 00163 /* ----------------------------- MNI Header ----------------------------------- 00164 @NAME : get_line_segment_index 00165 @INPUT : lines 00166 obj_index 00167 @OUTPUT : line 00168 seg 00169 @RETURNS : 00170 @DESCRIPTION: Converts an obj_index to a line index, and a line segment 00171 index. 00172 @METHOD : 00173 @GLOBALS : 00174 @CALLS : 00175 @CREATED : 1993 David MacDonald 00176 @MODIFIED : 00177 ---------------------------------------------------------------------------- */ 00178 00179 public void get_line_segment_index( 00180 lines_struct *lines, 00181 int obj_index, 00182 int *line, 00183 int *seg ) 00184 { 00185 int first, last, mid, n_objs; 00186 00187 first = 0; 00188 last = lines->n_items-1; 00189 00190 while( first < last ) 00191 { 00192 mid = (first + last) / 2; 00193 00194 n_objs = lines->end_indices[mid] - mid - 1; 00195 if( obj_index < n_objs ) 00196 last = mid; 00197 else 00198 first = mid+1; 00199 } 00200 00201 *line = first; 00202 00203 if( first == 0 ) 00204 *seg = obj_index; 00205 else 00206 *seg = obj_index - (lines->end_indices[first-1] - first); 00207 } 00208 00209 static void (*bintree_delete_function) ( bintree_struct_ptr* ) = NULL; 00210 00211 /* ----------------------------- MNI Header ----------------------------------- 00212 @NAME : set_bintree_delete_function 00213 @INPUT : func 00214 @OUTPUT : 00215 @RETURNS : 00216 @DESCRIPTION: Sets the bintree delete function for objects. This is done 00217 so that if the application does not use any bintree code, the 00218 bintree library does not get linked into the executable, simply 00219 because the delete objects code might have to delete a bintree. 00220 @METHOD : 00221 @GLOBALS : 00222 @CALLS : 00223 @CREATED : 1993 David MacDonald 00224 @MODIFIED : 00225 ---------------------------------------------------------------------------- */ 00226 00227 public void set_bintree_delete_function( 00228 void (*func)( bintree_struct_ptr * ) ) 00229 { 00230 bintree_delete_function = func; 00231 } 00232 00233 /* ----------------------------- MNI Header ----------------------------------- 00234 @NAME : delete_bintree_if_any 00235 @INPUT : bintree 00236 @OUTPUT : 00237 @RETURNS : 00238 @DESCRIPTION: Deletes the bintree, if non-null. 00239 @METHOD : 00240 @GLOBALS : 00241 @CALLS : 00242 @CREATED : 1993 David MacDonald 00243 @MODIFIED : 00244 ---------------------------------------------------------------------------- */ 00245 00246 public void delete_bintree_if_any( 00247 bintree_struct_ptr *bintree ) 00248 { 00249 if( bintree_delete_function != NULL ) 00250 (*bintree_delete_function) ( bintree ); 00251 } 00252 00253 /* ----------------------------- MNI Header ----------------------------------- 00254 @NAME : get_lines_length 00255 @INPUT : lines 00256 @OUTPUT : 00257 @RETURNS : length 00258 @DESCRIPTION: Gets the total length of the lines. 00259 @METHOD : 00260 @GLOBALS : 00261 @CALLS : 00262 @CREATED : 1993 David MacDonald 00263 @MODIFIED : 00264 ---------------------------------------------------------------------------- */ 00265 00266 public Real get_lines_length( 00267 lines_struct *lines ) 00268 { 00269 Real len; 00270 int line, i, p0, p1, size; 00271 00272 len = 0.0; 00273 00274 for_less( line, 0, lines->n_items ) 00275 { 00276 size = GET_OBJECT_SIZE( *lines, line ); 00277 00278 for_less( i, 0, size-1 ) 00279 { 00280 p0 = lines->indices[POINT_INDEX(lines->end_indices,line,i)]; 00281 p1 = lines->indices[POINT_INDEX(lines->end_indices,line,i+1)]; 00282 len += distance_between_points( &lines->points[p0], 00283 &lines->points[p1] ); 00284 } 00285 } 00286 00287 return( len ); 00288 } 00289 00290 /* ----------------------------- MNI Header ----------------------------------- 00291 @NAME : 00292 @INPUT : 00293 @OUTPUT : 00294 @RETURNS : 00295 @DESCRIPTION: 00296 @METHOD : 00297 @GLOBALS : 00298 @CALLS : 00299 @CREATED : Jul. 16, 1997 David MacDonald 00300 @MODIFIED : 00301 ---------------------------------------------------------------------------- */ 00302 00303 public void get_lines_arc_point( 00304 lines_struct *lines, 00305 Real arc_length, 00306 Point *point ) 00307 { 00308 Real len, segment_length, ratio; 00309 int line, i, p0, p1, size; 00310 BOOLEAN found; 00311 00312 if( arc_length < 0.0 ) 00313 { 00314 print_error( "get_lines_arc_point: arc_length < 0.0, using 0.0\n" ); 00315 arc_length = 0.0; 00316 } 00317 00318 len = 0.0; 00319 found = FALSE; 00320 00321 for_less( line, 0, lines->n_items ) 00322 { 00323 size = GET_OBJECT_SIZE( *lines, line ); 00324 00325 for_less( i, 0, size-1 ) 00326 { 00327 p0 = lines->indices[POINT_INDEX(lines->end_indices,line,i)]; 00328 p1 = lines->indices[POINT_INDEX(lines->end_indices,line,i+1)]; 00329 segment_length = distance_between_points( &lines->points[p0], 00330 &lines->points[p1] ); 00331 len += segment_length; 00332 00333 if( len > arc_length ) 00334 { 00335 found = TRUE; 00336 break; 00337 } 00338 } 00339 00340 if( found ) 00341 break; 00342 } 00343 00344 if( !found ) 00345 { 00346 print_error( "get_lines_arc_point: arc_length too large, using end\n" ); 00347 *point = lines->points[p1]; 00348 return; 00349 } 00350 00351 ratio = (len - arc_length) / segment_length; 00352 INTERPOLATE_POINTS( *point, lines->points[p1], lines->points[p0], ratio ); 00353 }

Generated on Wed Jul 28 09:10:57 2004 for BICPL by doxygen 1.3.7