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

tetrahedrons.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/geom.h> 00017 00018 #ifndef lint 00019 static char rcsid[] = "$Header: /software/source//libraries/bicpl/Geometry/tetrahedrons.c,v 1.14 2002/04/29 18:31:05 stever Exp $"; 00020 #endif 00021 00022 /* ----------------------------- MNI Header ----------------------------------- 00023 @NAME : is_this_tetrahedral_topology 00024 @INPUT : polygons 00025 @OUTPUT : 00026 @RETURNS : TRUE if correct topology 00027 @DESCRIPTION: Tests if the polygons are a tetrahedron (4 polygons), 00028 two tetrahedrons glued together (6 polygons), two pyramids glued 00029 together (8 polygons), an icosahedron (20 polygons), 00030 or a subdivision of one of these. 00031 @METHOD : 00032 @GLOBALS : 00033 @CALLS : 00034 @CREATED : 1993 David MacDonald 00035 @MODIFIED : 00036 ---------------------------------------------------------------------------- */ 00037 00038 public BOOLEAN is_this_tetrahedral_topology( 00039 polygons_struct *polygons ) 00040 { 00041 int n_polygons; 00042 00043 n_polygons = polygons->n_items; 00044 00045 while( n_polygons != 20 && n_polygons > 8 && n_polygons % 4 == 0 ) 00046 n_polygons /= 4; 00047 00048 return( n_polygons == 4 || n_polygons == 6 || n_polygons == 8 || 00049 n_polygons == 20 ); 00050 } 00051 00052 /* ----------------------------- MNI Header ----------------------------------- 00053 @NAME : get_tetra_tessellation_with_n_points 00054 @INPUT : n_points 00055 @OUTPUT : 00056 @RETURNS : tessellation number 00057 @DESCRIPTION: Returns the number of polygons that correspond to a tetrahedral 00058 topology with n_points points. 00059 @METHOD : 00060 @GLOBALS : 00061 @CALLS : 00062 @CREATED : 1993 David MacDonald 00063 @MODIFIED : 00064 ---------------------------------------------------------------------------- */ 00065 00066 public int get_tetra_tessellation_with_n_points( 00067 int n_points ) 00068 { 00069 int n_polygons; 00070 00071 n_polygons = 2 * (n_points - 2); 00072 00073 return( n_polygons ); 00074 } 00075 00076 /* ----------------------------- MNI Header ----------------------------------- 00077 @NAME : create_tetrahedral_sphere 00078 @INPUT : centre 00079 rx 00080 ry 00081 rz 00082 n_triangles 00083 @OUTPUT : polygons 00084 @RETURNS : 00085 @DESCRIPTION: Creates a tetrahedral tessellation of a sphere. This is 00086 either a tetrahedron, two tetrahedrons glued together, 00087 two pyramids glued together, an icosahedron, 00088 or some subdivision of these. 00089 This means that n_triangles must be either 4, 6, 8, 20, or 00090 a power of 4 times one of these, since a subdivision step 00091 quadruples the number of triangles. If it is not, then the 00092 smallest power of 4 larger than n_triangles will be used, 00093 resulting in the subdivision of a tetrahedron. 00094 @METHOD : 00095 @GLOBALS : 00096 @CALLS : 00097 @CREATED : 1993 David MacDonald 00098 @MODIFIED : 00099 ---------------------------------------------------------------------------- */ 00100 00101 public void create_tetrahedral_sphere( 00102 Point *centre, 00103 Real rx, 00104 Real ry, 00105 Real rz, 00106 int n_triangles, 00107 polygons_struct *polygons ) 00108 { 00109 static int possible_sizes[] = { 4, 6, 8, 20 }; 00110 int p, start_size, s, size, best_size, prev_size; 00111 Real cx, cy, cz, dx, dy, dz, scale; 00112 Real x, y, z; 00113 Point origin; 00114 00115 /*--- determine the base object, either 4, 6, or 8, 20 */ 00116 00117 start_size = 4; 00118 best_size = 0; 00119 for_less( s, 0, SIZEOF_STATIC_ARRAY( possible_sizes ) ) 00120 { 00121 size = possible_sizes[s]; 00122 prev_size = size; 00123 while( size < n_triangles ) 00124 { 00125 prev_size = size; 00126 size *= 4; 00127 } 00128 00129 if( ABS( n_triangles - prev_size ) < ABS( n_triangles - best_size ) ) 00130 { 00131 best_size = prev_size; 00132 start_size = possible_sizes[s]; 00133 } 00134 00135 if( ABS( n_triangles - size ) < ABS( n_triangles - best_size ) ) 00136 { 00137 best_size = size; 00138 start_size = possible_sizes[s]; 00139 } 00140 } 00141 00142 fill_Point( origin, 0.0, 0.0, 0.0 ); 00143 00144 if( start_size == 6 ) /* create 2 points at poles and 3 around equator */ 00145 { 00146 create_polygons_sphere( &origin, 1.0, 1.0, 1.0, 2, 3, FALSE, polygons ); 00147 } 00148 else if( start_size == 8 ) /* create 2 points at poles and 4 around equat */ 00149 { 00150 create_polygons_sphere( &origin, 1.0, 1.0, 1.0, 2, 4, FALSE, polygons ); 00151 } 00152 else if( start_size == 20 ) /* create icosahedron */ 00153 { 00154 create_unit_icosahedron( polygons ); 00155 } 00156 else /* create a tetrahedron */ 00157 { 00158 create_unit_tetrahedron( polygons ); 00159 } 00160 00161 cx = (Real) Point_x( *centre ); 00162 cy = (Real) Point_y( *centre ); 00163 cz = (Real) Point_z( *centre ); 00164 00165 for_less( p, 0, polygons->n_points ) 00166 { 00167 x = cx + rx * (Real) Point_x(polygons->points[p]); 00168 y = cy + ry * (Real) Point_y(polygons->points[p]); 00169 z = cz + rz * (Real) Point_z(polygons->points[p]); 00170 fill_Point( polygons->points[p], x, y, z ); 00171 } 00172 00173 /*--- having created the base object, subdivide it until we have the 00174 required number of triangles */ 00175 00176 while( polygons->n_items < n_triangles ) 00177 { 00178 subdivide_polygons( polygons ); 00179 00180 /*--- project the points to the ellipsoid */ 00181 00182 for_less( p, 0, polygons->n_points ) 00183 { 00184 dx = (Real) Point_x(polygons->points[p]) - cx; 00185 dy = (Real) Point_y(polygons->points[p]) - cy; 00186 dz = (Real) Point_z(polygons->points[p]) - cz; 00187 scale = dx * dx / rx / rx + dy * dy / ry / ry + dz * dz / rz / rz; 00188 scale = 1.0 / sqrt( scale ); 00189 dx *= scale; 00190 dy *= scale; 00191 dz *= scale; 00192 fill_Point( polygons->points[p], cx + dx, cy + dy, cz + dz ); 00193 } 00194 } 00195 00196 compute_polygon_normals( polygons ); 00197 } 00198 00199 /* ----------------------------- MNI Header ----------------------------------- 00200 @NAME : half_sample_tetrahedral_tessellation 00201 @INPUT : polygons 00202 @OUTPUT : half 00203 @RETURNS : 00204 @DESCRIPTION: Half samples the tetrahedron tesselation by combining every 00205 set of 4 triangles into 1. 00206 @METHOD : 00207 @GLOBALS : 00208 @CALLS : 00209 @CREATED : 1993 David MacDonald 00210 @MODIFIED : 00211 ---------------------------------------------------------------------------- */ 00212 00213 public void half_sample_tetrahedral_tessellation( 00214 polygons_struct *polygons, 00215 polygons_struct *half ) 00216 { 00217 int i, quarter_n_polygons; 00218 static Point dummy_centre = { 0.0f, 0.0f, 0.0f }; 00219 00220 quarter_n_polygons = polygons->n_items / 4; 00221 00222 create_tetrahedral_sphere( &dummy_centre, 1.0, 1.0, 1.0, 00223 quarter_n_polygons, half ); 00224 00225 for_less( i, 0, half->n_points ) 00226 { 00227 half->points[i] = polygons->points[i]; 00228 half->normals[i] = polygons->normals[i]; 00229 } 00230 00231 if( polygons->colour_flag == PER_VERTEX_COLOURS ) 00232 { 00233 half->colour_flag = PER_VERTEX_COLOURS; 00234 REALLOC( half->colours, half->n_points ); 00235 for_less( i, 0, half->n_points ) 00236 half->colours[i] = polygons->colours[i]; 00237 } 00238 }

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