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

intersect.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/intersect.c,v 1.12 2000/02/06 15:30:14 stever Exp $"; 00020 #endif 00021 00022 /* ----------------------------- MNI Header ----------------------------------- 00023 @NAME : line_segment_intersects_plane 00024 @INPUT : p1 00025 p2 00026 plane_origin 00027 plane_normal 00028 @OUTPUT : intersection_point 00029 @RETURNS : TRUE if line segment intersects plane 00030 @DESCRIPTION: Tests if a line segment from p1 to p2 intersects the plane, 00031 passing back the intersection point, if so. 00032 @METHOD : 00033 @GLOBALS : 00034 @CALLS : 00035 @CREATED : 1993 David MacDonald 00036 @MODIFIED : Jul 12, 1995 David MacDonald - rewrote to be clearer. 00037 ---------------------------------------------------------------------------- */ 00038 00039 public BOOLEAN line_segment_intersects_plane( 00040 Point *p1, 00041 Point *p2, 00042 Point *plane_origin, 00043 Vector *plane_normal, 00044 Point *intersection_point ) 00045 { 00046 Real t, t1, t2; 00047 Vector v1, v2; 00048 00049 SUB_POINTS( v1, *p1, *plane_origin ); 00050 SUB_POINTS( v2, *p2, *plane_origin ); 00051 00052 t1 = DOT_VECTORS( v1, *plane_normal ); 00053 t2 = DOT_VECTORS( v2, *plane_normal ); 00054 00055 if( t1 == t2 ) 00056 return( FALSE ); 00057 00058 if( t1 == 0.0 ) 00059 *intersection_point = *p1; 00060 else if( t2 == 0.0 ) 00061 *intersection_point = *p2; 00062 else 00063 { 00064 t = t1 / (t1 - t2); 00065 00066 if( t < 0.0 || t > 1.0 ) 00067 return( FALSE ); 00068 00069 INTERPOLATE_POINTS( *intersection_point, *p1, *p2, t ); 00070 } 00071 00072 return( TRUE ); 00073 } 00074 00075 /* ----------------------------- MNI Header ----------------------------------- 00076 @NAME : get_nearest_point_on_lines 00077 @INPUT : origin1 00078 delta1 00079 origin2 00080 delta2 00081 @OUTPUT : nearest_pt 00082 @RETURNS : TRUE if near point found 00083 @DESCRIPTION: Finds the nearest point on the first line to the second line, 00084 or returns FALSE if they are parallel. If it can, passes back 00085 the intersection point. 00086 @METHOD : 00087 @GLOBALS : 00088 @CALLS : 00089 @CREATED : 1993 David MacDonald 00090 @MODIFIED : 00091 ---------------------------------------------------------------------------- */ 00092 00093 public BOOLEAN get_nearest_point_on_lines( 00094 Point *origin1, 00095 Vector *delta1, 00096 Point *origin2, 00097 Vector *delta2, 00098 Point *nearest_point ) 00099 { 00100 BOOLEAN intersects; 00101 Real t, bottom; 00102 Real d11, d12, d22; 00103 Real o11, o12, o21, o22; 00104 00105 d11 = DOT_VECTORS( *delta1, *delta1 ); 00106 d12 = DOT_VECTORS( *delta1, *delta2 ); 00107 d22 = DOT_VECTORS( *delta2, *delta2 ); 00108 00109 bottom = d11 * d22 - d12 * d12; 00110 00111 intersects = (bottom != 0.0); 00112 00113 if( intersects ) 00114 { 00115 o11 = DOT_POINT_VECTOR( *origin1, *delta1 ); 00116 o12 = DOT_POINT_VECTOR( *origin1, *delta2 ); 00117 o21 = DOT_POINT_VECTOR( *origin2, *delta1 ); 00118 o22 = DOT_POINT_VECTOR( *origin2, *delta2 ); 00119 00120 t = -(d22 * (o11 - o21) + d12 * (o22 - o12)) / bottom; 00121 00122 GET_POINT_ON_RAY( *nearest_point, *origin1, *delta1, t ); 00123 } 00124 00125 return( intersects ); 00126 } 00127 00128 /* ----------------------------- MNI Header ----------------------------------- 00129 @NAME : clip_line_to_box 00130 @INPUT : origin 00131 direction 00132 x_min 00133 x_max 00134 y_min 00135 y_max 00136 z_min 00137 z_max 00138 @OUTPUT : t_min 00139 t_max 00140 @RETURNS : TRUE if line intersects box 00141 @DESCRIPTION: Determines if the line intersects the box, and if so, passes 00142 back the min and max multiple of direction vector for the box 00143 intersection. 00144 @METHOD : 00145 @GLOBALS : 00146 @CALLS : 00147 @CREATED : 1993 David MacDonald 00148 @MODIFIED : 00149 ---------------------------------------------------------------------------- */ 00150 00151 public BOOLEAN clip_line_to_box( 00152 Point *origin, 00153 Vector *direction, 00154 Real x_min, 00155 Real x_max, 00156 Real y_min, 00157 Real y_max, 00158 Real z_min, 00159 Real z_max, 00160 Real *t_min, 00161 Real *t_max ) 00162 { 00163 BOOLEAN first; 00164 Real dir, org, t1, t2, min_t, max_t; 00165 00166 *t_min = 0.0; 00167 *t_max = -1.0; 00168 00169 dir = (Real) Vector_x( *direction ); 00170 org = (Real) Point_x( *origin ); 00171 00172 if( dir == 0.0 ) 00173 { 00174 if( org < x_min || org > x_max ) 00175 return( FALSE ); 00176 00177 dir = (Real) Vector_y( *direction ); 00178 org = (Real) Point_y( *origin ); 00179 00180 if( dir < 0.0 ) 00181 { 00182 first = FALSE; 00183 min_t = (y_max - org) / dir; 00184 max_t = (y_min - org) / dir; 00185 } 00186 else if( dir > 0.0 ) 00187 { 00188 first = FALSE; 00189 min_t = (y_min - org) / dir; 00190 max_t = (y_max - org) / dir; 00191 } 00192 else 00193 { 00194 if( org < y_min || org > y_max ) 00195 return( FALSE ); 00196 00197 first = TRUE; 00198 } 00199 00200 dir = (Real) Vector_z( *direction ); 00201 org = (Real) Point_z( *origin ); 00202 00203 if( dir < 0.0 ) 00204 { 00205 t1 = (z_max - org) / dir; 00206 t2 = (z_min - org) / dir; 00207 00208 if( first || t1 > min_t ) 00209 min_t = t1; 00210 if( first || t2 < max_t ) 00211 max_t = t2; 00212 first = FALSE; 00213 } 00214 else if( dir > 0.0 ) 00215 { 00216 t1 = (z_min - org) / dir; 00217 t2 = (z_max - org) / dir; 00218 00219 if( first || t1 > min_t ) 00220 min_t = t1; 00221 if( first || t2 < max_t ) 00222 max_t = t2; 00223 first = FALSE; 00224 } 00225 else 00226 { 00227 if( org < z_min || org > z_max ) 00228 return( FALSE ); 00229 } 00230 00231 if( first ) 00232 { 00233 min_t = 0.0; 00234 max_t = 0.0; 00235 } 00236 00237 *t_min = min_t; 00238 *t_max = max_t; 00239 return( min_t <= max_t ); 00240 } 00241 00242 if( dir > 0.0 ) 00243 { 00244 min_t = (x_min - org) / dir; 00245 max_t = (x_max - org) / dir; 00246 } 00247 else 00248 { 00249 min_t = (x_max - org) / dir; 00250 max_t = (x_min - org) / dir; 00251 } 00252 00253 dir = (Real) Vector_y( *direction ); 00254 org = (Real) Point_y( *origin ); 00255 00256 if( dir == 0.0 ) 00257 { 00258 if( org < y_min || org > y_max ) 00259 return( FALSE ); 00260 } 00261 else 00262 { 00263 if( dir > 0.0 ) 00264 { 00265 t1 = (y_min - org) / dir; 00266 t2 = (y_max - org) / dir; 00267 } 00268 else 00269 { 00270 t1 = (y_max - org) / dir; 00271 t2 = (y_min - org) / dir; 00272 } 00273 00274 if( t1 > min_t ) 00275 { 00276 if( t1 > max_t ) 00277 return( FALSE ); 00278 min_t = t1; 00279 } 00280 if( t2 < max_t ) 00281 { 00282 if( t2 < min_t ) 00283 return( FALSE ); 00284 max_t = t2; 00285 } 00286 } 00287 00288 dir = (Real) Vector_z( *direction ); 00289 org = (Real) Point_z( *origin ); 00290 00291 if( dir == 0.0 ) 00292 { 00293 if( org < z_min || org > z_max ) 00294 return( FALSE ); 00295 } 00296 else 00297 { 00298 if( dir > 0.0 ) 00299 { 00300 t1 = (z_min - org) / dir; 00301 t2 = (z_max - org) / dir; 00302 } 00303 else 00304 { 00305 t1 = (z_max - org) / dir; 00306 t2 = (z_min - org) / dir; 00307 } 00308 00309 if( t1 > min_t ) 00310 { 00311 if( t1 > max_t ) 00312 return( FALSE ); 00313 min_t = t1; 00314 } 00315 if( t2 < max_t ) 00316 { 00317 if( t2 < min_t ) 00318 return( FALSE ); 00319 max_t = t2; 00320 } 00321 } 00322 00323 *t_min = min_t; 00324 *t_max = max_t; 00325 00326 return( min_t <= max_t ); 00327 }

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