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

scan_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.h> 00017 00018 #ifndef lint 00019 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Volumes/scan_lines.c,v 1.9 2000/02/05 21:27:28 stever Exp $"; 00020 #endif 00021 00022 private void scan_line_segment_to_voxels( 00023 Volume volume, 00024 Volume label_volume, 00025 int label, 00026 Point *p1, 00027 Point *p2, 00028 Real radius ); 00029 00030 /* ----------------------------- MNI Header ----------------------------------- 00031 @NAME : scan_lines_to_voxels 00032 @INPUT : lines 00033 volume 00034 label_volume 00035 label 00036 @OUTPUT : 00037 @RETURNS : 00038 @DESCRIPTION: Fills in the label_volume with label, where the line 00039 intersects it. 00040 @METHOD : 00041 @GLOBALS : 00042 @CALLS : 00043 @CREATED : 1993 David MacDonald 00044 @MODIFIED : 00045 ---------------------------------------------------------------------------- */ 00046 00047 public void scan_lines_to_voxels( 00048 lines_struct *lines, 00049 Volume volume, 00050 Volume label_volume, 00051 int label ) 00052 { 00053 int i, line, size; 00054 Point p1, p2; 00055 00056 for_less( line, 0, lines->n_items ) 00057 { 00058 size = GET_OBJECT_SIZE( *lines, line ); 00059 00060 for_less( i, 0, size-1 ) 00061 { 00062 p1 = lines->points[ 00063 lines->indices[POINT_INDEX(lines->end_indices,line,i)]]; 00064 p2 = lines->points[ 00065 lines->indices[POINT_INDEX(lines->end_indices,line,i+1)]]; 00066 00067 scan_line_segment_to_voxels( volume, label_volume, label, 00068 &p1, &p2, 00069 (Real) lines->line_thickness ); 00070 } 00071 } 00072 } 00073 00074 /* ----------------------------- MNI Header ----------------------------------- 00075 @NAME : 00076 @INPUT : 00077 @OUTPUT : 00078 @RETURNS : 00079 @DESCRIPTION: 00080 @METHOD : 00081 @GLOBALS : 00082 @CALLS : 00083 @CREATED : 1993 David MacDonald 00084 @MODIFIED : 00085 ---------------------------------------------------------------------------- */ 00086 00087 private Real point_segment_distance_squared( 00088 Point *point, 00089 Point *p1, 00090 Point *p2 ) 00091 { 00092 Vector offset; 00093 Point closest; 00094 00095 get_closest_point_on_line_segment( point, p1, p2, &closest ); 00096 00097 SUB_POINTS( offset, *point, closest ); 00098 00099 return( DOT_VECTORS( offset, offset ) ); 00100 } 00101 00102 /* ----------------------------- MNI Header ----------------------------------- 00103 @NAME : scan_line_segment_to_voxels 00104 @INPUT : volume 00105 label_volume 00106 label 00107 p1 00108 p2 00109 radius 00110 @OUTPUT : 00111 @RETURNS : 00112 @DESCRIPTION: Scans a cylinder with spheres on both ends into the volume. 00113 @METHOD : 00114 @GLOBALS : 00115 @CALLS : 00116 @CREATED : 1993 David MacDonald 00117 @MODIFIED : 00118 ---------------------------------------------------------------------------- */ 00119 00120 private void scan_line_segment_to_voxels( 00121 Volume volume, 00122 Volume label_volume, 00123 int label, 00124 Point *p1, 00125 Point *p2, 00126 Real radius ) 00127 { 00128 int c, sizes[MAX_DIMENSIONS]; 00129 Point min_point, max_point; 00130 Real min_voxel[MAX_DIMENSIONS], min_v, max_v; 00131 Real max_voxel[MAX_DIMENSIONS]; 00132 Real voxel[MAX_DIMENSIONS]; 00133 Real x_world, y_world, z_world; 00134 int int_voxel[MAX_DIMENSIONS]; 00135 int int_min_voxel[MAX_DIMENSIONS]; 00136 int int_max_voxel[MAX_DIMENSIONS]; 00137 int tx, ty, tz, dim; 00138 Point world_voxel; 00139 00140 for_less( c, 0, N_DIMENSIONS ) 00141 { 00142 Point_coord(min_point,c) = (Point_coord_type) 00143 ((Real) MIN(Point_coord(*p1,c),Point_coord(*p2,c)) - radius); 00144 Point_coord(max_point,c) = (Point_coord_type) 00145 ((Real) MAX(Point_coord(*p1,c),Point_coord(*p2,c)) + radius); 00146 } 00147 00148 get_volume_sizes( volume, sizes ); 00149 00150 for_less( tx, 0, 2 ) 00151 for_less( ty, 0, 2 ) 00152 for_less( tz, 0, 2 ) 00153 { 00154 convert_world_to_voxel( volume, 00155 (tx == 0) ? RPoint_x(min_point) : 00156 RPoint_x(max_point), 00157 (ty == 0) ? RPoint_y(min_point) : 00158 RPoint_y(max_point), 00159 (tz == 0) ? RPoint_z(min_point) : 00160 RPoint_z(max_point), 00161 voxel ); 00162 00163 for_less( dim, 0, N_DIMENSIONS ) 00164 { 00165 if( tx == 0 && ty == 0 && tz == 0 ) 00166 { 00167 min_voxel[dim] = voxel[dim]; 00168 max_voxel[dim] = voxel[dim]; 00169 } 00170 else if( voxel[dim] < min_voxel[dim] ) 00171 min_voxel[dim] = voxel[dim]; 00172 else if( voxel[dim] > max_voxel[dim] ) 00173 max_voxel[dim] = voxel[dim]; 00174 } 00175 } 00176 00177 for_less( c, 0, N_DIMENSIONS ) 00178 { 00179 min_v = MIN( min_voxel[c], max_voxel[c] ); 00180 max_v = MAX( min_voxel[c], max_voxel[c] ); 00181 00182 int_min_voxel[c] = ROUND( min_v ); 00183 int_max_voxel[c] = ROUND( max_v ); 00184 00185 if( int_min_voxel[c] < 0 ) 00186 int_min_voxel[c] = 0; 00187 if( int_max_voxel[c] > sizes[c]-1 ) 00188 int_max_voxel[c] = sizes[c]-1; 00189 } 00190 00191 for_inclusive( int_voxel[X], int_min_voxel[X], int_max_voxel[X] ) 00192 for_inclusive( int_voxel[Y], int_min_voxel[Y], int_max_voxel[Y] ) 00193 for_inclusive( int_voxel[Z], int_min_voxel[Z], int_max_voxel[Z] ) 00194 { 00195 convert_3D_voxel_to_world( volume, (Real) int_voxel[X], 00196 (Real) int_voxel[Y], (Real) int_voxel[Z], 00197 &x_world, &y_world, &z_world ); 00198 00199 fill_Point( world_voxel, x_world, y_world, z_world ); 00200 00201 if( point_segment_distance_squared( &world_voxel, p1, p2 ) < 00202 radius * radius ) 00203 { 00204 set_volume_label_data( label_volume, int_voxel, label ); 00205 } 00206 } 00207 }

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