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

plane_polygon_intersect.c

Go to the documentation of this file.
00001 #include <volume_io/internal_volume_io.h> 00002 #include <bicpl/geom.h> 00003 00004 private void coalesce_lines( 00005 lines_struct *lines ) 00006 { 00007 int p, n, l, *n_neighbours, **neighbours, total_neighbours; 00008 int size, p1, p2, n_items, n_indices, *indices, *end_indices, edge; 00009 00010 if( lines->n_points <= 0 || 00011 lines->n_items <= 0 ) 00012 { 00013 return; 00014 } 00015 00016 ALLOC( n_neighbours, lines->n_points ); 00017 00018 for_less( p, 0, lines->n_points ) 00019 n_neighbours[p] = 0; 00020 00021 for_less( l, 0, lines->n_items ) 00022 { 00023 size = GET_OBJECT_SIZE( *lines, l ); 00024 00025 for_less( edge, 0, size-1 ) 00026 { 00027 p1 = lines->indices[POINT_INDEX(lines->end_indices,l,edge)]; 00028 p2 = lines->indices[POINT_INDEX(lines->end_indices,l,edge+1)]; 00029 00030 ++n_neighbours[p1]; 00031 ++n_neighbours[p2]; 00032 } 00033 } 00034 00035 total_neighbours = 0; 00036 for_less( p, 0, lines->n_points ) 00037 { 00038 if( n_neighbours[p] != 0 && n_neighbours[p] != 2 ) 00039 { 00040 return; 00041 } 00042 total_neighbours += n_neighbours[p]; 00043 } 00044 00045 ALLOC( neighbours, lines->n_points ); 00046 ALLOC( neighbours[0], total_neighbours ); 00047 for_less( p, 1, lines->n_points ) 00048 { 00049 neighbours[p] = &neighbours[p-1][n_neighbours[p-1]]; 00050 } 00051 00052 for_less( p, 0, lines->n_points ) 00053 n_neighbours[p] = 0; 00054 00055 for_less( l, 0, lines->n_items ) 00056 { 00057 size = GET_OBJECT_SIZE( *lines, l ); 00058 00059 for_less( edge, 0, size-1 ) 00060 { 00061 p1 = lines->indices[POINT_INDEX(lines->end_indices,l,edge)]; 00062 p2 = lines->indices[POINT_INDEX(lines->end_indices,l,edge+1)]; 00063 00064 neighbours[p1][n_neighbours[p1]] = p2; 00065 ++n_neighbours[p1]; 00066 neighbours[p2][n_neighbours[p2]] = p1; 00067 ++n_neighbours[p2]; 00068 } 00069 } 00070 00071 n_items = 0; 00072 end_indices = NULL; 00073 n_indices = 0; 00074 indices = NULL; 00075 00076 for_less( l, 0, lines->n_items ) 00077 { 00078 size = GET_OBJECT_SIZE( *lines, l ); 00079 00080 for_less( edge, 0, size-1 ) 00081 { 00082 p1 = lines->indices[POINT_INDEX(lines->end_indices,l,edge)]; 00083 p2 = lines->indices[POINT_INDEX(lines->end_indices,l,edge+1)]; 00084 00085 for_less( n, 0, n_neighbours[p1] ) 00086 { 00087 if( neighbours[p1][n] == p2 ) 00088 break; 00089 } 00090 00091 if( n >= n_neighbours[p1] ) 00092 continue; 00093 00094 ADD_ELEMENT_TO_ARRAY( indices, n_indices, p1, DEFAULT_CHUNK_SIZE ); 00095 00096 while( n < n_neighbours[p1] ) 00097 { 00098 ADD_ELEMENT_TO_ARRAY( indices, n_indices, p2, 00099 DEFAULT_CHUNK_SIZE ); 00100 00101 neighbours[p1][n] = -1; 00102 00103 for_less( n, 0, n_neighbours[p2] ) 00104 { 00105 if( neighbours[p2][n] == p1 ) 00106 break; 00107 } 00108 00109 if( n >= n_neighbours[p1] ) 00110 { 00111 handle_internal_error( "coalesce_lines" ); 00112 return; 00113 } 00114 00115 neighbours[p2][n] = -1; 00116 00117 p1 = p2; 00118 00119 for_less( n, 0, n_neighbours[p1] ) 00120 { 00121 if( neighbours[p1][n] >= 0 ) 00122 break; 00123 } 00124 00125 p2 = neighbours[p1][n]; 00126 } 00127 00128 ADD_ELEMENT_TO_ARRAY( end_indices, n_items, n_indices, 00129 DEFAULT_CHUNK_SIZE ); 00130 } 00131 } 00132 00133 FREE( lines->end_indices ); 00134 FREE( lines->indices ); 00135 00136 lines->n_items = n_items; 00137 lines->indices = indices; 00138 lines->end_indices = end_indices; 00139 } 00140 00141 public void intersect_planes_with_polygons( 00142 polygons_struct *polygons, 00143 Point *plane_origin, 00144 Vector *plane_normal, 00145 lines_struct *lines ) 00146 { 00147 int n_points, p, index; 00148 int poly, edge, size; 00149 int point_index1, point_index2; 00150 Vector v1, v2; 00151 Point point; 00152 Real t1, t2, ratios[2]; 00153 int p1s[2], p2s[2]; 00154 hash2_table_struct hash; 00155 00156 initialize_lines( lines, WHITE ); 00157 00158 initialize_hash2_table( &hash, polygons->n_items, (int) sizeof(int), 00159 0.5, .25 ); 00160 00161 index = 0; 00162 00163 for_less( poly, 0, polygons->n_items ) 00164 { 00165 n_points = 0; 00166 00167 size = GET_OBJECT_SIZE( *polygons, poly ); 00168 00169 for_less( edge, 0, size ) 00170 { 00171 point_index1 = polygons->indices[ 00172 POINT_INDEX(polygons->end_indices,poly,edge)]; 00173 point_index2 = polygons->indices[ 00174 POINT_INDEX(polygons->end_indices,poly,(edge+1)%size)]; 00175 00176 SUB_POINTS( v1, polygons->points[point_index1], *plane_origin ); 00177 SUB_POINTS( v2, polygons->points[point_index2], *plane_origin ); 00178 00179 t1 = DOT_VECTORS( v1, *plane_normal ); 00180 t2 = DOT_VECTORS( v2, *plane_normal ); 00181 00182 /*--- check if it intersects the line segment [p1 .. p2) */ 00183 00184 if( t1 == 0.0 || (t1 > 0.0 && t2 < 0.0) || (t1 < 0.0 && t2 > 0.0) ) 00185 { 00186 if( n_points < 2 ) 00187 { 00188 if( t1 == 0.0 ) 00189 ratios[n_points] = 0.0; 00190 else 00191 ratios[n_points] = t1 / (t1 - t2); 00192 00193 p1s[n_points] = MIN( point_index1, point_index2 ); 00194 p2s[n_points] = MAX( point_index1, point_index2 ); 00195 if( p1s[n_points] != point_index1 ) 00196 ratios[n_points] = 1.0 - ratios[n_points]; 00197 00198 if( ratios[n_points] == 0.0 ) 00199 { 00200 p2s[n_points] = n_points; 00201 ratios[n_points] = 0.0; 00202 } 00203 else if( ratios[n_points] == 1.0 ) 00204 { 00205 p1s[n_points] = p2s[n_points]; 00206 p2s[n_points] = n_points; 00207 ratios[n_points] = 0.0; 00208 } 00209 } 00210 00211 ++n_points; 00212 } 00213 } 00214 00215 if( n_points == 2 && 00216 (ratios[0] != 0.0 || ratios[1] != 0.0 || p1s[0] != p1s[1]) ) 00217 { 00218 start_new_line( lines ); 00219 00220 for_less( p, 0, 2 ) 00221 { 00222 if( !lookup_in_hash2_table( &hash, p1s[p], p2s[p], 00223 (void *) &index ) ) 00224 { 00225 if( ratios[p] == 0.0 ) 00226 point = polygons->points[p1s[p]]; 00227 else 00228 { 00229 INTERPOLATE_POINTS( point, 00230 polygons->points[p1s[p]], 00231 polygons->points[p2s[p]], 00232 ratios[p] ); 00233 } 00234 00235 index = lines->n_points; 00236 insert_in_hash2_table( &hash, p1s[p], p2s[p], 00237 (void *) &index ); 00238 00239 ADD_ELEMENT_TO_ARRAY( lines->points, lines->n_points, 00240 point, DEFAULT_CHUNK_SIZE ); 00241 } 00242 00243 ADD_ELEMENT_TO_ARRAY( lines->indices, 00244 lines->end_indices[lines->n_items-1], 00245 index, DEFAULT_CHUNK_SIZE ); 00246 } 00247 } 00248 } 00249 00250 delete_hash2_table( &hash ); 00251 00252 coalesce_lines( lines ); 00253 } 00254 00255 public void intersect_planes_with_quadmesh( 00256 quadmesh_struct *quadmesh, 00257 Point *plane_origin, 00258 Vector *plane_normal, 00259 lines_struct *lines ) 00260 { 00261 int n_points, p, index, m, n, x_index, y_index; 00262 int edge; 00263 int point_index1, point_index2, indices[4]; 00264 Vector v1, v2; 00265 Point point, *points; 00266 Real t1, t2, ratios[2]; 00267 int p1s[2], p2s[2]; 00268 hash2_table_struct hash; 00269 00270 initialize_lines( lines, WHITE ); 00271 00272 get_quadmesh_n_objects( quadmesh, &m, &n ); 00273 00274 initialize_hash2_table( &hash, m * n, (int) sizeof(int), 00275 0.5, .25 ); 00276 00277 points = quadmesh->points; 00278 00279 index = 0; 00280 00281 for_less( x_index, 0, m ) 00282 { 00283 for_less( y_index, 0, n ) 00284 { 00285 n_points = 0; 00286 00287 indices[0] = IJ(x_index,y_index,quadmesh->n); 00288 indices[1] = IJ((x_index+1)%quadmesh->m,y_index,quadmesh->n); 00289 indices[2] = IJ((x_index+1)%quadmesh->m,(y_index+1)%quadmesh->n, 00290 quadmesh->n); 00291 indices[3] = IJ(x_index,(y_index+1)%quadmesh->n, 00292 quadmesh->n); 00293 00294 for_less( edge, 0, 4 ) 00295 { 00296 point_index1 = indices[edge]; 00297 point_index2 = indices[(edge+1) % 4]; 00298 00299 SUB_POINTS( v1, points[point_index1], *plane_origin ); 00300 SUB_POINTS( v2, points[point_index2], *plane_origin ); 00301 00302 t1 = DOT_VECTORS( v1, *plane_normal ); 00303 t2 = DOT_VECTORS( v2, *plane_normal ); 00304 00305 /*--- check if it intersects the line segment [p1 .. p2) */ 00306 00307 if( t1 == 0.0 || (t1 > 0.0 && t2 < 0.0) || (t1 < 0.0 && t2 > 0.0) ) 00308 { 00309 if( n_points < 2 ) 00310 { 00311 if( t1 == 0.0 ) 00312 ratios[n_points] = 0.0; 00313 else 00314 ratios[n_points] = t1 / (t1 - t2); 00315 00316 p1s[n_points] = MIN( point_index1, point_index2 ); 00317 p2s[n_points] = MAX( point_index1, point_index2 ); 00318 if( p1s[n_points] != point_index1 ) 00319 ratios[n_points] = 1.0 - ratios[n_points]; 00320 00321 if( ratios[n_points] == 0.0 ) 00322 { 00323 p2s[n_points] = n_points; 00324 ratios[n_points] = 0.0; 00325 } 00326 else if( ratios[n_points] == 1.0 ) 00327 { 00328 p1s[n_points] = p2s[n_points]; 00329 p2s[n_points] = n_points; 00330 ratios[n_points] = 0.0; 00331 } 00332 } 00333 00334 ++n_points; 00335 } 00336 } 00337 00338 if( n_points == 2 && 00339 (ratios[0] != 0.0 || ratios[1] != 0.0 || p1s[0] != p1s[1]) ) 00340 { 00341 start_new_line( lines ); 00342 00343 for_less( p, 0, 2 ) 00344 { 00345 if( !lookup_in_hash2_table( &hash, p1s[p], p2s[p], 00346 (void *) &index ) ) 00347 { 00348 if( ratios[p] == 0.0 ) 00349 point = points[p1s[p]]; 00350 else 00351 { 00352 INTERPOLATE_POINTS( point, 00353 points[p1s[p]], points[p2s[p]], 00354 ratios[p] ); 00355 } 00356 00357 index = lines->n_points; 00358 insert_in_hash2_table( &hash, p1s[p], p2s[p], 00359 (void *) &index ); 00360 00361 ADD_ELEMENT_TO_ARRAY( lines->points, lines->n_points, 00362 point, DEFAULT_CHUNK_SIZE ); 00363 } 00364 00365 ADD_ELEMENT_TO_ARRAY( lines->indices, 00366 lines->end_indices[lines->n_items-1], 00367 index, DEFAULT_CHUNK_SIZE ); 00368 } 00369 } 00370 } 00371 } 00372 00373 delete_hash2_table( &hash ); 00374 00375 coalesce_lines( lines ); 00376 }

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