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

smooth_curvature.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- 00002 @COPYRIGHT : 00003 Copyright 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/geom.h> 00017 #include <bicpl/data_structures.h> 00018 00019 #ifndef lint 00020 static char rcsid[] = "$Header: /software/source/libraries/bicpl/Geometry/smooth_curvature.c,v 1.15 2002/11/27 22:48:11 stever Exp $"; 00021 #endif 00022 00023 private int get_smoothing_points( 00024 polygons_struct *polygons, 00025 int n_neighbours[], 00026 int *neighbours[], 00027 int n_found, 00028 int list[], 00029 Real smoothing_distance, 00030 float distances[], 00031 Point *smoothing_points[] ); 00032 00033 private Real get_average_curvature( 00034 Point *point, 00035 Vector *normal, 00036 int n_smoothing_points, 00037 Point smoothing_points[] ); 00038 00039 /* ----------------------------- MNI Header ----------------------------------- 00040 @NAME : get_smooth_surface_curvature 00041 @INPUT : polygons 00042 poly 00043 vertex 00044 smoothing_distance 00045 @OUTPUT : 00046 @RETURNS : curvature between -180 and 180 00047 @DESCRIPTION: Computes the smooth surface curvature by finding a set of 00048 points the appropriate distance from the vertex and computing 00049 an average curvature of these points. 00050 @METHOD : 00051 @GLOBALS : 00052 @CALLS : 00053 @CREATED : 1994 David MacDonald 00054 @MODIFIED : 00055 ---------------------------------------------------------------------------- */ 00056 00057 public Real get_smooth_surface_curvature( 00058 polygons_struct *polygons, 00059 int n_neighbours[], 00060 int *neighbours[], 00061 int poly, 00062 int vertex, 00063 BOOLEAN distances_initialized, 00064 float distances[], 00065 Real smoothing_distance ) 00066 { 00067 int n_smoothing_points, point_index, n_found, *list, p; 00068 Point *smoothing_points; 00069 Real curvature; 00070 BOOLEAN alloced_distances; 00071 00072 if( distances == NULL ) 00073 { 00074 alloced_distances = TRUE; 00075 distances_initialized = FALSE; 00076 ALLOC( distances, polygons->n_points ); 00077 } 00078 else 00079 alloced_distances = FALSE; 00080 00081 point_index = polygons->indices[ 00082 POINT_INDEX(polygons->end_indices,poly,vertex)]; 00083 00084 /* If !distances_initialized, this routine sets them all to -1. 00085 Then the mesh distances from point_index are computed, up to 00086 smoothing_distance. However, if distances_initialized is TRUE, 00087 the distances are not reset. It seems to me that distances from 00088 a previous call to get_smooth_surface_curvature() with a different 00089 point may not be properly updated. 00090 */ 00091 n_found = compute_distances_from_point( polygons, n_neighbours, neighbours, 00092 &polygons->points[point_index], poly, 00093 smoothing_distance, 00094 distances_initialized, distances, 00095 &list ); 00096 00097 n_smoothing_points = get_smoothing_points( polygons, 00098 n_neighbours, neighbours, 00099 n_found, list, 00100 smoothing_distance, 00101 distances, &smoothing_points ); 00102 00103 if( alloced_distances ) 00104 FREE( distances ); 00105 else 00106 { 00107 for_less( p, 0, n_found ) 00108 distances[list[p]] = -1.0f; 00109 } 00110 00111 if( n_found > 0 ) 00112 FREE( list ); 00113 00114 if( n_smoothing_points > 0 ) 00115 { 00116 curvature = get_average_curvature( &polygons->points[point_index], 00117 &polygons->normals[point_index], 00118 n_smoothing_points, 00119 smoothing_points ); 00120 } 00121 else 00122 curvature = 0.0; 00123 00124 if( n_smoothing_points > 0 ) 00125 FREE( smoothing_points ); 00126 00127 return( curvature ); 00128 } 00129 00130 /* ----------------------------- MNI Header ----------------------------------- 00131 @NAME : get_smoothing_points 00132 @INPUT : polygons 00133 smoothing_distance 00134 @OUTPUT : distances 00135 smoothing_points 00136 @RETURNS : 00137 @DESCRIPTION: 00138 @METHOD : 00139 @GLOBALS : 00140 @CALLS : 00141 @CREATED : 1994 David MacDonald 00142 @MODIFIED : 00143 ---------------------------------------------------------------------------- */ 00144 00145 private int get_smoothing_points( 00146 polygons_struct *polygons, 00147 int n_neighbours[], 00148 int *neighbours[], 00149 int n_found, 00150 int list[], 00151 Real smoothing_distance, 00152 float distances[], 00153 Point *smoothing_points[] ) 00154 { 00155 int p, neigh, point_index, prev_index, inside, outside; 00156 int n_smoothing_points; 00157 Real dist, ratio; 00158 Point point; 00159 00160 n_smoothing_points = 0; 00161 00162 for_less( p, 0, n_found ) 00163 { 00164 point_index = list[p]; 00165 00166 if( distances[point_index] < 0.0f ) 00167 handle_internal_error( "get_smoothing_points" ); 00168 00169 for_less( neigh, 0, n_neighbours[point_index] ) 00170 { 00171 prev_index = neighbours[point_index][neigh]; 00172 00173 /* This seems to indicate that the distances are expected to 00174 be initialized to -1 in compute_distance_from_point(). 00175 */ 00176 if( distances[prev_index] < 0.0f ) 00177 { 00178 inside = point_index; 00179 outside = prev_index; 00180 00181 dist = (Real) distances[inside] + 00182 distance_between_points( 00183 &polygons->points[inside], 00184 &polygons->points[outside] ); 00185 00186 if( dist != (Real) distances[inside] ) 00187 { 00188 ratio = (smoothing_distance - (Real) distances[inside]) / 00189 (dist - (Real) distances[inside]); 00190 INTERPOLATE_POINTS( point, 00191 polygons->points[inside], 00192 polygons->points[outside], 00193 ratio ); 00194 ADD_ELEMENT_TO_ARRAY( *smoothing_points, n_smoothing_points, 00195 point, DEFAULT_CHUNK_SIZE ); 00196 } 00197 } 00198 } 00199 } 00200 00201 return( n_smoothing_points ); 00202 } 00203 00204 /* ----------------------------- MNI Header ----------------------------------- 00205 @NAME : get_average_curvature 00206 @INPUT : point 00207 n_smoothing_points 00208 smoothing_points 00209 @OUTPUT : 00210 @RETURNS : angle 00211 @DESCRIPTION: Gets average angle computed from centroid of points, point, 00212 and each of the smoothing points. 00213 @METHOD : 00214 @GLOBALS : 00215 @CALLS : 00216 @CREATED : 1994 David MacDonald 00217 @MODIFIED : 00218 ---------------------------------------------------------------------------- */ 00219 00220 private Real get_average_curvature( 00221 Point *point, 00222 Vector *normal, 00223 int n_smoothing_points, 00224 Point smoothing_points[] ) 00225 { 00226 int i; 00227 Real sum_curvature, curvature, angle, sign_curvature; 00228 Point centroid; 00229 Vector offset; 00230 00231 get_points_centroid( n_smoothing_points, smoothing_points, &centroid ); 00232 00233 SUB_POINTS( offset, *point, centroid ); 00234 if( DOT_VECTORS( offset, *normal ) < 0.0 ) 00235 sign_curvature = -1.0; 00236 else 00237 sign_curvature = 1.0; 00238 00239 sum_curvature = 0.0; 00240 for_less( i, 0, n_smoothing_points ) 00241 { 00242 angle = RAD_TO_DEG * get_angle_between_points( &smoothing_points[i], 00243 point, &centroid ); 00244 00245 curvature = 180.0 - 2.0 * angle; 00246 sum_curvature += curvature; 00247 } 00248 00249 curvature = sum_curvature * sign_curvature / (Real) n_smoothing_points; 00250 00251 #ifdef DEBUG 00252 { 00253 static BOOLEAN first = TRUE; 00254 Real **tags; 00255 if( first ) 00256 { 00257 first = FALSE; 00258 ALLOC2D( tags, n_smoothing_points+1, 3 ); 00259 tags[0][X] = RPoint_x(*point); 00260 tags[0][Y] = RPoint_y(*point); 00261 tags[0][Z] = RPoint_z(*point); 00262 for_less( i, 0, n_smoothing_points ) 00263 { 00264 tags[i+1][X] = RPoint_x(smoothing_points[i]); 00265 tags[i+1][Y] = RPoint_y(smoothing_points[i]); 00266 tags[i+1][Z] = RPoint_z(smoothing_points[i]); 00267 } 00268 (void) output_tag_file( "smooth_curvature.tag", "", 1, n_smoothing_points+1, 00269 tags, NULL, NULL, NULL, NULL, NULL ); 00270 FREE2D( tags ); 00271 } 00272 } 00273 #endif 00274 00275 return( curvature ); 00276 }

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