VIOAPI void create_orthogonal_vector( VIO_Vector *v, VIO_Vector *ortho ) { VIO_Real x, y, z; x = (VIO_Real) Vector_x(*v); y = (VIO_Real) Vector_y(*v); z = (VIO_Real) Vector_z(*v); fill_Vector( *ortho, y+z, -x-z, y-x ); }
int main( int argc, char *argv[] ) { char *input_filename; int i, n_objects; File_formats format; object_struct **object_list; Vector dir; Point eye; Real eye_x, eye_y, eye_z, dir_x, dir_y, dir_z; Real distance; int obj_index; BOOLEAN intersects; initialize_argument_processing( argc, argv ); if( !get_string_argument( "", &input_filename ) || !get_real_argument( 0.0, &eye_x ) || !get_real_argument( 0.0, &eye_y ) || !get_real_argument( 0.0, &eye_z ) || !get_real_argument( 0.0, &dir_x ) || !get_real_argument( 0.0, &dir_y ) || !get_real_argument( 0.0, &dir_z ) ) { print_error( "Usage\n" ); return( 1 ); } fill_Point( eye, eye_x, eye_y, eye_z ); fill_Vector( dir, dir_x, dir_y, dir_z ); NORMALIZE_VECTOR( dir, dir ); if( input_graphics_file( input_filename, &format, &n_objects, &object_list ) != OK ) return( 1 ); intersects = intersect_ray_with_object( &eye, &dir, object_list[0], &obj_index, &distance, NULL ); print( "%d: %g\n", intersects, distance ); return( 0 ); }
VIO_BOOL vol_to_cov(VIO_Volume d1, VIO_Volume m1, float centroid[4], float covar[4][4], double *step) { VectorR vector_step, slice_step, row_step, col_step; PointR starting_offset, starting_origin, starting_position, slice, row, col, voxel; VIO_Real tx,ty,tz; int i,r,c,s, limits[VOL_NDIMS]; float t, sxx,syy,szz, sxy,syz,sxz, sx,sy,sz,si; VIO_Real thickness[3]; int sizes[3]; VIO_Real true_value; get_volume_separations(d1, thickness); get_volume_sizes(d1, sizes); /* build sampling lattice info */ for(i=0; i<3; i++) { step[i] *= thickness[i] / fabs( thickness[i]); } fill_Vector( col_step, step[COL_IND], 0.0, 0.0 ); fill_Vector( row_step, 0.0, step[ROW_IND], 0.0 ); fill_Vector( slice_step, 0.0, 0.0, step[SLICE_IND] ); convert_3D_voxel_to_world(d1, 0.0, 0.0, 0.0, &tx, &ty, &tz); fill_Point( starting_origin, tx, ty, tz); for(i=0; i<3; i++) { /* for each dim, get # of steps in that direction, and set starting offset */ t = sizes[i] * thickness[i] / step[i]; limits[i] = abs( t ); Point_coord( starting_offset, (i) ) = ( (sizes[i]-1)*thickness[i] - (limits[i] * step[i] ) ) / 2.0; } ADD_POINTS( starting_position, starting_origin, starting_offset ); /* */ /* calculate centroids first */ sx = 0.0; sy = 0.0; sz = 0.0; si = 0.0; for(s=0; s<=limits[SLICE_IND]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[ROW_IND]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[COL_IND]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sx += Point_x(col) * true_value; sy += Point_y(col) * true_value; sz += Point_z(col) * true_value; si += true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } if (si!=0.0) { centroid[1] = sx/ si; centroid[2] = sy/ si; centroid[3] = sz/ si; sxx = syy = szz = 0.0; sxy = syz = sxz = 0.0; /* now calculate variances and co-variances */ for(s=0; s<=limits[VIO_Z]; s++) { SCALE_VECTOR( vector_step, slice_step, s); ADD_POINT_VECTOR( slice, starting_position, vector_step ); for(r=0; r<=limits[VIO_Y]; r++) { SCALE_VECTOR( vector_step, row_step, r); ADD_POINT_VECTOR( row, slice, vector_step ); SCALE_POINT( col, row, 1.0); /* init first col position */ for(c=0; c<=limits[VIO_X]; c++) { convert_3D_world_to_voxel(d1, Point_x(col), Point_y(col), Point_z(col), &tx, &ty, &tz); fill_Point( voxel, tx, ty, tz ); /* build the voxel POINT */ if (point_not_masked(m1, Point_x(col), Point_y(col), Point_z(col))) { if (INTERPOLATE_TRUE_VALUE( d1, &voxel, &true_value )) { sxx += (Point_x( col )-centroid[1]) * (Point_x( col )-centroid[1]) * true_value; syy += (Point_y( col )-centroid[2]) * (Point_y( col )-centroid[2]) * true_value; szz += (Point_z( col )-centroid[3]) * (Point_z( col )-centroid[3]) * true_value; sxy += (Point_x( col )-centroid[1]) * (Point_y( col )-centroid[2]) * true_value; syz += (Point_y( col )-centroid[2]) * (Point_z( col )-centroid[3]) * true_value; sxz += (Point_x( col )-centroid[1]) * (Point_z( col )-centroid[3]) * true_value; } /* else requested voxel is just outside volume., so ignore it */ } ADD_POINT_VECTOR( col, col, col_step ); } } } covar[1][1] = sxx/si; covar[1][2] = sxy/si; covar[1][3] = sxz/si; covar[2][1] = sxy/si; covar[2][2] = syy/si; covar[2][3] = syz/si; covar[3][1] = sxz/si; covar[3][2] = syz/si; covar[3][3] = szz/si; return(TRUE); } else { return(FALSE); } }
/* regrid a point in a file using the input co-ordinate and data */ void regrid_point(VIO_Volume * totals, VIO_Volume * weights, double x, double y, double z, int v_size, double *data_buf) { int sizes[MAX_VAR_DIMS]; VIO_Real steps[MAX_VAR_DIMS]; VIO_Real starts[MAX_VAR_DIMS]; int start_idx[3]; int stop_idx[3]; double value, weight; double euc_dist; double euc[3]; double c_pos[3]; int i, j, k, v; double coord[3]; /* target point in mm coordinates, in X, Y, Z order */ VIO_Transform dircos, invdircos; VIO_Vector vector; VIO_Real dir[3]; /* the coord used below has to be in mm coordinates in the dircos space of the target volume. Hence the manipulations with the vols direction_cosines */ make_identity_transform(&dircos); get_volume_direction_cosine(*totals, perm[0], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_x_axis(&dircos, &vector); get_volume_direction_cosine(*totals, perm[1], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_y_axis(&dircos, &vector); get_volume_direction_cosine(*totals, perm[2], dir); fill_Vector(vector, dir[0], dir[1], dir[2]); set_transform_z_axis(&dircos, &vector); for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ Transform_elem(invdircos, i, j) = Transform_elem(dircos, j, i); } } transform_point(&invdircos, x, y, z, &coord[0], &coord[1], &coord[2]); get_volume_sizes(*totals, sizes); /* in volume voxel order, ie z,y,x with x fastest */ get_volume_separations(*totals, steps); get_volume_starts(*totals, starts); /* figure out the neighbouring voxels start and stop (in voxel co-ordinates) */ for(i = 0; i < 3; i++){ /* go through x, y and z */ start_idx[i] = (int)rint((coord[i] - starts[perm[i]] - regrid_radius[i]) / steps[perm[i]]); stop_idx[i] = start_idx[i] + rint((regrid_radius[i] * 2) / steps[perm[i]]); /* flip if required */ if(start_idx[i] > stop_idx[i]){ value = start_idx[i]; start_idx[i] = stop_idx[i]; stop_idx[i] = value; } /* check that we aren't off the edge */ if(start_idx[i] < 0){ start_idx[i] = 0; } if(stop_idx[i] >= sizes[perm[i]]){ stop_idx[i] = sizes[perm[i]] - 1; } } /* loop over the neighbours, getting euclidian distance */ c_pos[0] = starts[perm[0]] + (start_idx[0] * steps[perm[0]]); for(i = start_idx[0]; i <= stop_idx[0]; i++){ euc[0] = fabs(c_pos[0] - coord[0]); c_pos[1] = starts[perm[1]] + (start_idx[1] * steps[perm[1]]); for(j = start_idx[1]; j <= stop_idx[1]; j++){ euc[1] = fabs(c_pos[1] - coord[1]); c_pos[2] = starts[perm[2]] + (start_idx[2] * steps[perm[2]]); for(k = start_idx[2]; k <= stop_idx[2]; k++){ euc[2] = fabs(c_pos[2] - coord[2]); euc_dist = sqrt(SQR2(euc[0]) + SQR2(euc[1]) + SQR2(euc[2])); if((regrid_radius[0] == 0 || euc[0] <= regrid_radius[0]) && (regrid_radius[1] == 0 || euc[1] <= regrid_radius[1]) && (regrid_radius[2] == 0 || euc[2] <= regrid_radius[2])){ /* calculate the weighting factor */ switch (regrid_type){ default: fprintf(stderr, "Erk! unknown regrid_type. File: %s Line: %d\n", __FILE__, __LINE__); exit(EXIT_FAILURE); break; case NEAREST_FUNC: case LINEAR_FUNC: weight = euc_dist; break; case KAISERBESSEL_FUNC: weight = gsl_sf_bessel_I0(regrid_sigma[0] * sqrt(1 - SQR2(euc[0] / regrid_radius[0]))) * gsl_sf_bessel_I0(regrid_sigma[1] * sqrt(1 - SQR2(euc[1] / regrid_radius[1]))) * gsl_sf_bessel_I0(regrid_sigma[2] * sqrt(1 - SQR2(euc[2] / regrid_radius[2]))) / SQR3((regrid_radius[0] + regrid_radius[1] + regrid_radius[2]) / 3); break; case GAUSSIAN_FUNC: weight = exp(-SQR2(euc[0]) / SQR2(regrid_sigma[0])) * exp(-SQR2(euc[1]) / SQR2(regrid_sigma[1])) * exp(-SQR2(euc[2]) / SQR2(regrid_sigma[2])); break; } /* set data values */ if(regrid_type == NEAREST_FUNC){ value = get_volume_real_value(*weights, k, j, i, 0, 0); if(weight < value){ set_volume_real_value(*weights, k, j, i, 0, 0, weight); for(v = 0; v < v_size; v++){ set_volume_real_value(*totals, k, j, i, v, 0, data_buf[0 + v] * weight); } } } else{ for(v = 0; v < v_size; v++){ value = get_volume_real_value(*totals, k, j, i, v, 0); set_volume_real_value(*totals, k, j, i, v, 0, value + (data_buf[0 + v] * weight)); } /* increment count value */ value = get_volume_real_value(*weights, k, j, i, 0, 0); set_volume_real_value(*weights, k, j, i, 0, 0, value + weight); } } c_pos[2] += steps[perm[2]]; } c_pos[1] += steps[perm[1]]; } c_pos[0] += steps[perm[0]]; } }