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/tubes.c,v 1.6 2000/02/06 15:30:20 stever Exp $";
00020
#endif
00021
00022
private void generate_tube(
00023
int n_points,
00024 Point points[],
00025
int n_around,
00026 Real radius,
00027 Point tube_points[],
00028 Vector tube_normals[] );
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 private void create_tube(
00048
int n_points,
00049 Point points[],
00050
int n_around,
00051 Real radius,
00052 Colour colour,
00053
quadmesh_struct *quadmesh )
00054 {
00055 Surfprop spr;
00056
00057
get_default_surfprop( &spr );
00058
00059
initialize_quadmesh( quadmesh, colour, &spr, n_points, n_around );
00060 quadmesh->
m_closed =
FALSE;
00061 quadmesh->
n_closed =
TRUE;
00062
00063
generate_tube( n_points, points, n_around, radius,
00064 quadmesh->
points, quadmesh->
normals );
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 public int convert_lines_to_tubes(
00085
lines_struct *lines,
00086
int n_around,
00087 Real radius,
00088
quadmesh_struct *quadmeshes[] )
00089 {
00090
int i, l, line_size;
00091
quadmesh_struct *quadmesh;
00092 Point *points;
00093
00094
if( lines->
n_items == 0 )
00095
return( 0 );
00096
00097 ALLOC( *quadmeshes, lines->
n_items );
00098
00099 for_less( l, 0, lines->
n_items )
00100 {
00101 line_size =
GET_OBJECT_SIZE( *lines, l );
00102
00103 ALLOC( points, line_size );
00104
00105 for_less( i, 0, line_size )
00106 {
00107 points[i] = lines->
points[lines->
indices[
00108
POINT_INDEX(lines->
end_indices,l,i)]];
00109 }
00110
00111 quadmesh = &(*quadmeshes)[l];
00112
00113
create_tube( line_size, points, n_around, radius, lines->
colours[0],
00114 quadmesh );
00115
00116 FREE( points );
00117 }
00118
00119
return( lines->
n_items );
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 private void get_direction(
00140
int n_points,
00141 Point points[],
00142
int i,
00143 BOOLEAN wrap_around,
00144 Vector *dir )
00145 {
00146
int end;
00147
00148 end = i;
00149
00150
do
00151 {
00152 ++end;
00153
if( end == n_points && wrap_around )
00154 end = 0;
00155 }
00156
while( end < n_points && end != i && EQUAL_POINTS(points[i],points[end]) );
00157
00158
if( end >= n_points || end == i )
00159 {
00160 fill_Vector( *dir, 0.0, 0.0, 0.0 );
00161 }
00162
else
00163 {
00164 SUB_POINTS( *dir, points[end], points[i] );
00165
00166 NORMALIZE_VECTOR( *dir, *dir );
00167 }
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 private void fill_in_ellipse_points(
00192 Point tube_points[],
00193 Vector tube_normals[],
00194 Point *centre,
00195
int n_around,
00196 Real x[],
00197 Real y[],
00198 Vector *hor,
00199 Vector *vert )
00200 {
00201
int i;
00202 Vector h, v, offset;
00203
00204 for_less( i, 0, n_around )
00205 {
00206 SCALE_VECTOR( h, *hor, x[i] );
00207 SCALE_VECTOR( v, *vert,
y[i] );
00208
00209 ADD_VECTORS( offset, h, v );
00210
00211 ADD_POINT_VECTOR( tube_points[i], *centre, offset );
00212 NORMALIZE_VECTOR( tube_normals[i], offset );
00213 }
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 private void project_vector_to_plane(
00235 Vector *v,
00236 Vector *direction,
00237 Vector *normal,
00238 Vector *projected )
00239 {
00240 Vector offset;
00241 Real t, n_dot_d, n_dot_v;
00242
00243 n_dot_d = DOT_VECTORS( *normal, *direction );
00244
00245
if( n_dot_d == 0.0 )
00246 {
00247 print_error(
"Error in project_vector_to_plane\n" );
00248 }
00249
else
00250 {
00251 n_dot_v = DOT_VECTORS( *normal, *v );
00252
00253 t = - n_dot_v / n_dot_d;
00254
00255 SCALE_VECTOR( offset, *direction, t );
00256 ADD_VECTORS( *projected, *v, offset );
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 private void generate_tube(
00278
int n_points,
00279 Point points[],
00280
int n_around,
00281 Real radius,
00282 Point tube_points[],
00283 Vector tube_normals[] )
00284 {
00285
int i;
00286 Real *x, *
y, angle;
00287 Vector hor, vert, dir, prev_dir, normal;
00288 BOOLEAN wrap_around;
00289
00290 ALLOC( x, n_around );
00291 ALLOC(
y, n_around );
00292
00293 for_less( i, 0, n_around )
00294 {
00295 angle = (Real) (n_around - 1 - i) / (Real) n_around * 2.0 * PI;
00296 x[i] = radius * cos( angle );
00297
y[i] = radius * sin( angle );
00298 }
00299
00300 wrap_around = EQUAL_POINTS( points[0], points[n_points-1] );
00301
00302
get_direction( n_points, points, 0, wrap_around, &dir );
00303 create_orthogonal_vector( &dir, &hor );
00304
00305
if( wrap_around )
00306
get_direction( n_points, points, n_points-2, wrap_around, &prev_dir );
00307
else
00308 prev_dir = dir;
00309
00310 for_less( i, 0, n_points )
00311 {
00312 CROSS_VECTORS( vert, prev_dir, hor );
00313 NORMALIZE_VECTOR( vert, vert );
00314
00315 CROSS_VECTORS( hor, vert, prev_dir );
00316 NORMALIZE_VECTOR( hor, hor );
00317
00318 ADD_VECTORS( normal, prev_dir, dir );
00319 NORMALIZE_VECTOR( normal, normal );
00320
00321
project_vector_to_plane( &hor, &prev_dir, &normal, &hor );
00322
project_vector_to_plane( &vert, &prev_dir, &normal, &vert );
00323
00324
fill_in_ellipse_points( &tube_points[IJ(i,0,n_around)],
00325 &tube_normals[IJ(i,0,n_around)],
00326 &points[i], n_around, x,
y, &hor, &vert );
00327
00328
if( i < n_points-1 )
00329 {
00330 prev_dir = dir;
00331
00332
if( wrap_around || i < n_points-2 )
00333
get_direction( n_points, points, i+1, wrap_around, &dir );
00334 }
00335 }
00336
00337 FREE( x );
00338 FREE(
y );
00339 }