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
#include <bicpl/data_structures.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Geometry/smooth_lines.c,v 1.11 2000/02/06 15:30:17 stever Exp $";
00021
#endif
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 public void smooth_lines(
00038
lines_struct *lines,
00039 Real smooth_length )
00040 {
00041
int *new_ids, n_points, n_items, n_indices, *indices, *end_indices;
00042
int l, p, point_index, size;
00043 BOOLEAN keep_point;
00044 Point prev;
00045 Real dist_to_prev;
00046 Point *points;
00047 Colour colour;
00048
00049 n_points = 0;
00050 n_items = 0;
00051 n_indices = 0;
00052 indices = NULL;
00053 end_indices = NULL;
00054 points = NULL;
00055
00056 ALLOC( new_ids, lines->
n_points );
00057
00058 for_less( l, 0, lines->
n_points )
00059 new_ids[l] = -1;
00060
00061 for_less( l, 0, lines->
n_items )
00062 {
00063 size =
GET_OBJECT_SIZE( *lines, l );
00064
00065 for_less( p, 0, size )
00066 {
00067 point_index = lines->
indices[
00068
POINT_INDEX(lines->
end_indices,l,p)];
00069
00070
if( p == 0 || p == size-1 )
00071 {
00072 keep_point =
TRUE;
00073 }
00074
else
00075 {
00076 dist_to_prev =
distance_between_points(&prev,
00077 &lines->
points[point_index]);
00078
00079 keep_point = (dist_to_prev >= smooth_length);
00080 }
00081
00082
if( keep_point )
00083 {
00084 prev = lines->
points[point_index];
00085
00086
if( new_ids[point_index] < 0 )
00087 {
00088 new_ids[point_index] = n_points;
00089
00090 ADD_ELEMENT_TO_ARRAY( points, n_points,
00091 lines->
points[point_index], DEFAULT_CHUNK_SIZE );
00092 }
00093
00094 ADD_ELEMENT_TO_ARRAY( indices, n_indices,
00095 new_ids[point_index], DEFAULT_CHUNK_SIZE );
00096 }
00097 }
00098
00099 ADD_ELEMENT_TO_ARRAY( end_indices, n_items,
00100 n_indices, DEFAULT_CHUNK_SIZE );
00101 }
00102
00103 colour = lines->
colours[0];
00104
delete_lines( lines );
00105
00106 lines->
colour_flag =
ONE_COLOUR;
00107 ALLOC( lines->
colours, 1 );
00108 lines->
colours[0] = colour;
00109 lines->
n_points = n_points;
00110 lines->
points = points;
00111 lines->
n_items = n_items;
00112 lines->
indices = indices;
00113 lines->
end_indices = end_indices;
00114
00115 FREE( new_ids );
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 public void create_line_spline(
00134
lines_struct *lines,
00135
int n_curve_segments,
00136
lines_struct *new_lines )
00137 {
00138
int c, l, p, point_index1, point_index2, pt_index, line_size, segment;
00139 BOOLEAN wrap_around;
00140 Point points[4], point;
00141 Real u;
00142
00143
initialize_lines( new_lines, lines->
colours[0] );
00144
00145 new_lines->
colours[0] = lines->
colours[0];
00146 new_lines->
line_thickness = lines->
line_thickness;
00147
00148 new_lines->
n_points = 0;
00149 new_lines->
n_items = 0;
00150
00151 for_less( l, 0, lines->
n_items )
00152 {
00153 line_size =
GET_OBJECT_SIZE( *lines, l );
00154
00155 point_index1 = lines->
indices[
POINT_INDEX(lines->
end_indices,l,0)];
00156 point_index2 = lines->
indices[
00157
POINT_INDEX(lines->
end_indices,l,line_size-1)];
00158
00159 wrap_around = (point_index1 == point_index2);
00160
00161
start_new_line( new_lines );
00162
00163
add_point_to_line( new_lines, &lines->
points[point_index1] );
00164
00165 for_less( p, 0, line_size-1 )
00166 {
00167
if( p == 0 )
00168 {
00169
if( wrap_around && line_size - 2 >= 0 )
00170 pt_index = line_size-2;
00171
else
00172 pt_index = 0;
00173 }
00174
else
00175 pt_index = p - 1;
00176
00177 points[0] = lines->
points[lines->
indices[
00178
POINT_INDEX(lines->
end_indices,l,pt_index)]];
00179
00180 points[1] = lines->
points[lines->
indices[
00181
POINT_INDEX(lines->
end_indices,l,p)]];
00182
00183 points[2] = lines->
points[lines->
indices[
00184
POINT_INDEX(lines->
end_indices,l,p+1)]];
00185
00186
if( p == line_size-2 )
00187 {
00188
if( wrap_around && 1 < line_size )
00189 pt_index = 1;
00190
else
00191 pt_index = line_size-1;
00192 }
00193
else
00194 pt_index = p + 2;
00195
00196 points[3] = lines->
points[lines->
indices[
00197
POINT_INDEX(lines->
end_indices,l,pt_index)]];
00198
00199 for_inclusive( segment, 1, n_curve_segments )
00200 {
00201 u = (Real) segment / (Real) n_curve_segments;
00202
00203 for_less( c, 0, N_DIMENSIONS )
00204 {
00205 Point_coord(point,c) = (Point_coord_type)
00206 cubic_interpolate( u,
00207 (Real) Point_coord(points[0],c),
00208 (Real) Point_coord(points[1],c),
00209 (Real) Point_coord(points[2],c),
00210 (Real) Point_coord(points[3],c) );
00211 }
00212
00213
add_point_to_line( new_lines, &point );
00214 }
00215 }
00216 }
00217 }