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

geometry.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/geometry.c,v 1.20 2000/02/06 15:30:14 stever Exp $"; 00020 #endif 00021 00022 /* ----------------------------- MNI Header ----------------------------------- 00023 @NAME : find_polygon_normal_no_normalize 00024 @INPUT : n_points 00025 points 00026 @OUTPUT : normal 00027 @RETURNS : 00028 @DESCRIPTION: Finds the normal to a polygon (convex or not), using Newell's 00029 formula. 00030 @METHOD : 00031 @GLOBALS : 00032 @CALLS : 00033 @CREATED : 1993 David MacDonald 00034 @MODIFIED : 00035 ---------------------------------------------------------------------------- */ 00036 00037 public void find_polygon_normal_no_normalize( 00038 int n_points, 00039 Point points[], 00040 Real *nx, 00041 Real *ny, 00042 Real *nz ) 00043 { 00044 int i, next_i; 00045 Vector v1, v2, normal; 00046 Real vx, vy, vz, x, y, z, tx, ty, tz, x0, x1, x2, y0, y1, y2, z0, z1, z2; 00047 00048 if( n_points == 3 ) 00049 { 00050 x0 = (Real) Point_x(points[0]); 00051 y0 = (Real) Point_y(points[0]); 00052 z0 = (Real) Point_z(points[0]); 00053 x1 = (Real) Point_x(points[1]) - x0; 00054 y1 = (Real) Point_y(points[1]) - y0; 00055 z1 = (Real) Point_z(points[1]) - z0; 00056 x2 = (Real) Point_x(points[2]) - x0; 00057 y2 = (Real) Point_y(points[2]) - y0; 00058 z2 = (Real) Point_z(points[2]) - z0; 00059 *nx = y1 * z2 - z1 * y2; 00060 *ny = z1 * x2 - x1 * z2; 00061 *nz = x1 * y2 - y1 * x2; 00062 return; 00063 } 00064 00065 vx = 0.0; 00066 vy = 0.0; 00067 vz = 0.0; 00068 00069 tx = (Real) Point_x(points[0]); 00070 ty = (Real) Point_y(points[0]); 00071 tz = (Real) Point_z(points[0]); 00072 00073 for_less( i, 0, n_points ) 00074 { 00075 next_i = (i + 1) % n_points; 00076 00077 x = tx; 00078 y = ty; 00079 z = tz; 00080 tx = (Real) Point_x(points[next_i]); 00081 ty = (Real) Point_y(points[next_i]); 00082 tz = (Real) Point_z(points[next_i]); 00083 00084 vx -= (y + ty) * (z - tz); 00085 vy -= (z + tz) * (x - tx); 00086 vz -= (x + tx) * (y - ty); 00087 } 00088 00089 /*--- if result is null, try to find one vertex for which a normal can 00090 be computed */ 00091 00092 if( vx == 0.0 && vy == 0.0 && vz == 0.0 ) 00093 { 00094 for_less( i, 0, n_points ) 00095 { 00096 SUB_POINTS( v1, points[(i+1)%n_points], points[i] ); 00097 SUB_POINTS( v2, points[(i-1)%n_points], points[i] ); 00098 CROSS_VECTORS( normal, v1, v2 ); 00099 if( !null_Vector( &normal ) ) 00100 { 00101 vx = (Real) Vector_x( normal ); 00102 vy = (Real) Vector_y( normal ); 00103 vz = (Real) Vector_z( normal ); 00104 break; 00105 } 00106 } 00107 } 00108 00109 *nx = vx; 00110 *ny = vy; 00111 *nz = vz; 00112 } 00113 00114 /* ----------------------------- MNI Header ----------------------------------- 00115 @NAME : find_polygon_normal 00116 @INPUT : n_points 00117 points 00118 @OUTPUT : normal 00119 @RETURNS : 00120 @DESCRIPTION: Finds the normal to a polygon (convex or not), using Newell's 00121 formula, then normalizing the result to unit length. 00122 @METHOD : 00123 @GLOBALS : 00124 @CALLS : 00125 @CREATED : 1993 David MacDonald 00126 @MODIFIED : 00127 ---------------------------------------------------------------------------- */ 00128 00129 public void find_polygon_normal( 00130 int n_points, 00131 Point points[], 00132 Vector *normal ) 00133 { 00134 Real nx, ny, nz; 00135 00136 find_polygon_normal_no_normalize( n_points, points, &nx, &ny, &nz ); 00137 00138 fill_Vector( *normal, nx, ny, nz ); 00139 00140 NORMALIZE_VECTOR( *normal, *normal ); 00141 } 00142 00143 /* ----------------------------- MNI Header ----------------------------------- 00144 @NAME : get_plane_through_points 00145 @INPUT : n_points 00146 points 00147 @OUTPUT : normal 00148 plane_constant 00149 @RETURNS : 00150 @DESCRIPTION: Computes the plane through the 3D points. Rather than compute 00151 the polygon normal, which is dependent on the ordering of 00152 points, it should do a linear least squares fit of the points. 00153 @METHOD : 00154 @GLOBALS : 00155 @CALLS : 00156 @CREATED : 1993 David MacDonald 00157 @MODIFIED : 00158 ---------------------------------------------------------------------------- */ 00159 00160 public void get_plane_through_points( 00161 int n_points, 00162 Point points[], 00163 Vector *normal, 00164 Real *plane_constant ) 00165 { 00166 Point centroid; 00167 00168 find_polygon_normal( n_points, points, normal ); 00169 00170 get_points_centroid( n_points, points, &centroid ); 00171 00172 *plane_constant = - distance_from_plane( &centroid, normal, 0.0 ); 00173 } 00174 00175 /* ----------------------------- MNI Header ----------------------------------- 00176 @NAME : distance_from_plane 00177 @INPUT : point 00178 plane_normal 00179 plane_constant 00180 @OUTPUT : 00181 @RETURNS : Distance 00182 @DESCRIPTION: Returns the distance of a point from a plane. 00183 @METHOD : 00184 @GLOBALS : 00185 @CALLS : 00186 @CREATED : 1993 David MacDonald 00187 @MODIFIED : 00188 ---------------------------------------------------------------------------- */ 00189 00190 public Real distance_from_plane( 00191 Point *point, 00192 Vector *plane_normal, 00193 Real plane_constant ) 00194 { 00195 return( DOT_POINT_VECTOR( *point, *plane_normal ) + plane_constant ); 00196 } 00197 00198 /* ----------------------------- MNI Header ----------------------------------- 00199 @NAME : distance_from_line 00200 @INPUT : point 00201 end_point1 00202 end_point2 00203 @OUTPUT : 00204 @RETURNS : Distance 00205 @DESCRIPTION: Returns the distance from the point to the line. 00206 @METHOD : 00207 @GLOBALS : 00208 @CALLS : 00209 @CREATED : 1993 David MacDonald 00210 @MODIFIED : 00211 ---------------------------------------------------------------------------- */ 00212 00213 public Real distance_from_line( 00214 Point *point, 00215 Point *end_point1, 00216 Point *end_point2 ) 00217 { 00218 Vector d, v; 00219 Real dist, len, v_dot_d, v_dot_v; 00220 00221 SUB_POINTS( d, *end_point2, *end_point1 ); 00222 00223 len = DOT_VECTORS( d, d ); 00224 if( len == 0.0 ) 00225 { 00226 dist = distance_between_points( point, end_point1 ); 00227 } 00228 else 00229 { 00230 SUB_POINTS( v, *point, *end_point1 ); 00231 00232 v_dot_d = DOT_VECTORS( v, d ); 00233 v_dot_v = DOT_VECTORS( v, v ); 00234 00235 dist = v_dot_v - v_dot_d * v_dot_d / len; 00236 dist = sqrt( dist ); 00237 } 00238 00239 return( dist ); 00240 }

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