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.h>
00017
00018
#ifndef lint
00019
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Volumes/scan_lines.c,v 1.9 2000/02/05 21:27:28 stever Exp $";
00020
#endif
00021
00022
private void scan_line_segment_to_voxels(
00023 Volume volume,
00024 Volume label_volume,
00025
int label,
00026 Point *p1,
00027 Point *p2,
00028 Real radius );
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 public void scan_lines_to_voxels(
00048
lines_struct *lines,
00049 Volume volume,
00050 Volume label_volume,
00051
int label )
00052 {
00053
int i, line, size;
00054 Point p1, p2;
00055
00056 for_less( line, 0, lines->
n_items )
00057 {
00058 size =
GET_OBJECT_SIZE( *lines, line );
00059
00060 for_less( i, 0, size-1 )
00061 {
00062 p1 = lines->
points[
00063 lines->
indices[
POINT_INDEX(lines->
end_indices,line,i)]];
00064 p2 = lines->
points[
00065 lines->
indices[
POINT_INDEX(lines->
end_indices,line,i+1)]];
00066
00067
scan_line_segment_to_voxels( volume, label_volume, label,
00068 &p1, &p2,
00069 (Real) lines->
line_thickness );
00070 }
00071 }
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 private Real
point_segment_distance_squared(
00088 Point *point,
00089 Point *p1,
00090 Point *p2 )
00091 {
00092 Vector offset;
00093 Point closest;
00094
00095
get_closest_point_on_line_segment( point, p1, p2, &closest );
00096
00097 SUB_POINTS( offset, *point, closest );
00098
00099
return( DOT_VECTORS( offset, offset ) );
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 private void scan_line_segment_to_voxels(
00121 Volume volume,
00122 Volume label_volume,
00123
int label,
00124 Point *p1,
00125 Point *p2,
00126 Real radius )
00127 {
00128
int c, sizes[MAX_DIMENSIONS];
00129 Point min_point, max_point;
00130 Real min_voxel[MAX_DIMENSIONS], min_v, max_v;
00131 Real max_voxel[MAX_DIMENSIONS];
00132 Real voxel[MAX_DIMENSIONS];
00133 Real x_world, y_world, z_world;
00134
int int_voxel[MAX_DIMENSIONS];
00135
int int_min_voxel[MAX_DIMENSIONS];
00136
int int_max_voxel[MAX_DIMENSIONS];
00137
int tx, ty, tz, dim;
00138 Point world_voxel;
00139
00140 for_less( c, 0, N_DIMENSIONS )
00141 {
00142 Point_coord(min_point,c) = (Point_coord_type)
00143 ((Real) MIN(Point_coord(*p1,c),Point_coord(*p2,c)) - radius);
00144 Point_coord(max_point,c) = (Point_coord_type)
00145 ((Real) MAX(Point_coord(*p1,c),Point_coord(*p2,c)) + radius);
00146 }
00147
00148 get_volume_sizes( volume, sizes );
00149
00150 for_less( tx, 0, 2 )
00151 for_less( ty, 0, 2 )
00152 for_less( tz, 0, 2 )
00153 {
00154 convert_world_to_voxel( volume,
00155 (tx == 0) ? RPoint_x(min_point) :
00156 RPoint_x(max_point),
00157 (ty == 0) ? RPoint_y(min_point) :
00158 RPoint_y(max_point),
00159 (tz == 0) ? RPoint_z(min_point) :
00160 RPoint_z(max_point),
00161 voxel );
00162
00163 for_less( dim, 0, N_DIMENSIONS )
00164 {
00165
if( tx == 0 && ty == 0 && tz == 0 )
00166 {
00167 min_voxel[dim] = voxel[dim];
00168 max_voxel[dim] = voxel[dim];
00169 }
00170
else if( voxel[dim] < min_voxel[dim] )
00171 min_voxel[dim] = voxel[dim];
00172
else if( voxel[dim] > max_voxel[dim] )
00173 max_voxel[dim] = voxel[dim];
00174 }
00175 }
00176
00177 for_less( c, 0, N_DIMENSIONS )
00178 {
00179 min_v = MIN( min_voxel[c], max_voxel[c] );
00180 max_v = MAX( min_voxel[c], max_voxel[c] );
00181
00182 int_min_voxel[c] = ROUND( min_v );
00183 int_max_voxel[c] = ROUND( max_v );
00184
00185
if( int_min_voxel[c] < 0 )
00186 int_min_voxel[c] = 0;
00187
if( int_max_voxel[c] > sizes[c]-1 )
00188 int_max_voxel[c] = sizes[c]-1;
00189 }
00190
00191 for_inclusive( int_voxel[X], int_min_voxel[X], int_max_voxel[X] )
00192 for_inclusive( int_voxel[Y], int_min_voxel[Y], int_max_voxel[Y] )
00193 for_inclusive( int_voxel[Z], int_min_voxel[Z], int_max_voxel[Z] )
00194 {
00195 convert_3D_voxel_to_world( volume, (Real) int_voxel[X],
00196 (Real) int_voxel[Y], (Real) int_voxel[Z],
00197 &x_world, &y_world, &z_world );
00198
00199 fill_Point( world_voxel, x_world, y_world, z_world );
00200
00201
if(
point_segment_distance_squared( &world_voxel, p1, p2 ) <
00202 radius * radius )
00203 {
00204
set_volume_label_data( label_volume, int_voxel, label );
00205 }
00206 }
00207 }