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/objects.h>
00017
#include <bicpl/geom.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Objects/lines.c,v 1.19 2000/02/06 15:30:43 stever Exp $";
00021
#endif
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 public void initialize_lines(
00037
lines_struct *lines,
00038 Colour col )
00039 {
00040 ALLOC( lines->
colours, 1 );
00041
00042 lines->
colour_flag =
ONE_COLOUR;
00043 lines->
colours[0] = col;
00044
00045 lines->
line_thickness = 1.0f;
00046 lines->
n_points = 0;
00047 lines->
n_items = 0;
00048
00049 lines->
bintree = (
bintree_struct_ptr) NULL;
00050 }
00051
00052 public void initialize_lines_with_size(
00053
lines_struct *lines,
00054 Colour col,
00055
int size,
00056 BOOLEAN closed )
00057 {
00058
int i, n_indices;
00059
00060
initialize_lines( lines, col );
00061
00062
if( closed )
00063 n_indices = size + 1;
00064
else
00065 n_indices = size;
00066
00067 lines->
n_points = size;
00068 ALLOC( lines->
points, size );
00069
00070 lines->
n_items = 1;
00071 ALLOC( lines->
end_indices, 1 );
00072 lines->
end_indices[0] = n_indices;
00073
00074 ALLOC( lines->
indices, n_indices );
00075
00076 for_less( i, 0, n_indices )
00077 lines->
indices[i] = i % size;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 public void delete_lines(
lines_struct *lines )
00095 {
00096
free_colours( lines->
colour_flag, lines->
colours, lines->
n_points,
00097 lines->
n_items );
00098
00099
if( lines->
n_points > 0 )
00100 FREE( lines->
points );
00101
00102
if( lines->
n_items > 0 )
00103 FREE( lines->
end_indices );
00104
00105
if( lines->
n_items > 0 )
00106 FREE( lines->
indices );
00107
00108
delete_bintree_if_any( &lines->
bintree );
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 public void start_new_line(
lines_struct *lines )
00126 {
00127
int n_indices;
00128
00129 n_indices =
NUMBER_INDICES( *lines );
00130
00131 ADD_ELEMENT_TO_ARRAY( lines->
end_indices, lines->
n_items,
00132 n_indices, DEFAULT_CHUNK_SIZE );
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 public void add_point_to_line(
00150
lines_struct *lines,
00151 Point *point )
00152 {
00153
if( lines->
n_items == 0 )
00154
start_new_line( lines );
00155
00156 ADD_ELEMENT_TO_ARRAY( lines->
indices, lines->
end_indices[lines->
n_items-1],
00157 lines->
n_points, DEFAULT_CHUNK_SIZE );
00158
00159 ADD_ELEMENT_TO_ARRAY( lines->
points, lines->
n_points,
00160 *point, DEFAULT_CHUNK_SIZE );
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 public void get_line_segment_index(
00180
lines_struct *lines,
00181
int obj_index,
00182
int *line,
00183
int *seg )
00184 {
00185
int first, last, mid, n_objs;
00186
00187 first = 0;
00188 last = lines->
n_items-1;
00189
00190
while( first < last )
00191 {
00192 mid = (first + last) / 2;
00193
00194 n_objs = lines->
end_indices[mid] - mid - 1;
00195
if( obj_index < n_objs )
00196 last = mid;
00197
else
00198 first = mid+1;
00199 }
00200
00201 *line = first;
00202
00203
if( first == 0 )
00204 *seg = obj_index;
00205
else
00206 *seg = obj_index - (lines->
end_indices[first-1] - first);
00207 }
00208
00209
static void (*bintree_delete_function) (
bintree_struct_ptr* ) = NULL;
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 public void set_bintree_delete_function(
00228
void (*func)(
bintree_struct_ptr * ) )
00229 {
00230 bintree_delete_function = func;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 public void delete_bintree_if_any(
00247
bintree_struct_ptr *bintree )
00248 {
00249
if( bintree_delete_function != NULL )
00250 (*bintree_delete_function) ( bintree );
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 public Real
get_lines_length(
00267
lines_struct *lines )
00268 {
00269 Real len;
00270
int line, i, p0, p1, size;
00271
00272 len = 0.0;
00273
00274 for_less( line, 0, lines->
n_items )
00275 {
00276 size =
GET_OBJECT_SIZE( *lines, line );
00277
00278 for_less( i, 0, size-1 )
00279 {
00280 p0 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,i)];
00281 p1 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,i+1)];
00282 len +=
distance_between_points( &lines->
points[p0],
00283 &lines->
points[p1] );
00284 }
00285 }
00286
00287
return( len );
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 public void get_lines_arc_point(
00304
lines_struct *lines,
00305 Real arc_length,
00306 Point *point )
00307 {
00308 Real len, segment_length, ratio;
00309
int line, i, p0, p1, size;
00310 BOOLEAN found;
00311
00312
if( arc_length < 0.0 )
00313 {
00314 print_error(
"get_lines_arc_point: arc_length < 0.0, using 0.0\n" );
00315 arc_length = 0.0;
00316 }
00317
00318 len = 0.0;
00319 found =
FALSE;
00320
00321 for_less( line, 0, lines->
n_items )
00322 {
00323 size =
GET_OBJECT_SIZE( *lines, line );
00324
00325 for_less( i, 0, size-1 )
00326 {
00327 p0 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,i)];
00328 p1 = lines->
indices[
POINT_INDEX(lines->
end_indices,line,i+1)];
00329 segment_length =
distance_between_points( &lines->
points[p0],
00330 &lines->
points[p1] );
00331 len += segment_length;
00332
00333
if( len > arc_length )
00334 {
00335 found =
TRUE;
00336
break;
00337 }
00338 }
00339
00340
if( found )
00341
break;
00342 }
00343
00344
if( !found )
00345 {
00346 print_error(
"get_lines_arc_point: arc_length too large, using end\n" );
00347 *point = lines->
points[p1];
00348
return;
00349 }
00350
00351 ratio = (len - arc_length) / segment_length;
00352 INTERPOLATE_POINTS( *point, lines->
points[p1], lines->
points[p0], ratio );
00353 }