00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
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
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
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 }