Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 204 | chris | 1 | #include <math.h> |
| 2 | #include <stdio.h> |
||
| 3 | #include <AR/ar.h> |
||
| 4 | #include <AR/param.h> |
||
| 5 | #include <AR/matrix.h> |
||
| 6 | #include "calib_camera.h" |
||
| 7 | |||
| 8 | static int calc_inp2( CALIB_PATT_T *patt, CALIB_COORD_T *screen, double *pos2d, double *pos3d, |
||
| 9 | double dist_factor[4], double x0, double y0, double f[2], double *err ); |
||
| 10 | static void get_cpara( CALIB_COORD_T *world, CALIB_COORD_T *screen, int num, double para[3][3] ); |
||
| 11 | static int get_fl( double *p , double *q, int num, double f[2] ); |
||
| 12 | static int check_rotation( double rot[2][3] ); |
||
| 13 | |||
| 14 | int calc_inp( CALIB_PATT_T *patt, double dist_factor[4], int xsize, int ysize, double mat[3][4] ) |
||
| 15 | { |
||
| 16 | CALIB_COORD_T *screen, *sp; |
||
| 17 | double *pos2d, *pos3d, *pp; |
||
| 18 | double f[2]; |
||
| 19 | double x0, y0; |
||
| 20 | double err, minerr; |
||
| 21 | int res; |
||
| 22 | int i, j, k; |
||
| 23 | |||
| 24 | sp = screen = (CALIB_COORD_T *)malloc(sizeof(CALIB_COORD_T) * patt->h_num * patt->v_num * patt->loop_num); |
||
| 25 | pp = pos2d = (double *)malloc(sizeof(double) * patt->h_num * patt->v_num * patt->loop_num * 2); |
||
| 26 | pos3d = (double *)malloc(sizeof(double) * patt->h_num * patt->v_num * 2); |
||
| 27 | for( k = 0; k < patt->loop_num; k++ ) { |
||
| 28 | for( j = 0; j < patt->v_num; j++ ) { |
||
| 29 | for( i = 0; i < patt->h_num; i++ ) { |
||
| 30 | arParamObserv2Ideal( dist_factor, |
||
| 31 | patt->point[k][j*patt->h_num+i].x_coord, |
||
| 32 | patt->point[k][j*patt->h_num+i].y_coord, |
||
| 33 | &(sp->x_coord), &(sp->y_coord) ); |
||
| 34 | *(pp++) = sp->x_coord; |
||
| 35 | *(pp++) = sp->y_coord; |
||
| 36 | sp++; |
||
| 37 | } |
||
| 38 | } |
||
| 39 | } |
||
| 40 | pp = pos3d; |
||
| 41 | for( j = 0; j < patt->v_num; j++ ) { |
||
| 42 | for( i = 0; i < patt->h_num; i++ ) { |
||
| 43 | *(pp++) = patt->world_coord[j*patt->h_num+i].x_coord; |
||
| 44 | *(pp++) = patt->world_coord[j*patt->h_num+i].y_coord; |
||
| 45 | } |
||
| 46 | } |
||
| 47 | |||
| 48 | minerr = 100000000000000000000000.0; |
||
| 49 | for( j = -50; j <= 50; j++ ) { |
||
| 50 | printf("-- loop:%d --\n", j); |
||
| 51 | y0 = dist_factor[1] + j; |
||
| 52 | /* y0 = ysize/2 + j; */ |
||
| 53 | if( y0 < 0 || y0 >= ysize ) continue; |
||
| 54 | |||
| 55 | for( i = -50; i <= 50; i++ ) { |
||
| 56 | x0 = dist_factor[0] + i; |
||
| 57 | /* x0 = xsize/2 + i; */ |
||
| 58 | if( x0 < 0 || x0 >= xsize ) continue; |
||
| 59 | |||
| 60 | res = calc_inp2( patt, screen, pos2d, pos3d, dist_factor, x0, y0, f, &err ); |
||
| 61 | if( res < 0 ) continue; |
||
| 62 | if( err < minerr ) { |
||
| 63 | printf("F = (%f,%f), Center = (%f,%f): err = %f\n", f[0], f[1], x0, y0, err); |
||
| 64 | minerr = err; |
||
| 65 | |||
| 66 | mat[0][0] = f[0]; |
||
| 67 | mat[0][1] = 0.0; |
||
| 68 | mat[0][2] = x0; |
||
| 69 | mat[0][3] = 0.0; |
||
| 70 | mat[1][0] = 0.0; |
||
| 71 | mat[1][1] = f[1]; |
||
| 72 | mat[1][2] = y0; |
||
| 73 | mat[1][3] = 0.0; |
||
| 74 | mat[2][0] = 0.0; |
||
| 75 | mat[2][1] = 0.0; |
||
| 76 | mat[2][2] = 1.0; |
||
| 77 | mat[2][3] = 0.0; |
||
| 78 | } |
||
| 79 | } |
||
| 80 | } |
||
| 81 | |||
| 82 | free( screen ); |
||
| 83 | free( pos2d ); |
||
| 84 | free( pos3d ); |
||
| 85 | |||
| 86 | if( minerr >= 100.0 ) return -1; |
||
| 87 | return 0; |
||
| 88 | } |
||
| 89 | |||
| 90 | |||
| 91 | static int calc_inp2 ( CALIB_PATT_T *patt, CALIB_COORD_T *screen, double *pos2d, double *pos3d, |
||
| 92 | double dist_factor[4], double x0, double y0, double f[2], double *err ) |
||
| 93 | { |
||
| 94 | double x1, y1, x2, y2; |
||
| 95 | double p[LOOP_MAX], q[LOOP_MAX]; |
||
| 96 | double para[3][3]; |
||
| 97 | double rot[3][3], rot2[3][3]; |
||
| 98 | double cpara[3][4], conv[3][4]; |
||
| 99 | double ppos2d[4][2], ppos3d[4][2]; |
||
| 100 | double d, werr, werr2; |
||
| 101 | int i, j, k, l; |
||
| 102 | |||
| 103 | for( i = 0; i < patt->loop_num; i++ ) { |
||
| 104 | get_cpara( patt->world_coord, &(screen[i*patt->h_num*patt->v_num]), |
||
| 105 | patt->h_num*patt->v_num, para ); |
||
| 106 | x1 = para[0][0] / para[2][0]; |
||
| 107 | y1 = para[1][0] / para[2][0]; |
||
| 108 | x2 = para[0][1] / para[2][1]; |
||
| 109 | y2 = para[1][1] / para[2][1]; |
||
| 110 | |||
| 111 | p[i] = (x1 - x0)*(x2 - x0); |
||
| 112 | q[i] = (y1 - y0)*(y2 - y0); |
||
| 113 | } |
||
| 114 | if( get_fl(p, q, patt->loop_num, f) < 0 ) return -1; |
||
| 115 | |||
| 116 | cpara[0][0] = f[0]; |
||
| 117 | cpara[0][1] = 0.0; |
||
| 118 | cpara[0][2] = x0; |
||
| 119 | cpara[0][3] = 0.0; |
||
| 120 | cpara[1][0] = 0.0; |
||
| 121 | cpara[1][1] = f[1]; |
||
| 122 | cpara[1][2] = y0; |
||
| 123 | cpara[1][3] = 0.0; |
||
| 124 | cpara[2][0] = 0.0; |
||
| 125 | cpara[2][1] = 0.0; |
||
| 126 | cpara[2][2] = 1.0; |
||
| 127 | cpara[2][3] = 0.0; |
||
| 128 | |||
| 129 | werr = 0.0; |
||
| 130 | for( i = 0; i < patt->loop_num; i++ ) { |
||
| 131 | get_cpara( patt->world_coord, &(screen[i*patt->h_num*patt->v_num]), |
||
| 132 | patt->h_num*patt->v_num, para ); |
||
| 133 | rot[0][0] = (para[0][0] - x0*para[2][0]) / f[0]; |
||
| 134 | rot[0][1] = (para[1][0] - y0*para[2][0]) / f[1]; |
||
| 135 | rot[0][2] = para[2][0]; |
||
| 136 | d = sqrt( rot[0][0]*rot[0][0] + rot[0][1]*rot[0][1] + rot[0][2]*rot[0][2] ); |
||
| 137 | rot[0][0] /= d; |
||
| 138 | rot[0][1] /= d; |
||
| 139 | rot[0][2] /= d; |
||
| 140 | rot[1][0] = (para[0][1] - x0*para[2][1]) / f[0]; |
||
| 141 | rot[1][1] = (para[1][1] - y0*para[2][1]) / f[1]; |
||
| 142 | rot[1][2] = para[2][1]; |
||
| 143 | d = sqrt( rot[1][0]*rot[1][0] + rot[1][1]*rot[1][1] + rot[1][2]*rot[1][2] ); |
||
| 144 | rot[1][0] /= d; |
||
| 145 | rot[1][1] /= d; |
||
| 146 | rot[1][2] /= d; |
||
| 147 | check_rotation( rot ); |
||
| 148 | rot[2][0] = rot[0][1]*rot[1][2] - rot[0][2]*rot[1][1]; |
||
| 149 | rot[2][1] = rot[0][2]*rot[1][0] - rot[0][0]*rot[1][2]; |
||
| 150 | rot[2][2] = rot[0][0]*rot[1][1] - rot[0][1]*rot[1][0]; |
||
| 151 | d = sqrt( rot[2][0]*rot[2][0] + rot[2][1]*rot[2][1] + rot[2][2]*rot[2][2] ); |
||
| 152 | rot[2][0] /= d; |
||
| 153 | rot[2][1] /= d; |
||
| 154 | rot[2][2] /= d; |
||
| 155 | rot2[0][0] = rot[0][0]; |
||
| 156 | rot2[1][0] = rot[0][1]; |
||
| 157 | rot2[2][0] = rot[0][2]; |
||
| 158 | rot2[0][1] = rot[1][0]; |
||
| 159 | rot2[1][1] = rot[1][1]; |
||
| 160 | rot2[2][1] = rot[1][2]; |
||
| 161 | rot2[0][2] = rot[2][0]; |
||
| 162 | rot2[1][2] = rot[2][1]; |
||
| 163 | rot2[2][2] = rot[2][2]; |
||
| 164 | |||
| 165 | ppos2d[0][0] = pos2d[i*patt->h_num*patt->v_num*2 + 0]; |
||
| 166 | ppos2d[0][1] = pos2d[i*patt->h_num*patt->v_num*2 + 1]; |
||
| 167 | ppos2d[1][0] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num-1)*2 + 0]; |
||
| 168 | ppos2d[1][1] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num-1)*2 + 1]; |
||
| 169 | ppos2d[2][0] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num*(patt->v_num-1))*2 + 0]; |
||
| 170 | ppos2d[2][1] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num*(patt->v_num-1))*2 + 1]; |
||
| 171 | ppos2d[3][0] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num*patt->v_num-1)*2 + 0]; |
||
| 172 | ppos2d[3][1] = pos2d[i*patt->h_num*patt->v_num*2 + (patt->h_num*patt->v_num-1)*2 + 1]; |
||
| 173 | ppos3d[0][0] = pos3d[0]; |
||
| 174 | ppos3d[0][1] = pos3d[1]; |
||
| 175 | ppos3d[1][0] = pos3d[(patt->h_num-1)*2 + 0]; |
||
| 176 | ppos3d[1][1] = pos3d[(patt->h_num-1)*2 + 1]; |
||
| 177 | ppos3d[2][0] = pos3d[(patt->h_num*(patt->v_num-1))*2 + 0]; |
||
| 178 | ppos3d[2][1] = pos3d[(patt->h_num*(patt->v_num-1))*2 + 1]; |
||
| 179 | ppos3d[3][0] = pos3d[(patt->h_num*patt->v_num-1)*2 + 0]; |
||
| 180 | ppos3d[3][1] = pos3d[(patt->h_num*patt->v_num-1)*2 + 1]; |
||
| 181 | |||
| 182 | for( j = 0; j < 5; j++ ) { |
||
| 183 | arFittingMode = AR_FITTING_TO_IDEAL; |
||
| 184 | werr2 = arGetTransMat3( rot2, ppos2d, ppos3d, 4, conv, dist_factor, cpara ); |
||
| 185 | for( k = 0; k < 3; k++ ) { |
||
| 186 | for( l = 0; l < 3; l++ ) { |
||
| 187 | rot2[k][l] = conv[k][l]; |
||
| 188 | }} |
||
| 189 | } |
||
| 190 | werr += werr2; |
||
| 191 | |||
| 192 | } |
||
| 193 | *err = sqrt( werr / patt->loop_num ); |
||
| 194 | |||
| 195 | return 0; |
||
| 196 | } |
||
| 197 | |||
| 198 | static void get_cpara( CALIB_COORD_T *world, CALIB_COORD_T *screen, int num, double para[3][3] ) |
||
| 199 | { |
||
| 200 | ARMat *a, *b, *c; |
||
| 201 | ARMat *at, *aa, res; |
||
| 202 | int i; |
||
| 203 | |||
| 204 | a = arMatrixAlloc( num*2, 8 ); |
||
| 205 | b = arMatrixAlloc( num*2, 1 ); |
||
| 206 | c = arMatrixAlloc( 8, num*2 ); |
||
| 207 | at = arMatrixAlloc( 8, num*2 ); |
||
| 208 | aa = arMatrixAlloc( 8, 8 ); |
||
| 209 | for( i = 0; i < num; i++ ) { |
||
| 210 | a->m[i*16+0] = world[i].x_coord; |
||
| 211 | a->m[i*16+1] = world[i].y_coord; |
||
| 212 | a->m[i*16+2] = 1.0; |
||
| 213 | a->m[i*16+3] = 0.0; |
||
| 214 | a->m[i*16+4] = 0.0; |
||
| 215 | a->m[i*16+5] = 0.0; |
||
| 216 | a->m[i*16+6] = -world[i].x_coord * screen[i].x_coord; |
||
| 217 | a->m[i*16+7] = -world[i].y_coord * screen[i].x_coord; |
||
| 218 | a->m[i*16+8] = 0.0; |
||
| 219 | a->m[i*16+9] = 0.0; |
||
| 220 | a->m[i*16+10] = 0.0; |
||
| 221 | a->m[i*16+11] = world[i].x_coord; |
||
| 222 | a->m[i*16+12] = world[i].y_coord; |
||
| 223 | a->m[i*16+13] = 1.0; |
||
| 224 | a->m[i*16+14] = -world[i].x_coord * screen[i].y_coord; |
||
| 225 | a->m[i*16+15] = -world[i].y_coord * screen[i].y_coord; |
||
| 226 | b->m[i*2+0] = screen[i].x_coord; |
||
| 227 | b->m[i*2+1] = screen[i].y_coord; |
||
| 228 | } |
||
| 229 | arMatrixTrans( at, a ); |
||
| 230 | arMatrixMul( aa, at, a ); |
||
| 231 | arMatrixSelfInv( aa ); |
||
| 232 | arMatrixMul( c, aa, at ); |
||
| 233 | res.row = 8; |
||
| 234 | res.clm = 1; |
||
| 235 | res.m = &(para[0][0]); |
||
| 236 | arMatrixMul( &res, c, b ); |
||
| 237 | para[2][2] = 1.0; |
||
| 238 | |||
| 239 | arMatrixFree( a ); |
||
| 240 | arMatrixFree( b ); |
||
| 241 | arMatrixFree( c ); |
||
| 242 | arMatrixFree( at ); |
||
| 243 | arMatrixFree( aa ); |
||
| 244 | } |
||
| 245 | |||
| 246 | static int get_fl( double *p , double *q, int num, double f[2] ) |
||
| 247 | { |
||
| 248 | ARMat *a, *b, *c; |
||
| 249 | ARMat *at, *aa, *res; |
||
| 250 | int i; |
||
| 251 | |||
| 252 | #if 1 |
||
| 253 | a = arMatrixAlloc( num, 2 ); |
||
| 254 | b = arMatrixAlloc( num, 1 ); |
||
| 255 | c = arMatrixAlloc( 2, num ); |
||
| 256 | at = arMatrixAlloc( 2, num ); |
||
| 257 | aa = arMatrixAlloc( 2, 2 ); |
||
| 258 | res = arMatrixAlloc( 2, 1 ); |
||
| 259 | for( i = 0; i < num; i++ ) { |
||
| 260 | a->m[i*2+0] = *(p++); |
||
| 261 | a->m[i*2+1] = *(q++); |
||
| 262 | b->m[i] = -1.0; |
||
| 263 | } |
||
| 264 | #else |
||
| 265 | a = arMatrixAlloc( num-1, 2 ); |
||
| 266 | b = arMatrixAlloc( num-1, 1 ); |
||
| 267 | c = arMatrixAlloc( 2, num-1 ); |
||
| 268 | at = arMatrixAlloc( 2, num-1 ); |
||
| 269 | aa = arMatrixAlloc( 2, 2 ); |
||
| 270 | res = arMatrixAlloc( 2, 1 ); |
||
| 271 | p++; q++; |
||
| 272 | for( i = 0; i < num-1; i++ ) { |
||
| 273 | a->m[i*2+0] = *(p++); |
||
| 274 | a->m[i*2+1] = *(q++); |
||
| 275 | b->m[i] = -1.0; |
||
| 276 | } |
||
| 277 | #endif |
||
| 278 | arMatrixTrans( at, a ); |
||
| 279 | arMatrixMul( aa, at, a ); |
||
| 280 | arMatrixSelfInv( aa ); |
||
| 281 | arMatrixMul( c, aa, at ); |
||
| 282 | arMatrixMul( res, c, b ); |
||
| 283 | |||
| 284 | if( res->m[0] < 0 || res->m[1] < 0 ) return -1; |
||
| 285 | |||
| 286 | f[0] = sqrt( 1.0 / res->m[0] ); |
||
| 287 | f[1] = sqrt( 1.0 / res->m[1] ); |
||
| 288 | |||
| 289 | arMatrixFree( a ); |
||
| 290 | arMatrixFree( b ); |
||
| 291 | arMatrixFree( c ); |
||
| 292 | arMatrixFree( at ); |
||
| 293 | arMatrixFree( aa ); |
||
| 294 | arMatrixFree( res ); |
||
| 295 | |||
| 296 | return 0; |
||
| 297 | } |
||
| 298 | |||
| 299 | static int check_rotation( double rot[2][3] ) |
||
| 300 | { |
||
| 301 | double v1[3], v2[3], v3[3]; |
||
| 302 | double ca, cb, k1, k2, k3, k4; |
||
| 303 | double a, b, c, d; |
||
| 304 | double p1, q1, r1; |
||
| 305 | double p2, q2, r2; |
||
| 306 | double p3, q3, r3; |
||
| 307 | double p4, q4, r4; |
||
| 308 | double w; |
||
| 309 | double e1, e2, e3, e4; |
||
| 310 | int f; |
||
| 311 | |||
| 312 | v1[0] = rot[0][0]; |
||
| 313 | v1[1] = rot[0][1]; |
||
| 314 | v1[2] = rot[0][2]; |
||
| 315 | v2[0] = rot[1][0]; |
||
| 316 | v2[1] = rot[1][1]; |
||
| 317 | v2[2] = rot[1][2]; |
||
| 318 | v3[0] = v1[1]*v2[2] - v1[2]*v2[1]; |
||
| 319 | v3[1] = v1[2]*v2[0] - v1[0]*v2[2]; |
||
| 320 | v3[2] = v1[0]*v2[1] - v1[1]*v2[0]; |
||
| 321 | w = sqrt( v3[0]*v3[0]+v3[1]*v3[1]+v3[2]*v3[2] ); |
||
| 322 | if( w == 0.0 ) return -1; |
||
| 323 | v3[0] /= w; |
||
| 324 | v3[1] /= w; |
||
| 325 | v3[2] /= w; |
||
| 326 | |||
| 327 | cb = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; |
||
| 328 | if( cb < 0 ) cb *= -1.0; |
||
| 329 | ca = (sqrt(cb+1.0) + sqrt(1.0-cb)) * 0.5; |
||
| 330 | |||
| 331 | if( v3[1]*v1[0] - v1[1]*v3[0] != 0.0 ) { |
||
| 332 | f = 0; |
||
| 333 | } |
||
| 334 | else { |
||
| 335 | if( v3[2]*v1[0] - v1[2]*v3[0] != 0.0 ) { |
||
| 336 | w = v1[1]; v1[1] = v1[2]; v1[2] = w; |
||
| 337 | w = v3[1]; v3[1] = v3[2]; v3[2] = w; |
||
| 338 | f = 1; |
||
| 339 | } |
||
| 340 | else { |
||
| 341 | w = v1[0]; v1[0] = v1[2]; v1[2] = w; |
||
| 342 | w = v3[0]; v3[0] = v3[2]; v3[2] = w; |
||
| 343 | f = 2; |
||
| 344 | } |
||
| 345 | } |
||
| 346 | if( v3[1]*v1[0] - v1[1]*v3[0] == 0.0 ) return -1; |
||
| 347 | k1 = (v1[1]*v3[2] - v3[1]*v1[2]) / (v3[1]*v1[0] - v1[1]*v3[0]); |
||
| 348 | k2 = (v3[1] * ca) / (v3[1]*v1[0] - v1[1]*v3[0]); |
||
| 349 | k3 = (v1[0]*v3[2] - v3[0]*v1[2]) / (v3[0]*v1[1] - v1[0]*v3[1]); |
||
| 350 | k4 = (v3[0] * ca) / (v3[0]*v1[1] - v1[0]*v3[1]); |
||
| 351 | |||
| 352 | a = k1*k1 + k3*k3 + 1; |
||
| 353 | b = k1*k2 + k3*k4; |
||
| 354 | c = k2*k2 + k4*k4 - 1; |
||
| 355 | |||
| 356 | d = b*b - a*c; |
||
| 357 | if( d < 0 ) return -1; |
||
| 358 | r1 = (-b + sqrt(d))/a; |
||
| 359 | p1 = k1*r1 + k2; |
||
| 360 | q1 = k3*r1 + k4; |
||
| 361 | r2 = (-b - sqrt(d))/a; |
||
| 362 | p2 = k1*r2 + k2; |
||
| 363 | q2 = k3*r2 + k4; |
||
| 364 | if( f == 1 ) { |
||
| 365 | w = q1; q1 = r1; r1 = w; |
||
| 366 | w = q2; q2 = r2; r2 = w; |
||
| 367 | w = v1[1]; v1[1] = v1[2]; v1[2] = w; |
||
| 368 | w = v3[1]; v3[1] = v3[2]; v3[2] = w; |
||
| 369 | f = 0; |
||
| 370 | } |
||
| 371 | if( f == 2 ) { |
||
| 372 | w = p1; p1 = r1; r1 = w; |
||
| 373 | w = p2; p2 = r2; r2 = w; |
||
| 374 | w = v1[0]; v1[0] = v1[2]; v1[2] = w; |
||
| 375 | w = v3[0]; v3[0] = v3[2]; v3[2] = w; |
||
| 376 | f = 0; |
||
| 377 | } |
||
| 378 | |||
| 379 | if( v3[1]*v2[0] - v2[1]*v3[0] != 0.0 ) { |
||
| 380 | f = 0; |
||
| 381 | } |
||
| 382 | else { |
||
| 383 | if( v3[2]*v2[0] - v2[2]*v3[0] != 0.0 ) { |
||
| 384 | w = v2[1]; v2[1] = v2[2]; v2[2] = w; |
||
| 385 | w = v3[1]; v3[1] = v3[2]; v3[2] = w; |
||
| 386 | f = 1; |
||
| 387 | } |
||
| 388 | else { |
||
| 389 | w = v2[0]; v2[0] = v2[2]; v2[2] = w; |
||
| 390 | w = v3[0]; v3[0] = v3[2]; v3[2] = w; |
||
| 391 | f = 2; |
||
| 392 | } |
||
| 393 | } |
||
| 394 | if( v3[1]*v2[0] - v2[1]*v3[0] == 0.0 ) return -1; |
||
| 395 | k1 = (v2[1]*v3[2] - v3[1]*v2[2]) / (v3[1]*v2[0] - v2[1]*v3[0]); |
||
| 396 | k2 = (v3[1] * ca) / (v3[1]*v2[0] - v2[1]*v3[0]); |
||
| 397 | k3 = (v2[0]*v3[2] - v3[0]*v2[2]) / (v3[0]*v2[1] - v2[0]*v3[1]); |
||
| 398 | k4 = (v3[0] * ca) / (v3[0]*v2[1] - v2[0]*v3[1]); |
||
| 399 | |||
| 400 | a = k1*k1 + k3*k3 + 1; |
||
| 401 | b = k1*k2 + k3*k4; |
||
| 402 | c = k2*k2 + k4*k4 - 1; |
||
| 403 | |||
| 404 | d = b*b - a*c; |
||
| 405 | if( d < 0 ) return -1; |
||
| 406 | r3 = (-b + sqrt(d))/a; |
||
| 407 | p3 = k1*r3 + k2; |
||
| 408 | q3 = k3*r3 + k4; |
||
| 409 | r4 = (-b - sqrt(d))/a; |
||
| 410 | p4 = k1*r4 + k2; |
||
| 411 | q4 = k3*r4 + k4; |
||
| 412 | if( f == 1 ) { |
||
| 413 | w = q3; q3 = r3; r3 = w; |
||
| 414 | w = q4; q4 = r4; r4 = w; |
||
| 415 | w = v2[1]; v2[1] = v2[2]; v2[2] = w; |
||
| 416 | w = v3[1]; v3[1] = v3[2]; v3[2] = w; |
||
| 417 | f = 0; |
||
| 418 | } |
||
| 419 | if( f == 2 ) { |
||
| 420 | w = p3; p3 = r3; r3 = w; |
||
| 421 | w = p4; p4 = r4; r4 = w; |
||
| 422 | w = v2[0]; v2[0] = v2[2]; v2[2] = w; |
||
| 423 | w = v3[0]; v3[0] = v3[2]; v3[2] = w; |
||
| 424 | f = 0; |
||
| 425 | } |
||
| 426 | |||
| 427 | e1 = p1*p3+q1*q3+r1*r3; if( e1 < 0 ) e1 = -e1; |
||
| 428 | e2 = p1*p4+q1*q4+r1*r4; if( e2 < 0 ) e2 = -e2; |
||
| 429 | e3 = p2*p3+q2*q3+r2*r3; if( e3 < 0 ) e3 = -e3; |
||
| 430 | e4 = p2*p4+q2*q4+r2*r4; if( e4 < 0 ) e4 = -e4; |
||
| 431 | if( e1 < e2 ) { |
||
| 432 | if( e1 < e3 ) { |
||
| 433 | if( e1 < e4 ) { |
||
| 434 | rot[0][0] = p1; |
||
| 435 | rot[0][1] = q1; |
||
| 436 | rot[0][2] = r1; |
||
| 437 | rot[1][0] = p3; |
||
| 438 | rot[1][1] = q3; |
||
| 439 | rot[1][2] = r3; |
||
| 440 | } |
||
| 441 | else { |
||
| 442 | rot[0][0] = p2; |
||
| 443 | rot[0][1] = q2; |
||
| 444 | rot[0][2] = r2; |
||
| 445 | rot[1][0] = p4; |
||
| 446 | rot[1][1] = q4; |
||
| 447 | rot[1][2] = r4; |
||
| 448 | } |
||
| 449 | } |
||
| 450 | else { |
||
| 451 | if( e3 < e4 ) { |
||
| 452 | rot[0][0] = p2; |
||
| 453 | rot[0][1] = q2; |
||
| 454 | rot[0][2] = r2; |
||
| 455 | rot[1][0] = p3; |
||
| 456 | rot[1][1] = q3; |
||
| 457 | rot[1][2] = r3; |
||
| 458 | } |
||
| 459 | else { |
||
| 460 | rot[0][0] = p2; |
||
| 461 | rot[0][1] = q2; |
||
| 462 | rot[0][2] = r2; |
||
| 463 | rot[1][0] = p4; |
||
| 464 | rot[1][1] = q4; |
||
| 465 | rot[1][2] = r4; |
||
| 466 | } |
||
| 467 | } |
||
| 468 | } |
||
| 469 | else { |
||
| 470 | if( e2 < e3 ) { |
||
| 471 | if( e2 < e4 ) { |
||
| 472 | rot[0][0] = p1; |
||
| 473 | rot[0][1] = q1; |
||
| 474 | rot[0][2] = r1; |
||
| 475 | rot[1][0] = p4; |
||
| 476 | rot[1][1] = q4; |
||
| 477 | rot[1][2] = r4; |
||
| 478 | } |
||
| 479 | else { |
||
| 480 | rot[0][0] = p2; |
||
| 481 | rot[0][1] = q2; |
||
| 482 | rot[0][2] = r2; |
||
| 483 | rot[1][0] = p4; |
||
| 484 | rot[1][1] = q4; |
||
| 485 | rot[1][2] = r4; |
||
| 486 | } |
||
| 487 | } |
||
| 488 | else { |
||
| 489 | if( e3 < e4 ) { |
||
| 490 | rot[0][0] = p2; |
||
| 491 | rot[0][1] = q2; |
||
| 492 | rot[0][2] = r2; |
||
| 493 | rot[1][0] = p3; |
||
| 494 | rot[1][1] = q3; |
||
| 495 | rot[1][2] = r3; |
||
| 496 | } |
||
| 497 | else { |
||
| 498 | rot[0][0] = p2; |
||
| 499 | rot[0][1] = q2; |
||
| 500 | rot[0][2] = r2; |
||
| 501 | rot[1][0] = p4; |
||
| 502 | rot[1][1] = q4; |
||
| 503 | rot[1][2] = r4; |
||
| 504 | } |
||
| 505 | } |
||
| 506 | } |
||
| 507 | |||
| 508 | return 0; |
||
| 509 | } |