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/trans.h>
00017
#include <bicpl/numerical.h>
00018
00019
#ifndef lint
00020
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Transforms/transforms.c,v 1.13 2000/02/06 15:30:51 stever Exp $";
00021
#endif
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 public void make_scale_transform(
00039 Real sx,
00040 Real sy,
00041 Real sz,
00042 Transform *transform )
00043 {
00044 make_identity_transform( transform );
00045
00046 Transform_elem( *transform, 0, 0 ) = sx;
00047 Transform_elem( *transform, 1, 1 ) = sy;
00048 Transform_elem( *transform, 2, 2 ) = sz;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 public void set_transform_x_and_z_axes(
00073 Transform *transform,
00074 Vector *x_axis,
00075 Vector *z_axis )
00076 {
00077 Vector n_z, n_y, n_x;
00078
00079 NORMALIZE_VECTOR( n_z, *z_axis );
00080 CROSS_VECTORS( n_y, n_z, *x_axis );
00081 NORMALIZE_VECTOR( n_y, n_y );
00082 CROSS_VECTORS( n_x, n_z, n_y );
00083 NORMALIZE_VECTOR( n_x, n_x );
00084
00085 set_transform_x_axis( transform, &n_x );
00086 set_transform_y_axis( transform, &n_y );
00087 set_transform_z_axis( transform, &n_z );
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 public void make_translation_transform(
00106 Real x_trans,
00107 Real y_trans,
00108 Real z_trans,
00109 Transform *transform )
00110 {
00111 make_identity_transform( transform );
00112
00113 Transform_elem( *transform, 0, 3 ) = x_trans;
00114 Transform_elem( *transform, 1, 3 ) = y_trans;
00115 Transform_elem( *transform, 2, 3 ) = z_trans;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 public void make_origin_transform(
00132 Point *origin,
00133 Transform *transform )
00134 {
00135 make_identity_transform( transform );
00136
00137 Transform_elem( *transform, 0, 3 ) = (Transform_elem_type) Point_x(*origin);
00138 Transform_elem( *transform, 1, 3 ) = (Transform_elem_type) Point_y(*origin);
00139 Transform_elem( *transform, 2, 3 ) = (Transform_elem_type) Point_z(*origin);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 public void make_rotation_transform(
00158 Real radians,
00159
int axis,
00160 Transform *transform )
00161 {
00162
int a1, a2;
00163 Real c, s;
00164
00165 a1 = (axis + 1) % N_DIMENSIONS;
00166 a2 = (axis + 2) % N_DIMENSIONS;
00167
00168 make_identity_transform( transform );
00169
00170 c = cos( (
double) radians );
00171 s = sin( (
double) radians );
00172
00173 Transform_elem( *transform, a1, a1 ) = c;
00174 Transform_elem( *transform, a1, a2 ) = s;
00175 Transform_elem( *transform, a2, a1 ) = -s;
00176 Transform_elem( *transform, a2, a2 ) = c;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 public void make_transform_relative_to_point(
00199 Point *point,
00200 Transform *transform,
00201 Transform *rel_transform )
00202 {
00203 Transform to_origin, to_point;
00204
00205
make_translation_transform( (Real) Point_x(*point), (Real) Point_y(*point),
00206 (Real) Point_z(*point), &to_point );
00207
00208
make_translation_transform( -(Real) Point_x(*point),
00209 -(Real) Point_y(*point),
00210 -(Real) Point_z(*point), &to_origin );
00211
00212 concat_transforms( rel_transform, &to_origin, transform );
00213 concat_transforms( rel_transform, rel_transform, &to_point );
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 public void make_transform_in_coordinate_system(
00238 Point *origin,
00239 Vector *x_axis,
00240 Vector *y_axis,
00241 Vector *z_axis,
00242 Transform *transform,
00243 Transform *rel_transform )
00244 {
00245 Transform to_bases, from_bases;
00246
00247 make_change_to_bases_transform( origin, x_axis, y_axis, z_axis, &to_bases );
00248 make_change_from_bases_transform( origin, x_axis, y_axis, z_axis,
00249 &from_bases );
00250
00251 concat_transforms( rel_transform, &from_bases, transform );
00252 concat_transforms( rel_transform, rel_transform, &to_bases );
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 public void make_rotation_about_axis(
00271 Vector *axis,
00272 Real angle,
00273 Transform *transform )
00274 {
00275 Real c, s, t;
00276 Real txy, txz, tyz, sx, sy, sz;
00277 Real x,
y, z;
00278 Vector unit_axis;
00279
00280 NORMALIZE_VECTOR( unit_axis, *axis );
00281
00282 c = cos( (
double) -angle );
00283 s = sin( (
double) -angle );
00284 t = 1.0 - c;
00285
00286 x = (Real) Vector_x( unit_axis );
00287
y = (Real) Vector_y( unit_axis );
00288 z = (Real) Vector_z( unit_axis );
00289
00290 txy = t * x *
y;
00291 txz = t * x * z;
00292 tyz = t *
y * z;
00293
00294 sx = s * x;
00295 sy = s *
y;
00296 sz = s * z;
00297
00298 Transform_elem( *transform, 0, 0 ) = t * x * x + c;
00299 Transform_elem( *transform, 0, 1 ) = txy + sz;
00300 Transform_elem( *transform, 0, 2 ) = txz - sy;
00301 Transform_elem( *transform, 0, 3 ) = 0.0;
00302
00303 Transform_elem( *transform, 1, 0 ) = txy - sz;
00304 Transform_elem( *transform, 1, 1 ) = t *
y *
y + c;
00305 Transform_elem( *transform, 1, 2 ) = tyz + sx;
00306 Transform_elem( *transform, 1, 3 ) = 0.0;
00307
00308 Transform_elem( *transform, 2, 0 ) = txz + sy;
00309 Transform_elem( *transform, 2, 1 ) = tyz - sx;
00310 Transform_elem( *transform, 2, 2 ) = t * z * z + c;
00311 Transform_elem( *transform, 2, 3 ) = 0.0;
00312
00313 Transform_elem( *transform, 3, 0 ) = 0.0;
00314 Transform_elem( *transform, 3, 1 ) = 0.0;
00315 Transform_elem( *transform, 3, 2 ) = 0.0;
00316 Transform_elem( *transform, 3, 3 ) = 1.0;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 public void convert_2d_transform_to_rotation_translation(
00336 Transform *transform,
00337 Real *degrees_clockwise,
00338 Real *x_trans,
00339 Real *y_trans )
00340 {
00341 Real x,
y;
00342
00343 x = Transform_elem(*transform, X, X );
00344
y = Transform_elem(*transform, Y, X );
00345
00346 *degrees_clockwise = RAD_TO_DEG *
compute_clockwise_rotation( x,
y );
00347 *x_trans = Transform_elem( *transform, X, 3 );
00348 *y_trans = Transform_elem( *transform, Y, 3 );
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 public Real
compute_clockwise_rotation( Real x, Real y )
00368 {
00369 Real radians;
00370
00371
if( x == 0.0 )
00372 {
00373
if(
y < 0.0 )
00374
return( PI / 2.0 );
00375
else if(
y > 0.0 )
00376
return( 3.0 * PI / 2.0 );
00377
else
00378
return( 0.0 );
00379 }
00380
else if(
y == 0.0 )
00381 {
00382
if( x > 0.0 )
00383
return( 0.0 );
00384
else
00385
return( PI );
00386 }
00387
else
00388 {
00389 radians = - (Real) atan2( (
double)
y, (
double) x );
00390
00391
if( radians < 0.0 )
00392 radians += 2.0 * PI;
00393
00394
return( radians );
00395 }
00396 }
00397
00398 public BOOLEAN
is_transform_right_handed(
00399 Transform *transform )
00400 {
00401 Real volume;
00402 Vector x_axis, y_axis, z_axis, offset;
00403
00404 get_transform_x_axis( transform, &x_axis );
00405 get_transform_y_axis( transform, &y_axis );
00406 get_transform_z_axis( transform, &z_axis );
00407
00408 CROSS_VECTORS( offset, x_axis, y_axis );
00409 volume = DOT_VECTORS( offset, z_axis );
00410
00411
return( volume > 0.0 );
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 public void make_identity_transform_2d(
00428 Transform_2d *transform )
00429 {
00430 Transform_2d_elem( *transform, 0, 0 ) = 1.0;
00431 Transform_2d_elem( *transform, 0, 1 ) = 0.0;
00432 Transform_2d_elem( *transform, 0, 2 ) = 0.0;
00433 Transform_2d_elem( *transform, 1, 0 ) = 0.0;
00434 Transform_2d_elem( *transform, 1, 1 ) = 1.0;
00435 Transform_2d_elem( *transform, 1, 2 ) = 0.0;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 public void get_inverse_transform_2d(
00452 Transform_2d *transform,
00453 Transform_2d *inverse )
00454 {
00455 Real determinant;
00456
00457 determinant = Transform_2d_elem(*transform,0,0) *
00458 Transform_2d_elem(*transform,1,1) -
00459 Transform_2d_elem(*transform,1,0) *
00460 Transform_2d_elem(*transform,0,1);
00461
00462 Transform_2d_elem(*inverse,0,0) = Transform_2d_elem(*transform,1,1) /
00463 determinant;
00464 Transform_2d_elem(*inverse,0,1) = -Transform_2d_elem(*transform,0,1) /
00465 determinant;
00466 Transform_2d_elem(*inverse,0,2) = (Transform_2d_elem(*transform,1,2) *
00467 Transform_2d_elem(*transform,0,1) -
00468 Transform_2d_elem(*transform,1,1) *
00469 Transform_2d_elem(*transform,0,2)) /
00470 determinant;
00471
00472 Transform_2d_elem(*inverse,1,0) = -Transform_2d_elem(*transform,1,0) /
00473 determinant;
00474 Transform_2d_elem(*inverse,1,1) = Transform_2d_elem(*transform,0,0) /
00475 determinant;
00476 Transform_2d_elem(*inverse,1,2) = (Transform_2d_elem(*transform,1,0) *
00477 Transform_2d_elem(*transform,0,2) -
00478 Transform_2d_elem(*transform,0,0) *
00479 Transform_2d_elem(*transform,1,2)) /
00480 determinant;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 public void transform_point_2d(
00500 Transform_2d *transform,
00501 Real x,
00502 Real y,
00503 Real *x_trans,
00504 Real *y_trans )
00505 {
00506 *x_trans = Transform_2d_elem(*transform,0,0) * x +
00507 Transform_2d_elem(*transform,0,1) *
y +
00508 Transform_2d_elem(*transform,0,2);
00509 *y_trans = Transform_2d_elem(*transform,1,0) * x +
00510 Transform_2d_elem(*transform,1,1) *
y +
00511 Transform_2d_elem(*transform,1,2);
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 public void get_least_squares_transform_2d(
00534
int n_points,
00535 Real x[],
00536 Real y[],
00537 Real x_trans[],
00538 Real y_trans[],
00539 Transform_2d *transform_2d )
00540 {
00541
int p;
00542 Real coefs[2+1];
00543 Real **coords;
00544
00545 ALLOC2D( coords, n_points, 2 );
00546
00547 for_less( p, 0, n_points )
00548 {
00549 coords[p][X] = x[p];
00550 coords[p][Y] =
y[p];
00551 }
00552
00553
least_squares( n_points, 2, coords, x_trans, coefs );
00554
00555 Transform_2d_elem( *transform_2d, 0, 0 ) = coefs[1];
00556 Transform_2d_elem( *transform_2d, 0, 1 ) = coefs[2];
00557 Transform_2d_elem( *transform_2d, 0, 2 ) = coefs[0];
00558
00559
least_squares( n_points, 2, coords, y_trans, coefs );
00560
00561 Transform_2d_elem( *transform_2d, 1, 0 ) = coefs[1];
00562 Transform_2d_elem( *transform_2d, 1, 1 ) = coefs[2];
00563 Transform_2d_elem( *transform_2d, 1, 2 ) = coefs[0];
00564
00565 FREE2D( coords );
00566 }