00001 #ifndef OPERATIONS_H
00002 #define OPERATIONS_H
00003
00004 #include <vector>
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <string>
00008 #include <boost/numeric/ublas/matrix.hpp>
00009 #include <boost/numeric/ublas/vector.hpp>
00010 #include <boost/numeric/ublas/io.hpp>
00011 #include <boost/numeric/ublas/lu.hpp>
00012
00013 #include "Point.h"
00014 #include "Connection.h"
00015
00016 #define verbose 1
00017
00018 inline void toCPT3(BPType& val, PType& point ) {
00019 point(0) = val(0); point(1) = val(1); point(2) = val(2);
00020 }
00021
00022 inline void toBoost3( PType& val, BPType& point ) {
00023 point(0) = val(0); point(1) = val(1); point(2) = val(2);
00024 }
00025
00026 inline void toBoost3( const PType& val, BPType& point ) {
00027 point(0) = val(0); point(1) = val(1); point(2) = val(2);
00028 }
00029
00030
00031 inline int sgn(DataType a) {
00032 if ( fabs(a) < TOL ) return 0;
00033 else if (a < 0) return -1;
00034 else if (a > 0) return 1;
00035 else { assert(0); }
00036 return -2;
00037 }
00038
00039 inline int sgn2(DataType a) {
00040 if (a < 0) return -1;
00041 if (a >= 0) return 1;
00042 }
00043
00044 inline DataType norm_2(PType val) {
00045 DataType result;
00046 BPType boostTmp(3,0.);
00047 toBoost3(val,boostTmp);
00048
00049 result = boost::numeric::ublas::norm_2(boostTmp);
00050 return result;
00051 }
00052
00057 BPType normalize( BPType& a ) {
00058 BPType result(a);
00059
00060 if (norm_2(a) > TOL ) result /= norm_2(a);
00061 else result.resize(a.size(),0.);
00062
00063 return result;
00064 }
00065
00066 PType normalize( PType& a ) {
00067 PType result(a);
00068 BPType boostTmp(3,0);
00069 toBoost3(result,boostTmp);
00070 boostTmp = normalize(boostTmp);
00071 toCPT3(boostTmp,result);
00072 return result;
00073 }
00074
00079 inline int octant(BPType a) {
00080 if (sgn(a(0)) >= 0 && sgn(a(1)) >= 0 && sgn(a(2)) >= 0 ) { return 0; }
00081 else if (sgn(a(0)) <= 0 && sgn(a(1)) >= 0 && sgn(a(2)) >= 0 ) { return 1; }
00082 else if (sgn(a(0)) <= 0 && sgn(a(1)) <= 0 && sgn(a(2)) >= 0 ) { return 2; }
00083 else if (sgn(a(0)) >= 0 && sgn(a(1)) <= 0 && sgn(a(2)) >= 0 ) { return 3; }
00084 else if (sgn(a(0)) >= 0 && sgn(a(1)) >= 0 && sgn(a(2)) <= 0 ) { return 4; }
00085 else if (sgn(a(0)) <= 0 && sgn(a(1)) >= 0 && sgn(a(2)) <= 0 ) { return 5; }
00086 else if (sgn(a(0)) <= 0 && sgn(a(1)) <= 0 && sgn(a(2)) <= 0 ) { return 6; }
00087 else if (sgn(a(0)) >= 0 && sgn(a(1)) <= 0 && sgn(a(2)) <= 0 ) { return 7; }
00088 }
00089
00090 inline int octant(PType a) {
00091 BPType boostTmp(3,0);
00092 toBoost3(a,boostTmp);
00093 return octant(boostTmp);
00094 }
00095
00100 inline int octant(BPType a, BPType b) {
00101 if (sgn(a(0)) == sgn(b(0)) || sgn(a(0)) == 0 || sgn(b(0)) == 0 ) {
00102 if (sgn(a(1)) == sgn(b(1)) || sgn(a(1)) == 0 || sgn(b(1)) == 0 ) {
00103 if (sgn(a(2)) == sgn(b(2)) || sgn(a(2)) == 0 || sgn(b(2)) == 0 )
00104 return 1;
00105 }
00106 }
00107 return 0;
00108 }
00109
00110 inline int octant(PType a, PType b) {
00111 BPType Ba(3,0), Bb(3,0.);
00112 toBoost3(a,Ba);
00113 toBoost3(b,Bb);
00114 return octant(Ba,Bb);
00115 }
00116
00117 inline int octant2(BPType a, BPType b) {
00118 if (sgn(a(0)) == sgn(b(0)) || sgn(a(0)) == 0 || sgn(b(0)) == 0 ) {
00119 if (sgn(a(1)) == sgn(b(1)) || sgn(a(1)) == 0 || sgn(b(1)) == 0 ) {
00120 if (sgn(a(2)) == sgn(b(2)) || sgn(a(2)) == 0 || sgn(b(2)) == 0 )
00121 return 1;
00122 }
00123 }
00124 return 0;
00125 }
00126
00127 inline int octant2(PType a, PType b) {
00128 BPType Ba(3,0), Bb(3,0.);
00129 toBoost3(a,Ba);
00130 toBoost3(b,Bb);
00131 return octant2(Ba,Bb);
00132 }
00133
00138 BPType sin3D( BPType& a ) {
00139 BPType result(a);
00140
00141 result(0) = std::sin(a(0));
00142 result(1) = std::sin(a(1));
00143 result(2) = std::sin(a(2));
00144
00145 return result;
00146 }
00147
00152 BPType multElem( BPType& a, BPType& b) {
00153 BPType result(3,0.);
00154
00155 result(0) = a(0)*b(0);
00156 result(1) = a(1)*b(1);
00157 result(2) = a(2)*b(2);
00158
00159 return result;
00160 }
00161
00166 DataType innerProd3D(BPType& a, BPType& b) {
00167 DataType result = 0.;
00168
00169 result = a(0)*b(0) + a(1)*b(1) + a(2)*b(2);
00170
00171 return result;
00172 }
00173
00174 DataType innerProd3D(PType& a, PType& b) {
00175 DataType result = 0.;
00176
00177 result = a(0)*b(0) + a(1)*b(1) + a(2)*b(2);
00178
00179 return result;
00180 }
00181
00182 DataType innerProd3D(PType a, PType b) {
00183 DataType result = 0.;
00184
00185 result = a(0)*b(0) + a(1)*b(1) + a(2)*b(2);
00186
00187 return result;
00188 }
00189
00194 DataType cross( BPType& a, BPType& b) {
00195 PType result;
00196
00197 result(0) = a(1)*b(2) - a(2)*b(1);
00198 result(1) = a(2)*b(0) - a(0)*b(2);
00199
00200 return norm_2(result);
00201 }
00202
00207 BPType cross3D(BPType& a, BPType& b) {
00208 BPType result(3,0.);
00209
00210 result(0) = a(1)*b(2) - a(2)*b(1);
00211 result(1) = a(2)*b(0) - a(0)*b(2);
00212 result(2) = a(0)*b(1) - a(1)*b(0);
00213
00214 return result;
00215 }
00216
00217 PType cross3D(PType& a, PType& b) {
00218 PType result;
00219
00220 result(0) = a(1)*b(2) - a(2)*b(1);
00221 result(1) = a(2)*b(0) - a(0)*b(2);
00222 result(2) = a(0)*b(1) - a(1)*b(0);
00223
00224 return result;
00225 }
00226
00231 BPType cross3D(BPType& a, BPType& b, int& par) {
00232 BPType result(3,0.);
00233
00234 result(0) = a(1)*b(2) - a(2)*b(1);
00235 result(1) = a(2)*b(0) - a(0)*b(2);
00236 result(2) = a(0)*b(1) - a(1)*b(0);
00237
00238 par = 0;
00239
00240 if ( norm_2(result) < TOL ) {
00241 if (octant(a,b) == 1 ) {
00242 par = 1;
00243 }
00244 else {
00245 par = -1;
00246 }
00247 }
00248
00249 return result;
00250 }
00251
00252
00253 PType cross3D(PType& a, PType& b, int& par) {
00254 PType result;
00255 BPType tmp(3,0.);
00256
00257 result(0) = a(1)*b(2) - a(2)*b(1);
00258 result(1) = a(2)*b(0) - a(0)*b(2);
00259 result(2) = a(0)*b(1) - a(1)*b(0);
00260
00261 par = 0;
00262
00263 toBoost3(result,tmp);
00264 if ( norm_2(tmp) < TOL ) {
00265 if (octant(a,b) == 1 ) {
00266 par = 1;
00267 }
00268 else {
00269 par = -1;
00270 }
00271 }
00272
00273 return result;
00274 }
00275
00284 DataType angle3D_axis( BPType a, BPType b, BPType n) {
00285
00286 BPType c(3,0.), d(3,0.);
00287 DataType theta;
00288
00289 a = normalize(a);
00290 b = normalize(b);
00291 n = normalize(n);
00292
00293
00294
00295 if ( norm_2(a - n) < TOL || norm_2(b - n) < TOL ) {
00296 theta = 0.;
00297 return theta;
00298 }
00299
00300 c = a - n * inner_prod(a,n);
00301 d = b - n * inner_prod(b,n);
00302
00303 theta = std::acos( inner_prod(c,d) / ( norm_2(c)*norm_2(d) ) )/d2r;
00304
00305
00306
00307 return theta;
00308 }
00309
00310 DataType angle3D_axis( PType a, PType b, PType n) {
00311 BPType Ba(3,0), Bb(3,0),Bn(3,0);
00312 toBoost3(a,Ba);
00313 toBoost3(b,Bb);
00314 toBoost3(n,Bn);
00315 return angle3D_axis(Ba,Bb,Bn);
00316 }
00317
00326 DataType angle3D2_axis( BPType a, BPType b, BPType n) {
00327
00328 BPType c(3,0.), d(3,0.), ntmp(3,0.);
00329 DataType theta;
00330
00331 a = normalize(a);
00332 b = normalize(b);
00333 n = normalize(n);
00334
00335 if ( norm_2(a - n) < TOL ||
00336 norm_2(b - n) < TOL ||
00337 norm_2(a + n) < TOL ||
00338 norm_2(b + n) < TOL ||
00339 norm_2(a - b) < TOL ||
00340 norm_2(a + b) < TOL ) {
00341 theta = 0.;
00342 return theta;
00343 }
00344
00345 c = a - n * inner_prod(a,n);
00346 d = b - n * inner_prod(b,n);
00347
00348 theta = std::acos( inner_prod(c,d) / ( norm_2(c)*norm_2(d) ) )/d2r;
00349
00350 ntmp = cross3D(c,d);
00351
00352 if ( octant(n,ntmp) == 0 ) {
00353 theta *= -1.;
00354 }
00355
00356 return theta;
00357 }
00358
00359 DataType angle3D2_axis( PType a, PType b, PType n) {
00360 BPType Ba(3,0), Bb(3,0),Bn(3,0);
00361 toBoost3(a,Ba);
00362 toBoost3(b,Bb);
00363 toBoost3(n,Bn);
00364 return angle3D2_axis(Ba,Bb,Bn);
00365 }
00366
00367 DataType angle3D3_axis( BPType a, BPType b, BPType n, int& flip) {
00368
00369 BPType c(3,0.), d(3,0.), ntmp(3,0.);
00370 DataType theta;
00371
00372 a = normalize(a);
00373 b = normalize(b);
00374 n = normalize(n);
00375
00376
00377
00378 if ( norm_2(a - n) < TOL ||
00379 norm_2(b - n) < TOL ||
00380 norm_2(a + n) < TOL ||
00381 norm_2(b + n) < TOL ||
00382 norm_2(a - b) < TOL ||
00383 norm_2(a + b) < TOL ) {
00384 theta = 0.;
00385 return theta;
00386 }
00387
00388 c = a - n * inner_prod(a,n);
00389 d = b - n * inner_prod(b,n);
00390
00391 theta = std::acos( inner_prod(c,d) / ( norm_2(c)*norm_2(d) ) )/d2r;
00392
00393 ntmp = cross3D(a,b);
00394
00395
00396
00397 if ( inner_prod(n,ntmp) > 0 ) {
00398 ( mklog() << "FLIP!!!!!!!!!\t" ).flush();
00399 flip = 1;
00400 theta *= -1.;
00401 }
00402 else {
00403 flip = 0;
00404 }
00405
00406
00407
00408 return theta;
00409 }
00410
00411 DataType angle3D3_axis( PType a, PType b, PType n, int& f) {
00412 BPType Ba(3,0), Bb(3,0),Bn(3,0);
00413 toBoost3(a,Ba);
00414 toBoost3(b,Bb);
00415 toBoost3(n,Bn);
00416 return angle3D3_axis(Ba,Bb,Bn,f);
00417 }
00418
00423 BPType rotate3D( BPType& u, BPType& theta) {
00424 BPType result(3,0.), utmp(4,1.), rtmp(4,1.);
00425 MType m(4,4,0.);
00426 m(0,0) = 1.; m(1,1) = 1.; m(2,2) = 1.; m(3,3) = 1.;
00427
00428 theta *= d2r;
00429
00430 DataType ct1 = std::cos(theta(2));
00431 DataType ct2 = std::cos(theta(0));
00432 DataType ct3 = std::cos(theta(1));
00433 DataType st1 = std::sin(theta(2));
00434 DataType st2 = std::sin(theta(0));
00435 DataType st3 = std::sin(theta(1));
00436
00437 m(0,0) = (ct3*ct1 + st3*st2*st1 );
00438 m(0,1) = (-ct3*st1 + st3*st2*ct1 );
00439 m(0,2) = (st3*ct2 );
00440 m(1,0) = (ct2*st1 );
00441 m(1,1) = (ct2*ct1 );
00442 m(1,2) = (-st2 );
00443 m(2,0) = (-st3*ct1 + ct3*st2*st1 );
00444 m(2,1) = (st3*st1 + ct3*st2*ct1 );
00445 m(2,2) = (ct3*ct2 );
00446
00447 utmp(0) = u(0); utmp(1) = u(1); utmp(2) = u(2);
00448 rtmp = prod(m,utmp);
00449 result(0) = rtmp(0); result(1) = rtmp(1); result(2) = rtmp(2);
00450
00451 return result;
00452 }
00453
00458 bool InvertMatrix(const MType& input, MType& inverse)
00459 {
00460 typedef boost::numeric::ublas::permutation_matrix<std::size_t> pmatrix;
00461 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00462
00463
00464 MType A(input);
00465
00466
00467 pmatrix pm(A.size1());
00468
00469
00470 int res = 1.;
00471 res = boost::numeric::ublas::lu_factorize(A, pm);
00472
00473 if (res != 0)
00474 return false;
00475
00476
00477 inverse.assign(imatrix (A.size1()));
00478
00479
00480 boost::numeric::ublas::lu_substitute(A, pm, inverse);
00481
00482 return true;
00483 }
00484
00489 DataType determinant3(const MType& A) {
00490
00491 return ( A(0,0)*A(1,1)*A(2,2) + A(0,2)*A(1,2)*A(2,0) + A(0,2)*A(1,0)*A(2,1)
00492 - A(0,2)*A(1,1)*A(2,0) - A(0,1)*A(1,0)*A(2,2) - A(0,0)*A(1,2)*A(2,1) );
00493 }
00494
00495
00501 BPType pointFinM( BPType p, MType A) {
00502 BPType point(3,0.), dtemp(4,1.), ptemp(4,1.);
00503 MType Atransp(A);
00504
00505 dtemp(0) = A(0,3); dtemp(1) = A(1,3); dtemp(2) = A(2,3);
00506 Atransp(0,3) = 0.;
00507 Atransp(1,3) = 0.;
00508 Atransp(2,3) = 0.;
00509 Atransp = boost::numeric::ublas::trans(Atransp);
00510
00511 dtemp = DataType(-1.)*boost::numeric::ublas::prod(Atransp,dtemp);
00512
00513 Atransp(0,3) = dtemp(0);
00514 Atransp(1,3) = dtemp(1);
00515 Atransp(2,3) = dtemp(2);
00516
00517 ptemp(0) = p(0); ptemp(1) = p(1); ptemp(2) = p(2);
00518 ptemp = boost::numeric::ublas::prod(Atransp,ptemp);
00519
00520 point(0) = ptemp(0); point(1) = ptemp(1); point(2) = ptemp(2);
00521
00522 return point;
00523 }
00524
00530 MType FinM( MType A) {
00531 BPType dtemp(4,1.);
00532 MType Atransp(A);
00533
00534 dtemp(0) = A(0,3); dtemp(1) = A(1,3); dtemp(2) = A(2,3);
00535 Atransp(0,3) = 0.;
00536 Atransp(1,3) = 0.;
00537 Atransp(2,3) = 0.;
00538 Atransp = boost::numeric::ublas::trans(Atransp);
00539
00540 dtemp = DataType(-1.)*boost::numeric::ublas::prod(Atransp,dtemp);
00541
00542 Atransp(0,3) = dtemp(0);
00543 Atransp(1,3) = dtemp(1);
00544 Atransp(2,3) = dtemp(2);
00545
00546 return Atransp;
00547 }
00548
00553 MType tranMat3D( BPType move ) {
00554 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00555 MType m(4,4);
00556
00557 m.assign(imatrix (4));
00558 m(0,3) = move(0);
00559 m(1,3) = move(1);
00560 m(2,3) = move(2);
00561
00562 return m;
00563 }
00564
00565 MType tranMat3D( PType move ) {
00566 BPType Bmove(3,0.);
00567 toBoost3(move,Bmove);
00568 MType m(4,4);
00569 m = tranMat3D(Bmove);
00570
00571 return m;
00572 }
00573
00578 MType scalMat3D( BPType scale ) {
00579 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00580 MType m(4,4);
00581
00582 m.assign(imatrix (4));
00583
00584 m(0,0) = scale(0);
00585 m(1,1) = scale(1);
00586 m(2,2) = scale(2);
00587
00588 return m;
00589 }
00590
00591 MType scalMat3D( PType scale ) {
00592 BPType Bscale(3,0.);
00593 toBoost3(scale,Bscale);
00594 return scalMat3D(Bscale);
00595 }
00596
00601 MType rotMat3D( BPType theta ) {
00602 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00603 MType m(4,4);
00604
00605 m.assign(imatrix (4));
00606 DataType ct1 = std::cos(theta(2)*d2r);
00607 DataType ct2 = std::cos(theta(0)*d2r);
00608 DataType ct3 = std::cos(theta(1)*d2r);
00609 DataType st1 = std::sin(theta(2)*d2r);
00610 DataType st2 = std::sin(theta(0)*d2r);
00611 DataType st3 = std::sin(theta(1)*d2r);
00612
00613 m(0,0) = (ct3*ct1 + st3*st2*st1 );
00614 m(0,1) = (-ct3*st1 + st3*st2*ct1 );
00615 m(0,2) = (st3*ct2 );
00616 m(1,0) = (ct2*st1 );
00617 m(1,1) = (ct2*ct1 );
00618 m(1,2) = (-st2 );
00619 m(2,0) = (-st3*ct1 + ct3*st2*st1 );
00620 m(2,1) = (st3*st1 + ct3*st2*ct1 );
00621 m(2,2) = (ct3*ct2 );
00622
00623 return m;
00624 }
00625
00626 MType rotMat3D( PType theta ) {
00627 BPType Btheta(3,0.);
00628 toBoost3(theta,Btheta);
00629 return rotMat3D(Btheta);
00630 }
00631
00636 MType axisAngleMat3D( BPType axis, DataType angle ) {
00637 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00638 MType m(3,3);
00639 DataType ct, st, ct1;
00640
00641 ct = std::cos(angle);
00642 st = std::sin(angle);
00643 ct1 = DataType(1.) - std::cos(angle);
00644
00645 m.assign(imatrix (3));
00646 m(0,0) = ct1*axis(0)*axis(0) + ct;
00647 m(0,1) = ct1*axis(0)*axis(1) - axis(2)*st;
00648 m(0,2) = ct1*axis(0)*axis(2) + axis(1)*st;
00649
00650 m(1,0) = ct1*axis(1)*axis(0) + axis(2)*st;
00651 m(1,1) = ct1*axis(1)*axis(1) + ct;
00652 m(1,2) = ct1*axis(1)*axis(2) - axis(0)*st;
00653
00654 m(2,0) = ct1*axis(2)*axis(0) - axis(2)*st;
00655 m(2,1) = ct1*axis(2)*axis(1) + axis(1)*st;
00656 m(2,2) = ct1*axis(2)*axis(2) + ct;
00657
00658 return m;
00659 }
00660
00661 MType axisAngleMat3D( PType axis, DataType angle ) {
00662 BPType tmp(3,0.);
00663 toBoost3(axis,tmp);
00664 return axisAngleMat3D(tmp,angle);
00665 }
00666
00671 MType axisAngleMat3DH( BPType axis, DataType angle ) {
00672 typedef boost::numeric::ublas::identity_matrix<std::size_t> imatrix;
00673 MType m(4,4);
00674 DataType ct, st, ct1;
00675
00676 ct = std::cos(angle*d2r);
00677 st = std::sin(angle*d2r);
00678 ct1 = DataType(1.) - std::cos(angle*d2r);
00679
00680 m.assign(imatrix (4));
00681 m(0,0) = ct1*axis(0)*axis(0) + ct;
00682 m(0,1) = ct1*axis(0)*axis(1) - axis(2)*st;
00683 m(0,2) = ct1*axis(0)*axis(2) + axis(1)*st;
00684
00685 m(1,0) = ct1*axis(1)*axis(0) + axis(2)*st;
00686 m(1,1) = ct1*axis(1)*axis(1) + ct;
00687 m(1,2) = ct1*axis(1)*axis(2) - axis(0)*st;
00688
00689 m(2,0) = ct1*axis(2)*axis(0) - axis(1)*st;
00690 m(2,1) = ct1*axis(2)*axis(1) + axis(0)*st;
00691 m(2,2) = ct1*axis(2)*axis(2) + ct;
00692
00693 return m;
00694 }
00695
00696 MType axisAngleMat3DH( PType axis, DataType angle ) {
00697 BPType tmp(3,0.);
00698 toBoost3(axis,tmp);
00699 return axisAngleMat3DH(tmp,angle);
00700 }
00701
00706 BPType matTaitBryant( MType A) {
00707 BPType rotation(3,0.);
00708
00709 if ( ( std::fabs(A(2,0)) - DataType(1.) ) < TOL ) {
00710 rotation(1) = std::asin( -A(2,0) )/d2r;
00711 if ( rotation(1) < DataType(90.) ) {
00712 rotation(0) = std::atan2( A(2,1), A(2,2) )/d2r;
00713 rotation(2) = std::atan2( A(1,0), A(0,0) )/d2r;
00714 }
00715 else {
00716 rotation(0) = std::atan2( -A(2,1), -A(2,2) )/d2r;
00717 rotation(2) = std::atan2( -A(1,0), -A(0,0) )/d2r;
00718 }
00719 }
00720 else if ( ( A(2,0) + DataType(1.) ) < TOL ) {
00721 rotation(0) = std::atan2( A(0,1), A(0,2) )/d2r;
00722 rotation(1) = DataType(90.);
00723 rotation(2) = 0.;
00724 }
00725 else if ( ( A(2,0) - DataType(1.) ) < TOL ) {
00726 rotation(0) = std::atan2( -A(0,1), -A(0,2) )/d2r;
00727 rotation(1) = DataType(-90.);
00728 rotation(2) = 0.;
00729 }
00730
00731 return rotation;
00732 }
00733
00757 BPType angle3D2( BPType& u, BPType& v) {
00758 MType rmat(4,4);
00759 BPType utmp(u), vtmp(v), result(3,0.);
00760 BPType ntmp(3,0.);
00761 DataType atmp;
00762
00763 int par;
00764
00765
00766
00767 ntmp = cross3D(u,v,par);
00768 ntmp = normalize(ntmp);
00769
00770
00771
00773 if ( par == 0 ) {
00774 atmp = angle3D_axis(u,v,ntmp);
00775 rmat = axisAngleMat3DH(ntmp,atmp);
00776 result = matTaitBryant(rmat);
00777 ( mklog() << " angle3D2 called on intersecting lines result (deg)=" << result << std::endl ).flush();
00778 return result;
00779 }
00781 else if ( par == 1 ) {
00782 ( mklog() << " angle3D2 called on parallel lines result (deg)=" << result << std::endl ).flush();
00783 return result;
00784 }
00786 else if ( par == -1 ) {
00787 ntmp(0) = 1.; ntmp(1) = 0.; ntmp(2) = 0.;
00788 if ( boost::numeric::ublas::norm_2(u - ntmp) < TOL || boost::numeric::ublas::norm_2(v - ntmp) < TOL ) {
00789 ntmp(0) = ((DataType)rand()/(DataType)RAND_MAX);
00790 ntmp(1) = ((DataType)rand()/(DataType)RAND_MAX);
00791 ntmp(2) = ((DataType)rand()/(DataType)RAND_MAX);
00792 ntmp = normalize(ntmp);
00793 ( mklog() << " ntmp " << ntmp << std::endl ).flush();
00794 }
00795 atmp = angle3D_axis(u,v,ntmp);
00796 rmat = axisAngleMat3DH(ntmp,atmp);
00797 result = matTaitBryant(rmat);
00798 ( mklog() << " angle3D2 called on anti-parallel lines result (deg)=" << result << std::endl ).flush();
00799 return result;
00800 }
00801 else { assert(0); }
00802 return (BPType) 0;
00803 }
00804
00818 void dist3D_Line_to_Line( BPType L0P0, BPType L0P1, BPType L1P0, BPType L1P1, BPType& L0I, BPType& L1I, BPType& CN, DataType& dist, int& lcase)
00819 {
00820 BPType u(3,0.), v(3,0.), w(3,0.), dP(3,0.);
00821 DataType a, b, c, d, e, D, sc, tc;
00822 u = L0P1 - L0P0;
00823 v = L1P1 - L1P0;
00824 w = L0P0 - L1P0;
00825 a = boost::numeric::ublas::inner_prod(u,u);
00826 b = boost::numeric::ublas::inner_prod(u,v);
00827 c = boost::numeric::ublas::inner_prod(v,v);
00828 d = boost::numeric::ublas::inner_prod(u,w);
00829 e = boost::numeric::ublas::inner_prod(v,w);
00830 D = a*c - b*b;
00831
00833 if (D < TOL) {
00834 sc = 0.0;
00835 tc = (b>c ? d/b : e/c);
00836 }
00837 else {
00838 sc = (b*e - c*d) / D;
00839 tc = (a*e - b*d) / D;
00840 }
00841
00843 dP = w + (sc * u) - (tc * v);
00844 CN = normalize(dP);
00845
00846 L0I = L0P0 + (sc * u);
00847 L1I = L1P0 + (tc * v);
00848
00849 dist = boost::numeric::ublas::norm_2(dP);
00850
00852 if (norm_2(CN) < TOL && dist < TOL && norm_2(L0P0-L0I) < TOL && norm_2(L0P0-L1I) < TOL) {
00853 lcase = 2;
00854 }
00855 else if (norm_2(L0P0-L0I) < TOL && dist > TOL) {
00856 lcase = 1;
00857 }
00858 else if (norm_2(CN) < TOL && dist < TOL) {
00859 lcase = 0;
00860 }
00861 else if (norm_2(CN) > TOL && dist > TOL) {
00862 lcase = 3;
00863 }
00864 }
00865
00866 void dist3D_Line_to_Line( PType L0P0, PType L0P1, PType L1P0, PType L1P1, PType& L0I,
00867 PType& L1I, PType& CN, DataType& dist, int& lcase) {
00868 BPType BL0P0(3,0.), BL0P1(3,0.), BL1P0(3,0.), BL1P1(3,0.), BL0I(3,0.), BL1I(3,0.), BCN(3,0.);
00869 toBoost3(L0P0,BL0P0);
00870 toBoost3(L0P1,BL0P1);
00871 toBoost3(L1P0,BL1P0);
00872 toBoost3(L1P1,BL1P1);
00873 toBoost3(L0I,BL0I);
00874 toBoost3(L1I,BL1I);
00875 toBoost3(CN,BCN);
00876 dist3D_Line_to_Line(BL0P0,BL0P1,BL1P0,BL1P1,BL0I,BL1I,BCN,dist,lcase);
00877
00878 }
00879
00884 BPType project( BPType& u, BPType& v ) {
00885 BPType result(3,0.);
00886 MType Pv(3,3);
00887
00888 Pv.assign(imatrix(3));
00889 Pv(0,0) = v(0)*v(0);
00890 Pv(0,1) = v(0)*v(1);
00891 Pv(0,2) = v(0)*v(2);
00892
00893 Pv(1,0) = v(0)*v(1);
00894 Pv(1,1) = v(1)*v(1);
00895 Pv(1,2) = v(1)*v(2);
00896
00897 Pv(2,0) = v(0)*v(2);
00898 Pv(2,1) = v(1)*v(2);
00899 Pv(2,2) = v(2)*v(2);
00900
00901 result = prod(Pv,u);
00902
00903 return result;
00904
00905 }
00906
00907 PType project( PType& u, PType& v ) {
00908 BPType Bu(3,0.), Bv(3,0.), result(3,0.);
00909 PType answer;
00910 toBoost3(u,Bu);
00911 toBoost3(v,Bv);
00912 result = project(Bu,Bv);
00913 toCPT3(result,answer);
00914 return answer;
00915
00916 }
00917
00918 DataType projectScalar( BPType& u, BPType& v ) {
00919 DataType result;
00920 result = inner_prod(u,v)/norm_2(v);
00921 return result;
00922 }
00923
00924 DataType projectScalar( PType& u, PType& v ) {
00925 BPType Bu(3,0.), Bv(3,0.);
00926 DataType answer;
00927 toBoost3(u,Bu);
00928 toBoost3(v,Bv);
00929 answer = projectScalar(Bu,Bv);
00930 return answer;
00931 }
00932
00933 DataType distance_point_to_line3D(BPType a, BPType b, BPType p) {
00934 DataType dist = -1., length;
00935 BPType n(3,0.), v(3,0), w(3,0.);
00936 n = b - a;
00937 n = normalize(n);
00938 v = a - p;
00939 w = p - a;
00940
00941 length = boost::numeric::ublas::norm_2( (a-b) );
00942 dist = boost::numeric::ublas::norm_2( (a-p)-( boost::numeric::ublas::inner_prod((a-p),n) )*n );
00943
00944 if ( projectScalar(w,n) > length ) {
00945 dist = -1;
00946 }
00947 else if ( projectScalar(w,n) < 0 ) {
00948 dist = -1;
00949 }
00950
00951 return dist;
00952 }
00953
00954 DataType distance_point_to_line3D(PType a, PType b, PType p) {
00955 BPType Ba(3,0.), Bb(3,0.), Bp(3,0.);
00956 DataType answer;
00957 toBoost3(a,Ba);
00958 toBoost3(b,Bb);
00959 toBoost3(p,Bp);
00960 answer = distance_point_to_line3D(Ba,Bb,Bp);
00961 return answer;
00962 }
00963
00972 MType DenavitHartenbergMat( DataType radius, DataType alpha, DataType depth, DataType theta ) {
00973 MType DH(4,4);
00974 DataType ca, sa, ct, st;
00975
00976 ca = std::cos(alpha*d2r);
00977 sa = std::sin(alpha*d2r);
00978 ct = std::cos(theta*d2r);
00979 st = std::sin(theta*d2r);
00980
00981 DH(0,0) = ct;
00982 DH(0,1) = -st*ca;
00983 DH(0,2) = st*sa;
00984 DH(0,3) = radius*ct;
00985
00986 DH(1,0) = st;
00987 DH(1,1) = ct*ca;
00988 DH(1,2) = -ct*sa;
00989 DH(1,3) = radius*st;
00990
00991 DH(2,0) = 0.;
00992 DH(2,1) = sa;
00993 DH(2,2) = ca;
00994 DH(2,3) = depth;
00995
00996 DH(3,0) = 0.;
00997 DH(3,1) = 0.;
00998 DH(3,2) = 0.;
00999 DH(3,3) = 1.;
01000
01001 return DH;
01002 }
01003
01005 MType DenavitHartenbergMat_spericalWrist( DataType t4, DataType t5, DataType t6, DataType d6 ) {
01006 MType DH(4,4);
01007 DataType ct4, st4, ct5, st5, st6, ct6;
01008
01009 ct4 = std::cos(t4*d2r);
01010 st4 = std::sin(t4*d2r);
01011 ct5 = std::cos(t5*d2r);
01012 st5 = std::sin(t5*d2r);
01013 ct6 = std::cos(t6*d2r);
01014 st6 = std::sin(t6*d2r);
01015
01016 DH(0,0) = ct4*ct5*ct6 - st4*st6;
01017 DH(0,1) = -ct4*ct5*st6 - st4*ct6;
01018 DH(0,2) = ct4*st5;
01019 DH(0,3) = ct4*st5*d6;
01020
01021 DH(1,0) = st4*ct5*ct6 + ct4*st6;
01022 DH(1,1) = -st4*ct5*st6 + ct4*ct6;
01023 DH(1,2) = st4*st5;
01024 DH(1,3) = st4*st5*d6;
01025
01026 DH(2,0) = -st5*ct6;
01027 DH(2,1) = st5*st6;
01028 DH(2,2) = ct5;
01029 DH(2,3) = ct5*d6;
01030
01031 DH(3,0) = 0.;
01032 DH(3,1) = 0.;
01033 DH(3,2) = 0.;
01034 DH(3,3) = 1.;
01035
01036 return DH;
01037 }
01038
01039 void prodMVP( MType Tnet, std::vector<BPType>& in, std::vector<BPType>& out) {
01040 BPType v(in[0].size()+1,1.);
01041 out.resize(in.size());
01042 for (unsigned int i = 0; i < in.size(); i++) {
01043 v(0) = in[i](0); v(1) = in[i](1); v(2) = in[i](2);
01044 v = prod(Tnet, v);
01045 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01046 }
01047 }
01048
01049 void prodMVP( MType Tnet, std::vector<PType>& in, std::vector<PType>& out) {
01050 BPType v(in[0].size()+1,1.);
01051 out.resize(in.size());
01052 for (unsigned int i = 0; i < in.size(); i++) {
01053 v(0) = in[i](0); v(1) = in[i](1); v(2) = in[i](2);
01054 v = prod(Tnet, v);
01055 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01056 }
01057 }
01058
01059 BPType prodMP( MType Tnet, BPType in) {
01060 BPType v(in.size()+1,1.), result(3,0.);
01061 v(0) = in(0); v(1) = in(1); v(2) = in(2);
01062 v = prod(Tnet, v);
01063 result(0) = v(0); result(1) = v(1); result(2) = v(2);
01064 return result;
01065 }
01066
01067 PType prodMP( MType Tnet, PType in) {
01068 BPType v(in.size()+1,1.), tmp(3,0.);
01069 PType answer;
01070 v(0) = in(0); v(1) = in(1); v(2) = in(2);
01071 v = prod(Tnet, v);
01072 tmp(0) = v(0); tmp(1) = v(1); tmp(2) = v(2);
01073 toCPT3(tmp,answer);
01074 return answer;
01075 }
01076
01077 MType SkewSymmetric( BPType alpha ) {
01078 MType SS(4,4);
01079
01080 SS(0,0) = 0.;
01081 SS(0,1) = -alpha(2);
01082 SS(0,2) = alpha(1);
01083 SS(0,3) = 0.;
01084
01085 SS(1,0) = alpha(2);
01086 SS(1,1) = 0.;
01087 SS(1,2) = -alpha(0);
01088 SS(1,3) = 0.;
01089
01090 SS(2,0) = -alpha(1);
01091 SS(2,1) = alpha(0);
01092 SS(2,2) = 0.;
01093 SS(2,3) = 0.;
01094
01095 SS(3,0) = 0.;
01096 SS(3,1) = 0.;
01097 SS(3,2) = 0.;
01098 SS(3,3) = 1.;
01099
01100 return SS;
01101 }
01102
01103 void calcVelMVP( MType Tnet, std::vector<BPType>& origins, std::vector<BPType>& axis, std::vector<BPType>& angVel, std::vector<BPType>& linVel, std::vector<BPType>& in, std::vector<BPType>& out) {
01104 BPType v(in[0].size()+1,1.);
01105 out.resize(in.size());
01106
01107 MType skew(4,4);
01108 BPType rtmp(4,0.);
01109 for (unsigned int i = 0; i < in.size(); i++) {
01110
01111 v.resize(4,0.);
01112 for (unsigned int j = 0; j < angVel.size(); j++ ) {
01113 rtmp(0) = in[i](0) - angVel[j](0); rtmp(1) = in[i](1) - angVel[j](1); rtmp(2) = in[i](2) - angVel[j](2);
01114 skew = SkewSymmetric(angVel[j]);
01115 v = v + prod(skew,rtmp) + linVel[j];
01116 }
01117 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01118 }
01119 }
01120
01121 void numVelMVP( MType Tnet0, MType Tnet1, std::vector<BPType>& in, std::vector<BPType>& out, DataType dt) {
01122 BPType v(in[0].size()+1,1.);
01123 out.clear();
01124 std::copy (in.begin (), in.end (), std::back_inserter (out));
01125
01126 MType vtmp(4,4);
01127
01128 vtmp = (Tnet1 - Tnet0)*(DataType(1.)/dt);
01129 vtmp(3,3) = 1.;
01130 for (unsigned int i = 0; i < in.size(); i++) {
01131 v(0) = in[i](0); v(1) = in[i](1); v(2) = in[i](2);
01132 v = prod(vtmp,v);
01133 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01134 }
01135 }
01136
01137 void numVelMVP( MType Tnet0, MType Tnet1, std::vector<PType>& in, std::vector<PType>& out, DataType dt) {
01138 BPType v(in[0].size()+1,1.);
01139 out.clear();
01140 std::copy (in.begin (), in.end (), std::back_inserter (out));
01141
01142 MType mtmp(4,4);
01143
01144 mtmp = (Tnet1 - Tnet0)*(DataType(1.)/dt);
01145 mtmp(3,3) = 1.;
01146 for (unsigned int i = 0; i < in.size(); i++) {
01147 v(0) = in[i](0); v(1) = in[i](1); v(2) = in[i](2);
01148 v = prod(mtmp,v);
01149 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01150 }
01151 }
01152
01153 void printID(std::vector<int> tag) {
01154 for (unsigned int i = 0; i < tag.size(); i++) {
01155 ( mklog() << tag[i] ).flush();
01156 if (i < tag.size()-1) ( mklog() << ":" ).flush();
01157 }
01158 ( mklog() << std::endl ).flush();
01159 }
01160
01161 std::string stringID(std::vector<int> tag) {
01162 std::string id;
01163 for (unsigned int i = 0; i < tag.size(); i++) {
01164 std::stringstream ss;
01165 ss << tag[i];
01166 id += ss.str();
01167 if (i < tag.size()-1) id += ":";
01168 }
01169 return id;
01170 }
01171
01172 void trimID(std::vector<int> &tag) {
01173 for (int i = tag.size()-1; i > 0; i--) {
01174 if (tag[i-1] == -1) {
01175 tag.pop_back();
01176 }
01177 else {
01178 if (tag[i-1] < 0) tag.pop_back();
01179 ( mklog() << "\nDone Trimming Id Tag\n" ).flush();
01180 }
01181 }
01182 printID(tag);
01183 ( mklog() << std::endl ).flush();
01184 }
01185
01186 int checkTag(std::vector<int> tag) {
01187 int type;
01188 if ( tag[tag.size()-1] < 0 ) {
01189 type = 0;
01190 }
01191 else {
01192 type = 1;
01193 }
01194 return type;
01195 }
01196
01197 void assignVertices3D(const std::vector<BPType>& in, ads::FixedArray<3,DataType> * out) {
01198 ( mklog() << " assigning Points\n" ).flush();
01199 typedef ads::FixedArray<3,DataType> point_type;
01200
01201 point_type* piter = out;
01202 for (unsigned int i = 0; i < in.size(); i++) {
01203 piter[0] = in[i][0]; piter[1] = in[i][1]; piter[2] = in[i][2];
01204 piter++;
01205 }
01206 }
01207
01208 void assignConnections3D(std::vector<Facet<DataType> >& in, ads::FixedArray<3,int> * out) {
01209 ( mklog() << " assigning Conections\n" ).flush();
01210 typedef ads::FixedArray<3,int> multi_index_type;
01211 multi_index_type* citer = out;
01212 for (unsigned int i = 0; i < in.size(); i++) {
01213 citer[0] = in[i].getNthCon(0); citer[1] = in[i].getNthCon(1); citer[2] = in[i].getNthCon(2);
01214 citer++;
01215 }
01216
01217 }
01218
01219 PType intersection_line2facet(PType I_a, PType I_b, int& nump, int& numc, ads::FixedArray<3,DataType> * verts, ads::FixedArray<3,int> * conns , int& flag) {
01220 PType intPt;
01221
01222 PType p_0, p_1, p_2;
01223 MType X(3,3), Xinv(3,3);
01224 PType tuv(-1.), delta;
01225 DataType detCheck=0., distance=0., dtmp=0., r=20.0;
01226
01227 ( mklog() << " : I_a= " << I_a << " I_b= " << I_b << " nump = " << nump
01228 << " numc = " << numc << std::endl ).flush();
01229
01230 for ( register int j = 0; j < numc; j++ ) {
01231
01232 p_0 = verts[ conns[j](0) ];
01233 p_1 = verts[ conns[j](1) ];
01234 p_2 = verts[ conns[j](2) ];
01235
01236 r = norm_2(p_0-p_1);
01237 if ( r > norm_2(p_0-p_2) ) r = norm_2(p_0-p_2);
01238 if ( r > norm_2(p_1-p_2) ) r = norm_2(p_1-p_2);
01239
01240
01241 distance = distance_point_to_line3D(I_a, I_b, p_0);
01242 dtmp = distance_point_to_line3D(I_a, I_b, p_1);
01243 if (dtmp < distance) distance = dtmp;
01244 dtmp = distance_point_to_line3D(I_a, I_b, p_2);
01245 if (dtmp < distance) distance = dtmp;
01246
01247 if ( distance >= 0. && distance <= r ) {
01248 ( mklog() << " distance " << distance << " r = " << r << std::endl ).flush();
01249
01250 X(0,0) = ( I_a(0) - I_b(0) ); X(0,1) = ( p_1(0) - p_0(0) ); X(0,2) = ( p_2(0) - p_0(0) );
01251 X(1,0) = ( I_a(1) - I_b(1) ); X(1,1) = ( p_1(1) - p_0(1) ); X(1,2) = ( p_2(1) - p_0(1) );
01252 X(2,0) = ( I_a(2) - I_b(2) ); X(2,1) = ( p_1(2) - p_0(2) ); X(2,2) = ( p_2(2) - p_0(2) );
01253
01254 delta(0) = ( I_a(0) - p_0(0) );
01255 delta(1) = ( I_a(1) - p_0(1) );
01256 delta(2) = ( I_a(2) - p_0(2) );
01257
01258 detCheck = determinant3(X);
01259
01260 if (detCheck > TOL) {
01261
01262 if (InvertMatrix(X,Xinv)) {
01263 ( mklog() << " detCheck == " << detCheck << std::endl ).flush();
01264 InvertMatrix(X,Xinv);
01265 BPType boostTmp(3,0.);
01266 toBoost3(delta,boostTmp);
01267 boostTmp = prod(Xinv,boostTmp);
01268 toCPT3(boostTmp,tuv);
01269
01270 }
01271 else {
01272 ( mklog() << "InvertMatrix false\n" ).flush();
01273 tuv(0) = 3.; tuv(1) = 3.; tuv(2) = 3.;
01274
01275 }
01276 }
01277 ( mklog() << " norm_2(tuv) = " << norm_2(tuv) << " tuv " << tuv << std::endl
01278 << " p_0 " << p_0
01279 << " p_1 " << p_1
01280 << " p_2 " << p_2 << std::endl ).flush();
01281 if (norm_2(tuv) <= 2) {
01282 if (tuv(0) >= 0. && tuv(0) <= 1. ) {
01283 if (tuv(1) >= 0. && tuv(1) <= 1. ) {
01284 if (fabs(tuv(2)) <=1 ) {
01285 if ( (tuv(1)+tuv(2)) <= 1. ) {
01286 ( mklog() << "==== tuv" << tuv << std::endl
01287 << " ````` flagging facetB[" << j << "]\n"
01288 << " INTERSECTION = " << tuv(0)*( I_b - I_a ) + I_a
01289 << std::endl ).flush();
01290 intPt = tuv(0)*( I_b - I_a ) + I_a;
01291
01292 ( mklog() << " facetPtB->getNthCon(0) " << conns[j](0)
01293 << " facetPtB->getNthCon(1) " << conns[j](1)
01294 << " facetPtB->getNthCon(2) " << conns[j](2) << std::endl
01295 << " p_0 " << p_0
01296 << " p_1 " << p_1
01297 << " p_2 " << p_2 << std::endl ).flush();
01298 flag = 1;
01299 return intPt;
01300 }
01301 }
01302 }
01303 }
01304 }
01305 }
01306 }
01307
01308 flag = 0;
01309 return intPt;
01310 }
01311
01313 void reflect(std::vector<PType>& in, std::vector<PType>& out, PType n ) {
01314 MType ref(4,4);
01315 DataType a = n(0), b = n(1), c = n(2);
01316
01317 BPType v(in[0].size()+1,1.);
01318 out.clear();
01319 out.resize(in.size());\
01320
01321 ref(0,0) = 1. - 2.*a*a;
01322 ref(0,1) = -2.*a*b;
01323 ref(0,2) = -2.*a*c;
01324 ref(0,3) = 0.;
01325
01326 ref(1,0) = -2.*a*b;
01327 ref(1,1) = 1. - 2.*b*b;
01328 ref(1,2) = -2*b*c;
01329 ref(1,3) = 0.;
01330
01331 ref(2,0) = -2*a*c;
01332 ref(2,1) = -2*b*c;
01333 ref(2,2) = 1-2*c*c;
01334 ref(2,3) = 0.;
01335
01336 ref(3,0) = 0.;
01337 ref(3,1) = 0.;
01338 ref(3,2) = 0.;
01339 ref(3,3) = 1.;
01340
01341 ( mklog() << " REFLECTION MATRIX " << ref << std::endl ).flush();
01342
01343 for (unsigned int i = 0; i < in.size(); i++) {
01344 v(0) = in[i](0); v(1) = in[i](1); v(2) = in[i](2);
01345 v = prod(ref,v);
01346 out[i](0) = v(0); out[i](1) = v(1); out[i](2) = v(2);
01347 }
01348
01349 }
01350
01355 MType reflMat3D( BPType n ) {
01356 MType ref(4,4);
01357 DataType a = n(0), b = n(1), c = n(2);
01358
01359 ref(0,0) = 1. - 2.*a*a;
01360 ref(0,1) = -2.*a*b;
01361 ref(0,2) = -2.*a*c;
01362 ref(0,3) = 0.;
01363
01364 ref(1,0) = -2.*a*b;
01365 ref(1,1) = 1. - 2.*b*b;
01366 ref(1,2) = -2*b*c;
01367 ref(1,3) = 0.;
01368
01369 ref(2,0) = -2*a*c;
01370 ref(2,1) = -2*b*c;
01371 ref(2,2) = 1.-2*c*c;
01372 ref(2,3) = 0.;
01373
01374 ref(3,0) = 0.;
01375 ref(3,1) = 0.;
01376 ref(3,2) = 0.;
01377 ref(3,3) = 1.;
01378
01379 ( mklog() << "reflection matrix " << ref << std::endl ).flush();
01380
01381 return ref;
01382 }
01383
01384 MType reflMat3D( PType n ) {
01385 BPType Bn(3,0.);
01386 toBoost3(n,Bn);
01387 return reflMat3D(Bn);
01388 }
01389
01390 bool fexists(const char *filename)
01391 {
01392 std::ifstream ifile(filename);
01393 return ifile;
01394 }
01395
01396 #endif // OPERATIONS_H