00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "TriTensor.h"
00009
00010 #include <vcl_iostream.h>
00011 #include <vcl_cmath.h>
00012 #include <vcl_cassert.h>
00013 #include <vcl_vector.h>
00014
00015 #include <vul/vul_printf.h>
00016
00017 #include <vnl/vnl_matrix.h>
00018 #include <vnl/vnl_matlab_print.h>
00019 #include <vnl/vnl_double_3.h>
00020 #include <vnl/vnl_double_3x3.h>
00021 #include <vnl/vnl_identity_3x3.h>
00022 #include <vnl/vnl_cross_product_matrix.h>
00023 #include <vnl/algo/vnl_svd.h>
00024 #include <vnl/vnl_inverse.h>
00025
00026 #include <vgl/vgl_homg_point_2d.h>
00027 #include <vgl/vgl_homg_line_2d.h>
00028 #include <vgl/algo/vgl_h_matrix_2d.h>
00029 #include <vgl/algo/vgl_homg_operators_2d.h>
00030
00031 #include <mvl/HomgLine2D.h>
00032 #include <mvl/HomgPoint2D.h>
00033 #include <mvl/HMatrix2D.h>
00034 #include <mvl/FMatrix.h>
00035 #include <mvl/PMatrix.h>
00036 #include <mvl/PMatrixDecompAa.h>
00037 #include <mvl/HMatrix3D.h>
00038 #include <mvl/HomgOperator2D.h>
00039 #include <mvl/FManifoldProject.h>
00040
00041 struct OuterProduct3x3 : public vnl_double_3x3
00042 {
00043 OuterProduct3x3(vnl_double_3 const& a, vnl_double_3 const& b)
00044 {
00045 for (int i = 0; i < 3; ++i)
00046 for (int j = 0; j < 3; ++j)
00047 put(i,j, a[i] * b[j]);
00048 }
00049 };
00050
00051 static bool tt_verbose = false;
00052
00053 #define MUTABLE_CAST(slot) (((TriTensor*)this)->slot) // const violation ...
00054
00055
00056
00057
00058
00059 TriTensor::TriTensor()
00060 : T(3, 3, 3), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00061 {
00062 }
00063
00064
00065
00066
00067
00068 TriTensor::TriTensor(const double *tritensor_array)
00069 : T(3, 3, 3, tritensor_array), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00070 {
00071 }
00072
00073
00074 TriTensor::TriTensor(const TriTensor& that)
00075 : T(that.T), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00076 {
00077 }
00078
00079
00080 TriTensor::TriTensor(PMatrix const& P1,
00081 PMatrix const& P2,
00082 PMatrix const& P3)
00083 : T(3, 3, 3), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00084 {
00085 set(P1, P2, P3);
00086 }
00087
00088
00089 TriTensor::TriTensor(PMatrix const& P2,
00090 PMatrix const& P3)
00091 : T(3, 3, 3), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00092 {
00093 set(P2, P3);
00094 }
00095
00096
00097 TriTensor::TriTensor(vnl_matrix<double> const& T1,
00098 vnl_matrix<double> const& T2,
00099 vnl_matrix<double> const& T3)
00100 : T(3, 3, 3), e12_(0), e13_(0), fmp12_(0), fmp13_(0), fmp23_(0)
00101 {
00102 set(T1, T2, T3);
00103 }
00104
00105
00106 TriTensor& TriTensor::operator=(const TriTensor& that)
00107 {
00108 T = that.T;
00109 delete_caches();
00110
00111 return *this;
00112 }
00113
00114
00115 TriTensor::~TriTensor()
00116 {
00117 delete_caches();
00118 }
00119
00120
00121 void TriTensor::delete_caches() const
00122 {
00123 delete e12_; e12_ = 0;
00124 delete e13_; e13_ = 0;
00125 delete fmp12_; fmp12_ = 0;
00126 delete fmp13_; fmp13_ = 0;
00127 delete fmp23_; fmp23_ = 0;
00128 }
00129
00130
00131 void TriTensor::convert_to_vector(vnl_matrix<double> * out) const
00132 {
00133
00134 assert(out-> rows() == 27 && out-> columns() == 1);
00135 T.get(out->data_block());
00136 }
00137
00138
00139 void TriTensor::set(const vnl_matrix<double>& in)
00140 {
00141 assert(in.rows() == 27 && in.columns() == 1);
00142 T.set(in.data_block());
00143 delete_caches();
00144 }
00145
00146
00147
00148
00149 void
00150 TriTensor::set(const PMatrix& P1, const PMatrix& P2, const PMatrix& P3)
00151 {
00152 PMatrixDecompAa p2;
00153 PMatrixDecompAa p3;
00154
00155 bool canon1 = P1.is_canonical(1e-12);
00156 if (canon1) {
00157 p2.set(P2);
00158 p3.set(P3);
00159 }
00160 else {
00161 HMatrix3D H = P1.get_canonical_H();
00162 p2.set(P2 * H);
00163 p3.set(P3 * H);
00164 }
00165
00166 for (int i = 0; i < 3; ++i)
00167 for (int j = 0; j < 3; ++j)
00168 for (int k = 0; k < 3; ++k)
00169 T(i,j,k) = p2.A(j,i) * p3.a[k] - p3.A(k,i) * p2.a[j];
00170 delete_caches();
00171 }
00172
00173
00174
00175 void
00176 TriTensor::set(const PMatrix& P2, const PMatrix& P3)
00177 {
00178 PMatrixDecompAa p2;
00179 PMatrixDecompAa p3;
00180
00181 p2.set(P2);
00182 p3.set(P3);
00183
00184 for (int i = 0; i < 3; ++i)
00185 for (int j = 0; j < 3; ++j)
00186 for (int k = 0; k < 3; ++k)
00187 T(i,j,k) = p2.A(j,i) * p3.a[k] - p3.A(k,i) * p2.a[j];
00188
00189 delete_caches();
00190 }
00191
00192
00193 void
00194 TriTensor::set(vnl_matrix<double> const& T1,
00195 vnl_matrix<double> const& T2,
00196 vnl_matrix<double> const& T3)
00197 {
00198 vcl_cerr << "TriTensor: construct from 3 T-matrices: Unimplemented\n";
00199 vnl_matrix<double> const* Ts[3];
00200 Ts[0] = &T1;
00201 Ts[1] = &T2;
00202 Ts[2] = &T3;
00203
00204 for (int i = 0; i < 3; ++i) {
00205 const vnl_matrix<double>& Ti = *Ts[i];
00206 for (int j = 0; j < 3; ++j)
00207 for (int k = 0; k < 3; ++k)
00208 T(i,j,k) = Ti(j,k);
00209 }
00210 delete_caches();
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 HomgPoint2D
00222 TriTensor::image3_transfer(HomgPoint2D const& point1,
00223 HomgPoint2D const& point2,
00224 HomgPoint2D corrected[]) const
00225 {
00226 HomgPoint2D corr[2];
00227 if (!corrected) corrected = corr;
00228 get_fmp12()->correct(point1, point2, &corrected[0], &corrected[1]);
00229
00230 vcl_vector<HomgLine2D> constraint_lines(9);
00231 get_constraint_lines_image3(corrected[0], corrected[1], &constraint_lines);
00232 return HomgOperator2D::lines_to_point(constraint_lines);
00233 }
00234
00235
00236
00237
00238
00239
00240 HomgPoint2D
00241 TriTensor::image2_transfer(HomgPoint2D const& point1,
00242 HomgPoint2D const& point3,
00243 HomgPoint2D corrected[]) const
00244 {
00245 HomgPoint2D corr[2];
00246 if (!corrected) corrected = corr;
00247 get_fmp13()->correct(point1, point3, &corrected[0], &corrected[1]);
00248
00249 vcl_vector<HomgLine2D> constraint_lines(9);
00250 get_constraint_lines_image2(corrected[0], corrected[1], &constraint_lines);
00251 return HomgOperator2D::lines_to_point(constraint_lines);
00252 }
00253
00254
00255
00256
00257
00258
00259 vgl_homg_point_2d<double>
00260 TriTensor::image1_transfer(vgl_homg_point_2d<double> const& point2,
00261 vgl_homg_point_2d<double> const& point3,
00262 vgl_homg_point_2d<double> corrected[]) const
00263 {
00264 vgl_homg_point_2d<double> corr[2];
00265 if (!corrected) corrected = corr;
00266 get_fmp23()->correct(point2, point3, corrected[0], corrected[1]);
00267
00268 vcl_vector<vgl_homg_line_2d<double> > constraint_lines(9);
00269 get_constraint_lines_image1(corrected[0], corrected[1], constraint_lines);
00270 return vgl_homg_operators_2d<double>::lines_to_point(constraint_lines);
00271 }
00272
00273 HomgPoint2D
00274 TriTensor::image1_transfer(HomgPoint2D const& point2,
00275 HomgPoint2D const& point3,
00276 HomgPoint2D corrected[]) const
00277 {
00278 HomgPoint2D corr[2];
00279 if (!corrected) corrected = corr;
00280 get_fmp23()->correct(point2, point3, &corrected[0], &corrected[1]);
00281
00282 vcl_vector<HomgLine2D> constraint_lines(9);
00283 get_constraint_lines_image1(corrected[0], corrected[1], &constraint_lines);
00284 return HomgOperator2D::lines_to_point(constraint_lines);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294 vgl_homg_point_2d<double>
00295 TriTensor::image3_transfer_qd(vgl_homg_point_2d<double> const& point1,
00296 vgl_homg_point_2d<double> const& point2) const
00297 {
00298
00299 vcl_vector<vgl_homg_line_2d<double> > constraint_lines(9);
00300 get_constraint_lines_image3(point1, point2, constraint_lines);
00301 return vgl_homg_operators_2d<double>::lines_to_point(constraint_lines);
00302 }
00303
00304 HomgPoint2D
00305 TriTensor::image3_transfer_qd(HomgPoint2D const& point1,
00306 HomgPoint2D const& point2) const
00307 {
00308
00309 vcl_vector<HomgLine2D> constraint_lines(9);
00310 get_constraint_lines_image3(point1, point2, &constraint_lines);
00311 return HomgOperator2D::lines_to_point(constraint_lines);
00312 }
00313
00314
00315
00316
00317
00318
00319 vgl_homg_point_2d<double>
00320 TriTensor::image2_transfer_qd(vgl_homg_point_2d<double> const& point1,
00321 vgl_homg_point_2d<double> const& point3) const
00322 {
00323 vcl_vector<vgl_homg_line_2d<double> > constraint_lines(9);
00324 get_constraint_lines_image2(point1, point3, constraint_lines);
00325 return vgl_homg_operators_2d<double>::lines_to_point(constraint_lines);
00326 }
00327
00328 HomgPoint2D
00329 TriTensor::image2_transfer_qd(HomgPoint2D const& point1,
00330 HomgPoint2D const& point3) const
00331 {
00332 vcl_vector<HomgLine2D> constraint_lines(9);
00333 get_constraint_lines_image2(point1, point3, &constraint_lines);
00334 return HomgOperator2D::lines_to_point(constraint_lines);
00335 }
00336
00337
00338
00339
00340
00341
00342 vgl_homg_point_2d<double>
00343 TriTensor::image1_transfer_qd(vgl_homg_point_2d<double> const& point2,
00344 vgl_homg_point_2d<double> const& point3) const
00345 {
00346 vcl_vector<vgl_homg_line_2d<double> > constraint_lines(9);
00347 get_constraint_lines_image1(point2, point3, constraint_lines);
00348 return vgl_homg_operators_2d<double>::lines_to_point(constraint_lines);
00349 }
00350
00351 HomgPoint2D
00352 TriTensor::image1_transfer_qd(HomgPoint2D const& point2,
00353 HomgPoint2D const& point3) const
00354 {
00355 vcl_vector<HomgLine2D> constraint_lines(9);
00356 get_constraint_lines_image1(point2, point3, &constraint_lines);
00357 return HomgOperator2D::lines_to_point(constraint_lines);
00358 }
00359
00360
00361
00362
00363
00364
00365 vgl_homg_line_2d<double>
00366 TriTensor::image1_transfer(vgl_homg_line_2d<double> const& line2,
00367 vgl_homg_line_2d<double> const& line3) const
00368 {
00369 vnl_double_3 l1(0.0,0.0,0.0);
00370 vnl_double_3 l2(line2.a(),line2.b(),line2.c());
00371 vnl_double_3 l3(line3.a(),line3.b(),line3.c());
00372
00373 for (int i = 0; i < 3; i++)
00374 for (int j = 0; j < 3; j++)
00375 for (int k = 0; k < 3; k++)
00376 l1 [i] += T(i,j,k) * l2 [j] * l3 [k];
00377
00378 return vgl_homg_line_2d<double>(l1[0],l1[1],l1[2]);
00379 }
00380
00381 HomgLine2D
00382 TriTensor::image1_transfer(HomgLine2D const& line2,
00383 HomgLine2D const& line3) const
00384 {
00385 vnl_double_3 l1(0,0,0);
00386 const vnl_vector<double>& l2 = line2.get_vector().as_ref();
00387 const vnl_vector<double>& l3 = line3.get_vector().as_ref();
00388
00389 for (int i = 0; i < 3; i++)
00390 for (int j = 0; j < 3; j++)
00391 for (int k = 0; k < 3; k++)
00392 l1 [i] += T(i,j,k) * l2 [j] * l3 [k];
00393
00394 return HomgLine2D(l1);
00395 }
00396
00397
00398
00399
00400
00401
00402 vgl_homg_line_2d<double>
00403 TriTensor::image2_transfer(vgl_homg_line_2d<double> const& line1,
00404 vgl_homg_line_2d<double> const& line3) const
00405 {
00406 vnl_double_3 l1(line1.a(),line1.b(),line1.c());
00407 vnl_double_3 l3(line3.a(),line3.b(),line3.c());
00408 vnl_double_3 l = vnl_inverse(dot3(l3)) * l1;
00409 return vgl_homg_line_2d<double>(l[0],l[1],l[2]);
00410 }
00411
00412 HomgLine2D
00413 TriTensor::image2_transfer(HomgLine2D const& line1,
00414 HomgLine2D const& line3) const
00415 {
00416 return HomgLine2D(vnl_inverse(dot3(line3.get_vector().as_ref())) * line1.get_vector());
00417 }
00418
00419
00420
00421
00422
00423
00424 vgl_homg_line_2d<double>
00425 TriTensor::image3_transfer(vgl_homg_line_2d<double> const& line1,
00426 vgl_homg_line_2d<double> const& line2) const
00427 {
00428 vnl_double_3 l1(line1.a(),line1.b(),line1.c());
00429 vnl_double_3 l2(line2.a(),line2.b(),line2.c());
00430 vnl_double_3 l = vnl_inverse(dot2(l2)) * l1;
00431 return vgl_homg_line_2d<double>(l[0],l[1],l[2]);
00432 }
00433
00434 HomgLine2D
00435 TriTensor::image3_transfer(HomgLine2D const& line1,
00436 HomgLine2D const& line2) const
00437 {
00438 return HomgLine2D(vnl_inverse(dot2(line2.get_vector().as_ref())) * line1.get_vector());
00439 }
00440
00441
00442
00443
00444 vgl_h_matrix_2d<double> TriTensor::get_hmatrix_31(vgl_homg_line_2d<double> const& line2) const
00445 {
00446 vnl_double_3 l2(line2.a(),line2.b(),line2.c());
00447 return vgl_h_matrix_2d<double>(dot2(l2));
00448 }
00449
00450 HMatrix2D TriTensor::get_hmatrix_31(const HomgLine2D& line2) const
00451 {
00452 return HMatrix2D(dot2(line2.get_vector().as_ref()));
00453 }
00454
00455
00456 vgl_h_matrix_2d<double> TriTensor::get_hmatrix_21(vgl_homg_line_2d<double> const& line3) const
00457 {
00458 vnl_double_3 l3(line3.a(),line3.b(),line3.c());
00459 return vgl_h_matrix_2d<double>(dot3(l3));
00460 }
00461
00462 HMatrix2D TriTensor::get_hmatrix_21(const HomgLine2D& line3) const
00463 {
00464 return HMatrix2D(dot3(line3.get_vector().as_ref()));
00465 }
00466
00467
00468
00469
00470 vnl_double_3x3 TriTensor::dot1(const vnl_double_3& v) const
00471 {
00472 vnl_double_3x3 answer; answer.fill(0.0);
00473 for (int i = 0; i < 3; i++)
00474 for (int j = 0; j < 3; j++)
00475 for (int k = 0; k < 3; k++)
00476 answer(j,k) += v[i] * T(i,j,k);
00477 return answer;
00478 }
00479
00480
00481 vnl_double_3x3 TriTensor::dot2(const vnl_double_3& v) const
00482 {
00483 vnl_double_3x3 answer; answer.fill(0.0);
00484 for (int i = 0; i < 3; i++)
00485 for (int j = 0; j < 3; j++)
00486 for (int k = 0; k < 3; k++)
00487 answer(i,k) += v[j] * T(i,j,k);
00488 return answer;
00489 }
00490
00491
00492 vnl_double_3x3 TriTensor::dot3(const vnl_double_3& v) const
00493 {
00494 vnl_double_3x3 answer; answer.fill(0.0);
00495 for (int i = 0; i < 3; i++)
00496 for (int j = 0; j < 3; j++)
00497 for (int k = 0; k < 3; k++)
00498 answer(i,j) += v[k] * T(i,j,k);
00499 return answer;
00500 }
00501
00502
00503 vnl_double_3x3 TriTensor::dot1t(const vnl_double_3& v) const
00504 {
00505 vnl_double_3x3 answer; answer.fill(0.0);
00506 for (int i = 0; i < 3; i++)
00507 for (int j = 0; j < 3; j++)
00508 for (int k = 0; k < 3; k++)
00509 answer(k,j) += v[i] * T(i,j,k);
00510 return answer;
00511 }
00512
00513
00514 vnl_double_3x3 TriTensor::dot2t(const vnl_double_3& v) const
00515 {
00516 vnl_double_3x3 answer; answer.fill(0.0);
00517 for (int i = 0; i < 3; i++)
00518 for (int j = 0; j < 3; j++)
00519 for (int k = 0; k < 3; k++)
00520 answer(k,i) += v[j] * T(i,j,k);
00521 return answer;
00522 }
00523
00524
00525 vnl_double_3x3 TriTensor::dot3t(const vnl_double_3& v) const
00526 {
00527 vnl_double_3x3 answer; answer.fill(0.0);
00528 for (int i = 0; i < 3; i++)
00529 for (int j = 0; j < 3; j++)
00530 for (int k = 0; k < 3; k++)
00531 answer(j,i) += v[k] * T(i,j,k);
00532 return answer;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 TriTensor TriTensor::postmultiply(unsigned tensor_axis, const vnl_matrix<double>& M) const
00544 {
00545 switch (tensor_axis) {
00546 case 1: return postmultiply1(M);
00547 case 2: return postmultiply2(M);
00548 case 3: return postmultiply3(M);
00549 default:
00550 assert(tensor_axis <= 3);
00551 return *this;
00552 }
00553 }
00554
00555
00556
00557
00558
00559
00560
00561 TriTensor TriTensor::premultiply(unsigned tensor_axis, const vnl_matrix<double>& M) const
00562 {
00563 switch (tensor_axis) {
00564 case 1: return premultiply1(M);
00565 case 2: return premultiply2(M);
00566 case 3: return premultiply3(M);
00567 default:
00568 assert(tensor_axis <= 3);
00569 return *this;
00570 }
00571 }
00572
00573
00574 TriTensor TriTensor::postmultiply1(const vnl_matrix<double>& M) const
00575 {
00576 TriTensor S;
00577 for (int i = 0; i < 3; ++i)
00578 for (int j = 0; j < 3; ++j)
00579 for (int k = 0; k < 3; ++k) {
00580 double v = 0;
00581 for (int p = 0; p < 3; ++p)
00582 v += T(p,j,k) * M(p,i);
00583 S(i,j,k) = v;
00584 }
00585 return S;
00586 }
00587
00588
00589 TriTensor TriTensor::postmultiply2(const vnl_matrix<double>& M) const
00590 {
00591 TriTensor S;
00592 for (int i = 0; i < 3; ++i)
00593 for (int j = 0; j < 3; ++j)
00594 for (int k = 0; k < 3; ++k) {
00595 double v = 0;
00596 for (int p = 0; p < 3; ++p)
00597 v += T(i,p,k) * M(p,j);
00598 S(i,j,k) = v;
00599 }
00600 return S;
00601 }
00602
00603
00604 TriTensor TriTensor::postmultiply3(const vnl_matrix<double>& M) const
00605 {
00606 TriTensor S;
00607 for (int i = 0; i < 3; ++i)
00608 for (int j = 0; j < 3; ++j)
00609 for (int k = 0; k < 3; ++k) {
00610 double v = 0;
00611 for (int p = 0; p < 3; ++p)
00612 v += T(i,j,p) * M(p,k);
00613 S(i,j,k) = v;
00614 }
00615 return S;
00616 }
00617
00618
00619 TriTensor TriTensor::premultiply1(const vnl_matrix<double>& M) const
00620 {
00621 TriTensor S;
00622 for (int i = 0; i < 3; ++i)
00623 for (int j = 0; j < 3; ++j)
00624 for (int k = 0; k < 3; ++k) {
00625 double v = 0;
00626 for (int p = 0; p < 3; ++p)
00627 v += M(i,p) * T(p,j,k);
00628 S(i,j,k) = v;
00629 }
00630 return S;
00631 }
00632
00633
00634 TriTensor TriTensor::premultiply2(const vnl_matrix<double>& M) const
00635 {
00636 TriTensor S;
00637 for (int i = 0; i < 3; ++i)
00638 for (int j = 0; j < 3; ++j)
00639 for (int k = 0; k < 3; ++k) {
00640 double v = 0;
00641 for (int p = 0; p < 3; ++p)
00642 v += M(j,p) * T(i,p,k);
00643 S(i,j,k) = v;
00644 }
00645 return S;
00646 }
00647
00648
00649 TriTensor TriTensor::premultiply3(const vnl_matrix<double>& M) const
00650 {
00651 TriTensor S;
00652 for (int i = 0; i < 3; ++i)
00653 for (int j = 0; j < 3; ++j)
00654 for (int k = 0; k < 3; ++k) {
00655 double v = 0;
00656 for (int p = 0; p < 3; ++p)
00657 v += M(k,p) * T(i,j,p);
00658 S(i,j,k) = v;
00659 }
00660 return S;
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 TriTensor TriTensor::condition(vnl_matrix<double> const& line_1_denorm,
00677 vnl_matrix<double> const& line_2_norm,
00678 vnl_matrix<double> const& line_3_norm) const
00679 {
00680 return premultiply1(line_1_denorm).postmultiply2(line_2_norm).postmultiply3(line_3_norm);
00681 }
00682
00683 TriTensor TriTensor::decondition(vnl_matrix<double> const& line_1_norm,
00684 vnl_matrix<double> const& line_2_denorm,
00685 vnl_matrix<double> const& line_3_denorm) const
00686 {
00687 return premultiply1(line_1_norm).postmultiply2(line_2_denorm).postmultiply3(line_3_denorm);
00688 }
00689
00690
00691
00692 void TriTensor::get_constraint_lines_image3(vgl_homg_point_2d<double> const& p1,
00693 vgl_homg_point_2d<double> const& p2,
00694 vcl_vector<vgl_homg_line_2d<double> >& lines) const
00695 {
00696
00697 double x1 = p1.x();
00698 double y1 = p1.y();
00699 double z1 = p1.w();
00700
00701 double x2 = p2.x();
00702 double y2 = p2.y();
00703 double z2 = p2.w();
00704
00705 lines.clear();
00706
00707
00708 {
00709 double lx =
00710 -x1 * x2 * T(0,1,1) + x1 * y2 * T(0,0,1)
00711 -y1 * x2 * T(1,1,1) + y1 * y2 * T(1,0,1)
00712 -z1 * x2 * T(2,1,1) + z1 * y2 * T(2,0,1);
00713
00714 double ly =
00715 x1 * x2 * T(0,1,0) - x1 * y2 * T(0,0,0) +
00716 y1 * x2 * T(1,1,0) - y1 * y2 * T(1,0,0) +
00717 z1 * x2 * T(2,1,0) - z1 * y2 * T(2,0,0);
00718
00719 double lz = 0;
00720 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00721 }
00722
00723
00724 {
00725 double lx =
00726 -x1 * x2 * T(0,1,2) + x1 * y2 * T(0,0,2)
00727 - y1 * x2 * T(1,1,2) + y1 * y2 * T(1,0,2)
00728 - z1 * x2 * T(2,1,2) + z1 * y2 * T(2,0,2);
00729
00730 double ly = 0;
00731
00732 double lz
00733 = x1 * x2 * T(0,1,0) - x1 * y2 * T(0,0,0)
00734 + y1 * x2 * T(1,1,0) - y1 * y2 * T(1,0,0)
00735 + z1 * x2 * T(2,1,0) - z1 * y2 * T(2,0,0);
00736
00737 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00738 }
00739
00740
00741 {
00742 double lx =
00743 0;
00744
00745 double ly =
00746 -x1 * x2 * T(0,1,2) + x1 * y2 * T(0,0,2)
00747 -y1 * x2 * T(1,1,2) + y1 * y2 * T(1,0,2)
00748 -z1 * x2 * T(2,1,2) + z1 * y2 * T(2,0,2);
00749
00750 double lz =
00751 x1 * x2 * T(0,1,1) - x1 * y2 * T(0,0,1)
00752 + y1 * x2 * T(1,1,1) - y1 * y2 * T(1,0,1)
00753 + z1 * x2 * T(2,1,1) - z1 * y2 * T(2,0,1);
00754
00755 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00756 }
00757
00758
00759 {
00760 double lx =
00761 -x1 * x2 * T(0,2,1) + x1 * z2 * T(0,0,1)
00762 - y1 * x2 * T(1,2,1) + y1 * z2 * T(1,0,1)
00763 - z1 * x2 * T(2,2,1) + z1 * z2 * T(2,0,1);
00764
00765 double ly =
00766 x1 * x2 * T(0,2,0) - x1 * z2 * T(0,0,0)
00767 + y1 * x2 * T(1,2,0) - y1 * z2 * T(1,0,0)
00768 + z1 * x2 * T(2,2,0) - z1 * z2 * T(2,0,0);
00769
00770 double lz = 0;
00771 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00772 }
00773
00774
00775 {
00776 double lx =
00777 -x1 * x2 * T(0,2,2) + x1 * z2 * T(0,0,2)
00778 -y1 * x2 * T(1,2,2) + y1 * z2 * T(1,0,2)
00779 -z1 * x2 * T(2,2,2) + z1 * z2 * T(2,0,2);
00780
00781 double ly = 0;
00782
00783 double lz =
00784 x1 * x2 * T(0,2,0) - x1 * z2 * T(0,0,0) +
00785 y1 * x2 * T(1,2,0) - y1 * z2 * T(1,0,0) +
00786 z1 * x2 * T(2,2,0) - z1 * z2 * T(2,0,0);
00787 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00788 }
00789
00790
00791 {
00792 double lx = 0;
00793
00794 double ly =
00795 -x1 * x2 * T(0,2,2) + x1 * z2 * T(0,0,2)
00796 -y1 * x2 * T(1,2,2) + y1 * z2 * T(1,0,2)
00797 -z1 * x2 * T(2,2,2) + z1 * z2 * T(2,0,2);
00798
00799 double lz
00800 = x1 * x2 * T(0,2,1) - x1 * z2 * T(0,0,1)
00801 + y1 * x2 * T(1,2,1) - y1 * z2 * T(1,0,1)
00802 + z1 * x2 * T(2,2,1) - z1 * z2 * T(2,0,1);
00803 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00804 }
00805
00806
00807 {
00808 double lx
00809 = - x1 * y2 * T(0,2,1) + x1 * z2 * T(0,1,1)
00810 - y1 * y2 * T(1,2,1) + y1 * z2 * T(1,1,1)
00811 - z1 * y2 * T(2,2,1) + z1 * z2 * T(2,1,1);
00812
00813 double ly
00814 = x1 * y2 * T(0,2,0) - x1 * z2 * T(0,1,0)
00815 + y1 * y2 * T(1,2,0) - y1 * z2 * T(1,1,0)
00816 + z1 * y2 * T(2,2,0) - z1 * z2 * T(2,1,0);
00817
00818 double lz = 0;
00819 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00820 }
00821
00822
00823 {
00824 double lx
00825 = -x1 * y2 * T(0,2,2) + x1 * z2 * T(0,1,2)
00826 - y1 * y2 * T(1,2,2) + y1 * z2 * T(1,1,2)
00827 - z1 * y2 * T(2,2,2) + z1 * z2 * T(2,1,2);
00828
00829 double ly = 0;
00830
00831 double lz
00832 = x1 * y2 * T(0,2,0) - x1 * z2 * T(0,1,0)
00833 + y1 * y2 * T(1,2,0) - y1 * z2 * T(1,1,0)
00834 + z1 * y2 * T(2,2,0) - z1 * z2 * T(2,1,0);
00835
00836 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00837 }
00838
00839
00840 {
00841 double lx = 0;
00842
00843 double ly
00844 = -x1 * y2 * T(0,2,2) + x1 * z2 * T(0,1,2)
00845 - y1 * y2 * T(1,2,2) + y1 * z2 * T(1,1,2)
00846 - z1 * y2 * T(2,2,2) + z1 * z2 * T(2,1,2);
00847
00848 double lz
00849 = x1 * y2 * T(0,2,1) - x1 * z2 * T(0,1,1)
00850 + y1 * y2 * T(1,2,1) - y1 * z2 * T(1,1,1)
00851 + z1 * y2 * T(2,2,1) - z1 * z2 * T(2,1,1);
00852
00853 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
00854 }
00855
00856 assert(lines.size() == 9);
00857 if (tt_verbose)
00858 for (int i = 0; i < 9; ++i)
00859 vcl_cerr << lines[i]<< '\n';
00860
00861 return;
00862 }
00863
00864 void TriTensor::get_constraint_lines_image3(HomgPoint2D const& p1,
00865 HomgPoint2D const& p2,
00866 vcl_vector<HomgLine2D>* lines) const
00867 {
00868 #if 0 // Old code assumed points were in image coordinates and conditioned them,
00869
00870 ma2_static_multiply_3x3_trivec(tritensor_ptr->corner1_norm_matrix, trivec1_ptr, &mapped_trivec1);
00871 ma2_static_multiply_3x3_trivec(tritensor_ptr->corner2_norm_matrix, trivec2_ptr, &mapped_trivec2);
00872 #endif // 0
00873
00874
00875 double x1 = p1.x();
00876 double y1 = p1.y();
00877 double z1 = p1.w();
00878
00879 double x2 = p2.x();
00880 double y2 = p2.y();
00881 double z2 = p2.w();
00882
00883 #ifdef DEBUG
00884 vcl_cerr << "CLINES = [" << x1 << ' ' << y1 << ' ' << z1 << "; " << x2 << ' ' << y2 << ' ' << z2 << "];\n";
00885 #endif
00886
00887 lines->resize(0);
00888
00889
00890
00891 {
00892 double lx =
00893 -x1 * x2 * T(0,1,1) + x1 * y2 * T(0,0,1)
00894 -y1 * x2 * T(1,1,1) + y1 * y2 * T(1,0,1)
00895 -z1 * x2 * T(2,1,1) + z1 * y2 * T(2,0,1);
00896
00897 double ly =
00898 x1 * x2 * T(0,1,0) - x1 * y2 * T(0,0,0) +
00899 y1 * x2 * T(1,1,0) - y1 * y2 * T(1,0,0) +
00900 z1 * x2 * T(2,1,0) - z1 * y2 * T(2,0,0);
00901
00902 double lz = 0;
00903 lines->push_back(HomgLine2D(lx, ly, lz));
00904 }
00905
00906
00907 {
00908 double lx =
00909 -x1 * x2 * T(0,1,2) + x1 * y2 * T(0,0,2)
00910 - y1 * x2 * T(1,1,2) + y1 * y2 * T(1,0,2)
00911 - z1 * x2 * T(2,1,2) + z1 * y2 * T(2,0,2);
00912
00913 double ly = 0;
00914
00915 double lz
00916 = x1 * x2 * T(0,1,0) - x1 * y2 * T(0,0,0)
00917 + y1 * x2 * T(1,1,0) - y1 * y2 * T(1,0,0)
00918 + z1 * x2 * T(2,1,0) - z1 * y2 * T(2,0,0);
00919
00920 lines->push_back(HomgLine2D(lx, ly, lz));
00921 }
00922
00923
00924 {
00925 double lx =
00926 0;
00927
00928 double ly =
00929 -x1 * x2 * T(0,1,2) + x1 * y2 * T(0,0,2)
00930 -y1 * x2 * T(1,1,2) + y1 * y2 * T(1,0,2)
00931 -z1 * x2 * T(2,1,2) + z1 * y2 * T(2,0,2);
00932
00933 double lz =
00934 x1 * x2 * T(0,1,1) - x1 * y2 * T(0,0,1)
00935 + y1 * x2 * T(1,1,1) - y1 * y2 * T(1,0,1)
00936 + z1 * x2 * T(2,1,1) - z1 * y2 * T(2,0,1);
00937
00938 lines->push_back(HomgLine2D(lx, ly, lz));
00939 }
00940
00941
00942 {
00943 double lx =
00944 -x1 * x2 * T(0,2,1) + x1 * z2 * T(0,0,1)
00945 - y1 * x2 * T(1,2,1) + y1 * z2 * T(1,0,1)
00946 - z1 * x2 * T(2,2,1) + z1 * z2 * T(2,0,1);
00947
00948 double ly =
00949 x1 * x2 * T(0,2,0) - x1 * z2 * T(0,0,0)
00950 + y1 * x2 * T(1,2,0) - y1 * z2 * T(1,0,0)
00951 + z1 * x2 * T(2,2,0) - z1 * z2 * T(2,0,0);
00952
00953 double lz = 0;
00954 lines->push_back(HomgLine2D(lx, ly, lz));
00955 }
00956
00957
00958 {
00959 double lx =
00960 -x1 * x2 * T(0,2,2) + x1 * z2 * T(0,0,2)
00961 -y1 * x2 * T(1,2,2) + y1 * z2 * T(1,0,2)
00962 -z1 * x2 * T(2,2,2) + z1 * z2 * T(2,0,2);
00963
00964 double ly = 0;
00965
00966 double lz =
00967 x1 * x2 * T(0,2,0) - x1 * z2 * T(0,0,0) +
00968 y1 * x2 * T(1,2,0) - y1 * z2 * T(1,0,0) +
00969 z1 * x2 * T(2,2,0) - z1 * z2 * T(2,0,0);
00970 lines->push_back(HomgLine2D(lx, ly, lz));
00971 }
00972
00973
00974 {
00975 double lx = 0;
00976
00977 double ly =
00978 -x1 * x2 * T(0,2,2) + x1 * z2 * T(0,0,2)
00979 -y1 * x2 * T(1,2,2) + y1 * z2 * T(1,0,2)
00980 -z1 * x2 * T(2,2,2) + z1 * z2 * T(2,0,2);
00981
00982 double lz
00983 = x1 * x2 * T(0,2,1) - x1 * z2 * T(0,0,1)
00984 + y1 * x2 * T(1,2,1) - y1 * z2 * T(1,0,1)
00985 + z1 * x2 * T(2,2,1) - z1 * z2 * T(2,0,1);
00986 lines->push_back(HomgLine2D(lx, ly, lz));
00987 }
00988
00989
00990 {
00991 double lx
00992 = - x1 * y2 * T(0,2,1) + x1 * z2 * T(0,1,1)
00993 - y1 * y2 * T(1,2,1) + y1 * z2 * T(1,1,1)
00994 - z1 * y2 * T(2,2,1) + z1 * z2 * T(2,1,1);
00995
00996 double ly
00997 = x1 * y2 * T(0,2,0) - x1 * z2 * T(0,1,0)
00998 + y1 * y2 * T(1,2,0) - y1 * z2 * T(1,1,0)
00999 + z1 * y2 * T(2,2,0) - z1 * z2 * T(2,1,0);
01000
01001 double lz = 0;
01002 lines->push_back(HomgLine2D(lx, ly, lz));
01003 }
01004
01005
01006 {
01007 double lx
01008 = -x1 * y2 * T(0,2,2) + x1 * z2 * T(0,1,2)
01009 - y1 * y2 * T(1,2,2) + y1 * z2 * T(1,1,2)
01010 - z1 * y2 * T(2,2,2) + z1 * z2 * T(2,1,2);
01011
01012 double ly = 0;
01013
01014 double lz
01015 = x1 * y2 * T(0,2,0) - x1 * z2 * T(0,1,0)
01016 + y1 * y2 * T(1,2,0) - y1 * z2 * T(1,1,0)
01017 + z1 * y2 * T(2,2,0) - z1 * z2 * T(2,1,0);
01018
01019 lines->push_back(HomgLine2D(lx, ly, lz));
01020 }
01021
01022
01023 {
01024 double lx = 0;
01025
01026 double ly
01027 = -x1 * y2 * T(0,2,2) + x1 * z2 * T(0,1,2)
01028 - y1 * y2 * T(1,2,2) + y1 * z2 * T(1,1,2)
01029 - z1 * y2 * T(2,2,2) + z1 * z2 * T(2,1,2);
01030
01031 double lz
01032 = x1 * y2 * T(0,2,1) - x1 * z2 * T(0,1,1)
01033 + y1 * y2 * T(1,2,1) - y1 * z2 * T(1,1,1)
01034 + z1 * y2 * T(2,2,1) - z1 * z2 * T(2,1,1);
01035
01036 lines->push_back(HomgLine2D(lx, ly, lz));
01037 }
01038
01039 assert(lines->size() == 9);
01040 if (tt_verbose)
01041 for (int i = 0; i < 9; ++i)
01042 vcl_cerr << (*lines)[i]<< '\n';
01043
01044 return;
01045
01046 #if 0
01047 *trivec3_ptr = ho_trivec_orthog(line_table_ptr);
01048 ma2_static_multiply_3x3_trivec(point_invnorm_matrix3, trivec3_ptr, trivec3_ptr);
01049
01050
01051 if (false)
01052 for (int line_index = 0; line_index < lines->size(); line_index++)
01053 ma2_static_multiply_3x3_trivec(line_invnorm_matrix3, lines[line_index], lines[line_index]);
01054
01055
01056 ho_triveccam_aspect_lines_to_point(line_table_ptr, trivec3_ptr);
01057 #endif
01058 }
01059
01060 void TriTensor::get_constraint_lines_image2(vgl_homg_point_2d<double> const& p1,
01061 vgl_homg_point_2d<double> const& p3,
01062 vcl_vector<vgl_homg_line_2d<double> >& lines) const
01063 {
01064 double x1 = p1.x();
01065 double y1 = p1.y();
01066 double z1 = p1.w();
01067
01068 double x3 = p3.x();
01069 double y3 = p3.y();
01070 double z3 = p3.w();
01071
01072 lines.resize(0);
01073
01074
01075 {
01076 double lx
01077 = x1 * y3 * T(0,1,0) - x1 * x3 * T(0,1,1)
01078 + y1 * y3 * T(1,1,0) - y1 * x3 * T(1,1,1)
01079 + z1 * y3 * T(2,1,0) - z1 * x3 * T(2,1,1);
01080
01081 double ly
01082 = - x1 * y3 * T(0,0,0) + x1 * x3 * T(0,0,1)
01083 - y1 * y3 * T(1,0,0) + y1 * x3 * T(1,0,1)
01084 - z1 * y3 * T(2,0,0) + z1 * x3 * T(2,0,1);
01085
01086 double lz = 0;
01087
01088 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01089 }
01090
01091
01092 {
01093 double lx
01094 = x1 * z3 * T(0,1,0) - x1 * x3 * T(0,1,2)
01095 + y1 * z3 * T(1,1,0) - y1 * x3 * T(1,1,2)
01096 + z1 * z3 * T(2,1,0) - z1 * x3 * T(2,1,2);
01097
01098 double ly
01099 = - x1 * z3 * T(0,0,0) + x1 * x3 * T(0,0,2)
01100 - y1 * z3 * T(1,0,0) + y1 * x3 * T(1,0,2)
01101 - z1 * z3 * T(2,0,0) + z1 * x3 * T(2,0,2);
01102
01103 double lz = 0;
01104
01105 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01106 }
01107
01108
01109 {
01110 double lx
01111 = x1 * z3 * T(0,1,1) - x1 * y3 * T(0,1,2)
01112 + y1 * z3 * T(1,1,1) - y1 * y3 * T(1,1,2)
01113 + z1 * z3 * T(2,1,1) - z1 * y3 * T(2,1,2);
01114
01115 double ly
01116 = -x1 * z3 * T(0,0,1) + x1 * y3 * T(0,0,2)
01117 - y1 * z3 * T(1,0,1) + y1 * y3 * T(1,0,2)
01118 - z1 * z3 * T(2,0,1) + z1 * y3 * T(2,0,2);
01119
01120 double lz = 0;
01121
01122 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01123 }
01124
01125
01126 {
01127 double lx
01128 = x1 * y3 * T(0,2,0) - x1 * x3 * T(0,2,1)
01129 + y1 * y3 * T(1,2,0) - y1 * x3 * T(1,2,1)
01130 + z1 * y3 * T(2,2,0) - z1 * x3 * T(2,2,1);
01131
01132 double ly = 0;
01133
01134 double lz
01135 = -x1 * y3 * T(0,0,0) + x1 * x3 * T(0,0,1)
01136 - y1 * y3 * T(1,0,0) + y1 * x3 * T(1,0,1)
01137 - z1 * y3 * T(2,0,0) + z1 * x3 * T(2,0,1);
01138
01139 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01140 }
01141
01142
01143 {
01144 double lx
01145 = x1 * z3 * T(0,2,0) - x1 * x3 * T(0,2,2)
01146 + y1 * z3 * T(1,2,0) - y1 * x3 * T(1,2,2)
01147 + z1 * z3 * T(2,2,0) - z1 * x3 * T(2,2,2);
01148
01149 double ly = 0;
01150
01151 double lz
01152 = - x1 * z3 * T(0,0,0) + x1 * x3 * T(0,0,2)
01153 - y1 * z3 * T(1,0,0) + y1 * x3 * T(1,0,2)
01154 - z1 * z3 * T(2,0,0) + z1 * x3 * T(2,0,2);
01155
01156 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01157 }
01158
01159
01160 {
01161 double lx
01162 = x1 * z3 * T(0,2,1) - x1 * y3 * T(0,2,2)
01163 + y1 * z3 * T(1,2,1) - y1 * y3 * T(1,2,2)
01164 + z1 * z3 * T(2,2,1) - z1 * y3 * T(2,2,2);
01165
01166 double ly = 0;
01167
01168 double lz
01169 = - x1 * z3 * T(0,0,1) + x1 * y3 * T(0,0,2)
01170 - y1 * z3 * T(1,0,1) + y1 * y3 * T(1,0,2)
01171 - z1 * z3 * T(2,0,1) + z1 * y3 * T(2,0,2);
01172
01173 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01174 }
01175
01176
01177 {
01178 double lx = 0;
01179
01180 double ly
01181 = x1 * y3 * T(0,2,0) - x1 * x3 * T(0,2,1)
01182 + y1 * y3 * T(1,2,0) - y1 * x3 * T(1,2,1)
01183 + z1 * y3 * T(2,2,0) - z1 * x3 * T(2,2,1);
01184
01185 double lz
01186 = -x1 * y3 * T(0,1,0) + x1 * x3 * T(0,1,1)
01187 - y1 * y3 * T(1,1,0) + y1 * x3 * T(1,1,1)
01188 - z1 * y3 * T(2,1,0) + z1 * x3 * T(2,1,1);
01189
01190 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01191 }
01192
01193
01194 {
01195 double lx = 0;
01196
01197 double ly
01198 = x1 * z3 * T(0,2,0) - x1 * x3 * T(0,2,2)
01199 + y1 * z3 * T(1,2,0) - y1 * x3 * T(1,2,2)
01200 + z1 * z3 * T(2,2,0) - z1 * x3 * T(2,2,2);
01201
01202 double lz
01203 = - x1 * z3 * T(0,1,0) + x1 * x3 * T(0,1,2)
01204 - y1 * z3 * T(1,1,0) + y1 * x3 * T(1,1,2)
01205 - z1 * z3 * T(2,1,0) + z1 * x3 * T(2,1,2);
01206
01207 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01208 }
01209
01210
01211 {
01212 double lx = 0;
01213
01214 double ly
01215 = x1 * z3 * T(0,2,1) - x1 * y3 * T(0,2,2)
01216 + y1 * z3 * T(1,2,1) - y1 * y3 * T(1,2,2)
01217 + z1 * z3 * T(2,2,1) - z1 * y3 * T(2,2,2);
01218
01219 double lz
01220 = - x1 * z3 * T(0,1,1) + x1 * y3 * T(0,1,2)
01221 - y1 * z3 * T(1,1,1) + y1 * y3 * T(1,1,2)
01222 - z1 * z3 * T(2,1,1) + z1 * y3 * T(2,1,2);
01223
01224 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01225 }
01226 }
01227
01228 void TriTensor::get_constraint_lines_image2(HomgPoint2D const& p1,
01229 HomgPoint2D const& p3,
01230 vcl_vector<HomgLine2D>* lines) const
01231 {
01232 double x1 = p1.x();
01233 double y1 = p1.y();
01234 double z1 = p1.w();
01235
01236 double x3 = p3.x();
01237 double y3 = p3.y();
01238 double z3 = p3.w();
01239
01240 lines->resize(0);
01241
01242
01243 {
01244 double lx
01245 = x1 * y3 * T(0,1,0) - x1 * x3 * T(0,1,1)
01246 + y1 * y3 * T(1,1,0) - y1 * x3 * T(1,1,1)
01247 + z1 * y3 * T(2,1,0) - z1 * x3 * T(2,1,1);
01248
01249 double ly
01250 = - x1 * y3 * T(0,0,0) + x1 * x3 * T(0,0,1)
01251 - y1 * y3 * T(1,0,0) + y1 * x3 * T(1,0,1)
01252 - z1 * y3 * T(2,0,0) + z1 * x3 * T(2,0,1);
01253
01254 double lz = 0;
01255
01256 lines->push_back(HomgLine2D(lx, ly, lz));
01257 }
01258
01259
01260 {
01261 double lx
01262 = x1 * z3 * T(0,1,0) - x1 * x3 * T(0,1,2)
01263 + y1 * z3 * T(1,1,0) - y1 * x3 * T(1,1,2)
01264 + z1 * z3 * T(2,1,0) - z1 * x3 * T(2,1,2);
01265
01266 double ly
01267 = - x1 * z3 * T(0,0,0) + x1 * x3 * T(0,0,2)
01268 - y1 * z3 * T(1,0,0) + y1 * x3 * T(1,0,2)
01269 - z1 * z3 * T(2,0,0) + z1 * x3 * T(2,0,2);
01270
01271 double lz = 0;
01272
01273 lines->push_back(HomgLine2D(lx, ly, lz));
01274 }
01275
01276
01277 {
01278 double lx
01279 = x1 * z3 * T(0,1,1) - x1 * y3 * T(0,1,2)
01280 + y1 * z3 * T(1,1,1) - y1 * y3 * T(1,1,2)
01281 + z1 * z3 * T(2,1,1) - z1 * y3 * T(2,1,2);
01282
01283 double ly
01284 = -x1 * z3 * T(0,0,1) + x1 * y3 * T(0,0,2)
01285 - y1 * z3 * T(1,0,1) + y1 * y3 * T(1,0,2)
01286 - z1 * z3 * T(2,0,1) + z1 * y3 * T(2,0,2);
01287
01288 double lz = 0;
01289
01290 lines->push_back(HomgLine2D(lx, ly, lz));
01291 }
01292
01293
01294 {
01295 double lx
01296 = x1 * y3 * T(0,2,0) - x1 * x3 * T(0,2,1)
01297 + y1 * y3 * T(1,2,0) - y1 * x3 * T(1,2,1)
01298 + z1 * y3 * T(2,2,0) - z1 * x3 * T(2,2,1);
01299
01300 double ly = 0;
01301
01302 double lz
01303 = -x1 * y3 * T(0,0,0) + x1 * x3 * T(0,0,1)
01304 - y1 * y3 * T(1,0,0) + y1 * x3 * T(1,0,1)
01305 - z1 * y3 * T(2,0,0) + z1 * x3 * T(2,0,1);
01306
01307 lines->push_back(HomgLine2D(lx, ly, lz));
01308 }
01309
01310
01311 {
01312 double lx
01313 = x1 * z3 * T(0,2,0) - x1 * x3 * T(0,2,2)
01314 + y1 * z3 * T(1,2,0) - y1 * x3 * T(1,2,2)
01315 + z1 * z3 * T(2,2,0) - z1 * x3 * T(2,2,2);
01316
01317 double ly = 0;
01318
01319 double lz
01320 = - x1 * z3 * T(0,0,0) + x1 * x3 * T(0,0,2)
01321 - y1 * z3 * T(1,0,0) + y1 * x3 * T(1,0,2)
01322 - z1 * z3 * T(2,0,0) + z1 * x3 * T(2,0,2);
01323
01324 lines->push_back(HomgLine2D(lx, ly, lz));
01325 }
01326
01327
01328 {
01329 double lx
01330 = x1 * z3 * T(0,2,1) - x1 * y3 * T(0,2,2)
01331 + y1 * z3 * T(1,2,1) - y1 * y3 * T(1,2,2)
01332 + z1 * z3 * T(2,2,1) - z1 * y3 * T(2,2,2);
01333
01334 double ly = 0;
01335
01336 double lz
01337 = - x1 * z3 * T(0,0,1) + x1 * y3 * T(0,0,2)
01338 - y1 * z3 * T(1,0,1) + y1 * y3 * T(1,0,2)
01339 - z1 * z3 * T(2,0,1) + z1 * y3 * T(2,0,2);
01340
01341 lines->push_back(HomgLine2D(lx, ly, lz));
01342 }
01343
01344
01345 {
01346 double lx = 0;
01347
01348 double ly
01349 = x1 * y3 * T(0,2,0) - x1 * x3 * T(0,2,1)
01350 + y1 * y3 * T(1,2,0) - y1 * x3 * T(1,2,1)
01351 + z1 * y3 * T(2,2,0) - z1 * x3 * T(2,2,1);
01352
01353 double lz
01354 = -x1 * y3 * T(0,1,0) + x1 * x3 * T(0,1,1)
01355 - y1 * y3 * T(1,1,0) + y1 * x3 * T(1,1,1)
01356 - z1 * y3 * T(2,1,0) + z1 * x3 * T(2,1,1);
01357
01358 lines->push_back(HomgLine2D(lx, ly, lz));
01359 }
01360
01361
01362 {
01363 double lx = 0;
01364
01365 double ly
01366 = x1 * z3 * T(0,2,0) - x1 * x3 * T(0,2,2)
01367 + y1 * z3 * T(1,2,0) - y1 * x3 * T(1,2,2)
01368 + z1 * z3 * T(2,2,0) - z1 * x3 * T(2,2,2);
01369
01370 double lz
01371 = - x1 * z3 * T(0,1,0) + x1 * x3 * T(0,1,2)
01372 - y1 * z3 * T(1,1,0) + y1 * x3 * T(1,1,2)
01373 - z1 * z3 * T(2,1,0) + z1 * x3 * T(2,1,2);
01374
01375 lines->push_back(HomgLine2D(lx, ly, lz));
01376 }
01377
01378
01379 {
01380 double lx = 0;
01381
01382 double ly
01383 = x1 * z3 * T(0,2,1) - x1 * y3 * T(0,2,2)
01384 + y1 * z3 * T(1,2,1) - y1 * y3 * T(1,2,2)
01385 + z1 * z3 * T(2,2,1) - z1 * y3 * T(2,2,2);
01386
01387 double lz
01388 = - x1 * z3 * T(0,1,1) + x1 * y3 * T(0,1,2)
01389 - y1 * z3 * T(1,1,1) + y1 * y3 * T(1,1,2)
01390 - z1 * z3 * T(2,1,1) + z1 * y3 * T(2,1,2);
01391
01392 lines->push_back(HomgLine2D(lx, ly, lz));
01393 }
01394
01395
01396 }
01397
01398 void TriTensor::get_constraint_lines_image1(vgl_homg_point_2d<double> const& p2,
01399 vgl_homg_point_2d<double> const& p3,
01400 vcl_vector<vgl_homg_line_2d<double> >& lines) const
01401 {
01402
01403
01404 double x2 = p2.x();
01405 double y2 = p2.y();
01406 double z2 = p2.w();
01407
01408 double x3 = p3.x();
01409 double y3 = p3.y();
01410 double z3 = p3.w();
01411
01412 lines.resize(0);
01413
01414
01415
01416 {
01417 double lx
01418 = x2 * y3 * T(0,1,0)
01419 - y2 * y3 * T(0,0,0)
01420 - x2 * x3 * T(0,1,1)
01421 + y2 * x3 * T(0,0,1);
01422
01423 double ly
01424 = x2 * y3 * T(1,1,0)
01425 - y2 * y3 * T(1,0,0)
01426 - x2 * x3 * T(1,1,1)
01427 + y2 * x3 * T(1,0,1);
01428
01429 double lz
01430 = x2 * y3 * T(2,1,0)
01431 - y2 * y3 * T(2,0,0)
01432 - x2 * x3 * T(2,1,1)
01433 + y2 * x3 * T(2,0,1);
01434
01435 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01436 }
01437
01438
01439 {
01440 double lx
01441 = x2 * z3 * T(0,1,0)
01442 - y2 * z3 * T(0,0,0)
01443 - x2 * x3 * T(0,1,2)
01444 + y2 * x3 * T(0,0,2);
01445
01446 double ly
01447 = x2 * z3 * T(1,1,0)
01448 - y2 * z3 * T(1,0,0)
01449 - x2 * x3 * T(1,1,2)
01450 + y2 * x3 * T(1,0,2);
01451
01452 double lz
01453 = x2 * z3 * T(2,1,0)
01454 - y2 * z3 * T(2,0,0)
01455 - x2 * x3 * T(2,1,2)
01456 + y2 * x3 * T(2,0,2);
01457
01458 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01459 }
01460
01461
01462 {
01463 double lx
01464 = x2 * z3 * T(0,1,1)
01465 - y2 * z3 * T(0,0,1)
01466 - x2 * y3 * T(0,1,2)
01467 + y2 * y3 * T(0,0,2);
01468
01469 double ly
01470 = x2 * z3 * T(1,1,1)
01471 - y2 * z3 * T(1,0,1)
01472 - x2 * y3 * T(1,1,2)
01473 + y2 * y3 * T(1,0,2);
01474
01475 double lz
01476 = x2 * z3 * T(2,1,1)
01477 - y2 * z3 * T(2,0,1)
01478 - x2 * y3 * T(2,1,2)
01479 + y2 * y3 * T(2,0,2);
01480
01481 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01482 }
01483
01484
01485 {
01486 double lx
01487 = x2 * y3 * T(0,2,0)
01488 - z2 * y3 * T(0,0,0)
01489 - x2 * x3 * T(0,2,1)
01490 + z2 * x3 * T(0,0,1);
01491
01492 double ly
01493 = x2 * y3 * T(1,2,0)
01494 - z2 * y3 * T(1,0,0)
01495 - x2 * x3 * T(1,2,1)
01496 + z2 * x3 * T(1,0,1);
01497
01498 double lz
01499 = x2 * y3 * T(2,2,0)
01500 - z2 * y3 * T(2,0,0)
01501 - x2 * x3 * T(2,2,1)
01502 + z2 * x3 * T(2,0,1);
01503
01504 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01505 }
01506
01507
01508 {
01509 double lx
01510 = x2 * z3 * T(0,2,0)
01511 - z2 * z3 * T(0,0,0)
01512 - x2 * x3 * T(0,2,2)
01513 + z2 * x3 * T(0,0,2);
01514
01515 double ly
01516 = x2 * z3 * T(1,2,0)
01517 - z2 * z3 * T(1,0,0)
01518 - x2 * x3 * T(1,2,2)
01519 + z2 * x3 * T(1,0,2);
01520
01521 double lz
01522 = x2 * z3 * T(2,2,0)
01523 - z2 * z3 * T(2,0,0)
01524 - x2 * x3 * T(2,2,2)
01525 + z2 * x3 * T(2,0,2);
01526
01527 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01528 }
01529
01530
01531 {
01532 double lx
01533 = x2 * z3 * T(0,2,1)
01534 - z2 * z3 * T(0,0,1)
01535 - x2 * y3 * T(0,2,2)
01536 + z2 * y3 * T(0,0,2);
01537
01538 double ly
01539 = x2 * z3 * T(1,2,1)
01540 - z2 * z3 * T(1,0,1)
01541 - x2 * y3 * T(1,2,2)
01542 + z2 * y3 * T(1,0,2);
01543
01544 double lz
01545 = x2 * z3 * T(2,2,1)
01546 - z2 * z3 * T(2,0,1)
01547 - x2 * y3 * T(2,2,2)
01548 + z2 * y3 * T(2,0,2);
01549
01550 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01551 }
01552
01553
01554 {
01555 double lx
01556 = y2 * y3 * T(0,2,0)
01557 - z2 * y3 * T(0,1,0)
01558 - y2 * x3 * T(0,2,1)
01559 + z2 * x3 * T(0,1,1);
01560
01561 double ly
01562 = y2 * y3 * T(1,2,0)
01563 - z2 * y3 * T(1,1,0)
01564 - y2 * x3 * T(1,2,1)
01565 + z2 * x3 * T(1,1,1);
01566
01567 double lz
01568 = y2 * y3 * T(2,2,0)
01569 - z2 * y3 * T(2,1,0)
01570 - y2 * x3 * T(2,2,1)
01571 + z2 * x3 * T(2,1,1);
01572
01573 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01574 }
01575
01576
01577 {
01578 double lx
01579 = y2 * z3 * T(0,2,0)
01580 - z2 * z3 * T(0,1,0)
01581 - y2 * x3 * T(0,2,2)
01582 + z2 * x3 * T(0,1,2);
01583
01584 double ly
01585 = y2 * z3 * T(1,2,0)
01586 - z2 * z3 * T(1,1,0)
01587 - y2 * x3 * T(1,2,2)
01588 + z2 * x3 * T(1,1,2);
01589
01590 double lz
01591 = y2 * z3 * T(2,2,0)
01592 - z2 * z3 * T(2,1,0)
01593 - y2 * x3 * T(2,2,2)
01594 + z2 * x3 * T(2,1,2);
01595
01596 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01597 }
01598
01599
01600 {
01601 double lx
01602 = y2 * z3 * T(0,2,1)
01603 - z2 * z3 * T(0,1,1)
01604 - y2 * y3 * T(0,2,2)
01605 + z2 * y3 * T(0,1,2);
01606
01607 double ly
01608 = y2 * z3 * T(1,2,1)
01609 - z2 * z3 * T(1,1,1)
01610 - y2 * y3 * T(1,2,2)
01611 + z2 * y3 * T(1,1,2);
01612
01613 double lz
01614 = y2 * z3 * T(2,2,1)
01615 - z2 * z3 * T(2,1,1)
01616 - y2 * y3 * T(2,2,2)
01617 + z2 * y3 * T(2,1,2);
01618
01619 lines.push_back(vgl_homg_line_2d<double>(lx, ly, lz));
01620 }
01621 }
01622
01623 void TriTensor::get_constraint_lines_image1(HomgPoint2D const& p2,
01624 HomgPoint2D const& p3,
01625 vcl_vector<HomgLine2D>* lines) const
01626 {
01627
01628
01629 double x2 = p2.x();
01630 double y2 = p2.y();
01631 double z2 = p2.w();
01632
01633 double x3 = p3.x();
01634 double y3 = p3.y();
01635 double z3 = p3.w();
01636
01637 lines->resize(0);
01638
01639
01640
01641 {
01642 double lx
01643 = x2 * y3 * T(0,1,0)
01644 - y2 * y3 * T(0,0,0)
01645 - x2 * x3 * T(0,1,1)
01646 + y2 * x3 * T(0,0,1);
01647
01648 double ly
01649 = x2 * y3 * T(1,1,0)
01650 - y2 * y3 * T(1,0,0)
01651 - x2 * x3 * T(1,1,1)
01652 + y2 * x3 * T(1,0,1);
01653
01654 double lz
01655 = x2 * y3 * T(2,1,0)
01656 - y2 * y3 * T(2,0,0)
01657 - x2 * x3 * T(2,1,1)
01658 + y2 * x3 * T(2,0,1);
01659
01660 lines->push_back(HomgLine2D(lx, ly, lz));
01661 }
01662
01663
01664 {
01665 double lx
01666 = x2 * z3 * T(0,1,0)
01667 - y2 * z3 * T(0,0,0)
01668 - x2 * x3 * T(0,1,2)
01669 + y2 * x3 * T(0,0,2);
01670
01671 double ly
01672 = x2 * z3 * T(1,1,0)
01673 - y2 * z3 * T(1,0,0)
01674 - x2 * x3 * T(1,1,2)
01675 + y2 * x3 * T(1,0,2);
01676
01677 double lz
01678 = x2 * z3 * T(2,1,0)
01679 - y2 * z3 * T(2,0,0)
01680 - x2 * x3 * T(2,1,2)
01681 + y2 * x3 * T(2,0,2);
01682
01683 lines->push_back(HomgLine2D(lx, ly, lz));
01684 }
01685
01686
01687 {
01688 double lx
01689 = x2 * z3 * T(0,1,1)
01690 - y2 * z3 * T(0,0,1)
01691 - x2 * y3 * T(0,1,2)
01692 + y2 * y3 * T(0,0,2);
01693
01694 double ly
01695 = x2 * z3 * T(1,1,1)
01696 - y2 * z3 * T(1,0,1)
01697 - x2 * y3 * T(1,1,2)
01698 + y2 * y3 * T(1,0,2);
01699
01700 double lz
01701 = x2 * z3 * T(2,1,1)
01702 - y2 * z3 * T(2,0,1)
01703 - x2 * y3 * T(2,1,2)
01704 + y2 * y3 * T(2,0,2);
01705
01706 lines->push_back(HomgLine2D(lx, ly, lz));
01707 }
01708
01709
01710 {
01711 double lx
01712 = x2 * y3 * T(0,2,0)
01713 - z2 * y3 * T(0,0,0)
01714 - x2 * x3 * T(0,2,1)
01715 + z2 * x3 * T(0,0,1);
01716
01717 double ly
01718 = x2 * y3 * T(1,2,0)
01719 - z2 * y3 * T(1,0,0)
01720 - x2 * x3 * T(1,2,1)
01721 + z2 * x3 * T(1,0,1);
01722
01723 double lz
01724 = x2 * y3 * T(2,2,0)
01725 - z2 * y3 * T(2,0,0)
01726 - x2 * x3 * T(2,2,1)
01727 + z2 * x3 * T(2,0,1);
01728
01729 lines->push_back(HomgLine2D(lx, ly, lz));
01730 }
01731
01732
01733 {
01734 double lx
01735 = x2 * z3 * T(0,2,0)
01736 - z2 * z3 * T(0,0,0)
01737 - x2 * x3 * T(0,2,2)
01738 + z2 * x3 * T(0,0,2);
01739
01740 double ly
01741 = x2 * z3 * T(1,2,0)
01742 - z2 * z3 * T(1,0,0)
01743 - x2 * x3 * T(1,2,2)
01744 + z2 * x3 * T(1,0,2);
01745
01746 double lz
01747 = x2 * z3 * T(2,2,0)
01748 - z2 * z3 * T(2,0,0)
01749 - x2 * x3 * T(2,2,2)
01750 + z2 * x3 * T(2,0,2);
01751
01752 lines->push_back(HomgLine2D(lx, ly, lz));
01753 }
01754
01755
01756 {
01757 double lx
01758 = x2 * z3 * T(0,2,1)
01759 - z2 * z3 * T(0,0,1)
01760 - x2 * y3 * T(0,2,2)
01761 + z2 * y3 * T(0,0,2);
01762
01763 double ly
01764 = x2 * z3 * T(1,2,1)
01765 - z2 * z3 * T(1,0,1)
01766 - x2 * y3 * T(1,2,2)
01767 + z2 * y3 * T(1,0,2);
01768
01769 double lz
01770 = x2 * z3 * T(2,2,1)
01771 - z2 * z3 * T(2,0,1)
01772 - x2 * y3 * T(2,2,2)
01773 + z2 * y3 * T(2,0,2);
01774
01775 lines->push_back(HomgLine2D(lx, ly, lz));
01776 }
01777
01778
01779 {
01780 double lx
01781 = y2 * y3 * T(0,2,0)
01782 - z2 * y3 * T(0,1,0)
01783 - y2 * x3 * T(0,2,1)
01784 + z2 * x3 * T(0,1,1);
01785
01786 double ly
01787 = y2 * y3 * T(1,2,0)
01788 - z2 * y3 * T(1,1,0)
01789 - y2 * x3 * T(1,2,1)
01790 + z2 * x3 * T(1,1,1);
01791
01792 double lz
01793 = y2 * y3 * T(2,2,0)
01794 - z2 * y3 * T(2,1,0)
01795 - y2 * x3 * T(2,2,1)
01796 + z2 * x3 * T(2,1,1);
01797
01798 lines->push_back(HomgLine2D(lx, ly, lz));
01799 }
01800
01801
01802 {
01803 double lx
01804 = y2 * z3 * T(0,2,0)
01805 - z2 * z3 * T(0,1,0)
01806 - y2 * x3 * T(0,2,2)
01807 + z2 * x3 * T(0,1,2);
01808
01809 double ly
01810 = y2 * z3 * T(1,2,0)
01811 - z2 * z3 * T(1,1,0)
01812 - y2 * x3 * T(1,2,2)
01813 + z2 * x3 * T(1,1,2);
01814
01815 double lz
01816 = y2 * z3 * T(2,2,0)
01817 - z2 * z3 * T(2,1,0)
01818 - y2 * x3 * T(2,2,2)
01819 + z2 * x3 * T(2,1,2);
01820
01821 lines->push_back(HomgLine2D(lx, ly, lz));
01822 }
01823
01824
01825 {
01826 double lx
01827 = y2 * z3 * T(0,2,1)
01828 - z2 * z3 * T(0,1,1)
01829 - y2 * y3 * T(0,2,2)
01830 + z2 * y3 * T(0,1,2);
01831
01832 double ly
01833 = y2 * z3 * T(1,2,1)
01834 - z2 * z3 * T(1,1,1)
01835 - y2 * y3 * T(1,2,2)
01836 + z2 * y3 * T(1,1,2);
01837
01838 double lz
01839 = y2 * z3 * T(2,2,1)
01840 - z2 * z3 * T(2,1,1)
01841 - y2 * y3 * T(2,2,2)
01842 + z2 * y3 * T(2,1,2);
01843
01844 lines->push_back(HomgLine2D(lx, ly, lz));
01845 }
01846
01847
01848 }
01849
01850
01851
01852
01853
01854
01855 vcl_istream& operator>>(vcl_istream& s, TriTensor& T)
01856 {
01857 for (int i = 0; i < 3; ++i)
01858 for (int j = 0; j < 3; ++j)
01859 for (int k = 0; k < 3; ++k)
01860 s >> T(i,j,k);
01861 return s;
01862 }
01863
01864
01865
01866 vcl_ostream& operator<<(vcl_ostream& s, const TriTensor& T)
01867 {
01868 for (int i = 0; i < 3; ++i) {
01869 for (int j = 0; j < 3; ++j) {
01870 for (int k = 0; k < 3; ++k)
01871 vul_printf(s, "%20.16e ", T(i,j,k));
01872 s << vcl_endl;
01873 }
01874 s << vcl_endl;
01875 }
01876 return s;
01877 }
01878
01879 struct Column3x3 : public vnl_double_3x3
01880 {
01881 Column3x3(const vnl_vector<double>& v1, const vnl_vector<double>& v2, const vnl_vector<double>& v3)
01882 {
01883 (*this)(0,0) = v1[0]; (*this)(0,1) = v2[0]; (*this)(0,2) = v3[0];
01884 (*this)(1,0) = v1[1]; (*this)(1,1) = v2[1]; (*this)(1,2) = v3[1];
01885 (*this)(2,0) = v1[2]; (*this)(2,1) = v2[2]; (*this)(2,2) = v3[2];
01886 }
01887 };
01888
01889
01890
01891
01892 bool TriTensor::compute_epipoles() const
01893 {
01894 vnl_double_3x3 T1 = dot1(vnl_double_3(1,0,0).as_ref());
01895 vnl_double_3x3 T2 = dot1(vnl_double_3(0,1,0).as_ref());
01896 vnl_double_3x3 T3 = dot1(vnl_double_3(0,0,1).as_ref());
01897
01898 vnl_svd<double> svd1(T1.as_ref());
01899 vnl_double_3 u1 = svd1.nullvector();
01900 vnl_double_3 v1 = svd1.left_nullvector();
01901
01902 vnl_svd<double> svd2(T2.as_ref());
01903 vnl_double_3 u2 = svd2.nullvector();
01904 vnl_double_3 v2 = svd2.left_nullvector();
01905
01906 vnl_svd<double> svd3(T3.as_ref());
01907 vnl_double_3 u3 = svd3.nullvector();
01908 vnl_double_3 v3 = svd3.left_nullvector();
01909
01910 vnl_double_3x3 V;
01911 V(0,0) = v1[0]; V(0,1) = v2[0]; V(0,2) = v3[0];
01912 V(1,0) = v1[1]; V(1,1) = v2[1]; V(1,2) = v3[1];
01913 V(2,0) = v1[2]; V(2,1) = v2[2]; V(2,2) = v3[2];
01914
01915 vnl_svd<double> svdv(V.as_ref());
01916
01917 delete e12_;
01918 e12_ = new HomgPoint2D(svdv.left_nullvector());
01919
01920 vnl_double_3x3 U;
01921 U(0,0) = u1[0]; U(0,1) = u2[0]; U(0,2) = u3[0];
01922 U(1,0) = u1[1]; U(1,1) = u2[1]; U(1,2) = u3[1];
01923 U(2,0) = u1[2]; U(2,1) = u2[2]; U(2,2) = u3[2];
01924
01925 vnl_svd<double> svdu(U.as_ref());
01926
01927 delete e13_;
01928 e13_ = new HomgPoint2D(svdu.left_nullvector());
01929
01930 return e12_!=0 && e13_!=0;
01931 }
01932
01933
01934 bool TriTensor::get_epipoles(vgl_homg_point_2d<double>& e2,
01935 vgl_homg_point_2d<double>& e3) const
01936 {
01937
01938 if (!e12_ || !e13_)
01939 compute_epipoles();
01940
01941 e2.set(e12_->x(),e12_->y(),e12_->w());
01942 e3.set(e13_->x(),e13_->y(),e13_->w());
01943 return true;
01944 }
01945
01946 bool TriTensor::get_epipoles(HomgPoint2D* e2,
01947 HomgPoint2D* e3) const
01948 {
01949
01950 if (!e12_ || !e13_)
01951 compute_epipoles();
01952
01953 if (e2) *e2 = *e12_;
01954 if (e3) *e3 = *e13_;
01955 return true;
01956 }
01957
01958
01959 HomgPoint2D TriTensor::get_epipole_12() const
01960 {
01961 get_epipoles(0,0);
01962 return *e12_;
01963 }
01964
01965
01966 HomgPoint2D TriTensor::get_epipole_13() const
01967 {
01968 get_epipoles(0,0);
01969 return *e13_;
01970 }
01971
01972
01973 FMatrix TriTensor::get_fmatrix_12() const
01974 {
01975 get_epipoles(0,0);
01976 return FMatrix(vnl_cross_product_matrix(e12_->get_vector()) * dot3(e13_->get_vector().as_ref()).transpose().as_ref());
01977 }
01978
01979
01980 FMatrix TriTensor::get_fmatrix_13() const
01981 {
01982 get_epipoles(0,0);
01983 return FMatrix(vnl_cross_product_matrix(e13_->get_vector()) * dot2(e12_->get_vector().as_ref()).transpose().as_ref());
01984 }
01985
01986 FMatrix TriTensor::compute_fmatrix_23() const
01987 {
01988 PMatrix P2, P3;
01989 compute_P_matrices(&P2, &P3);
01990 return FMatrix(P2, P3);
01991 }
01992
01993
01994
01995 const FManifoldProject* TriTensor::get_fmp12() const
01996 {
01997
01998 if (!fmp12_) fmp12_ = new FManifoldProject(get_fmatrix_12());
01999 return fmp12_;
02000 }
02001
02002
02003 const FManifoldProject* TriTensor::get_fmp13() const
02004 {
02005
02006 if (!fmp13_) fmp13_ = new FManifoldProject(get_fmatrix_13());
02007 return fmp13_;
02008 }
02009
02010
02011 const FManifoldProject* TriTensor::get_fmp23() const
02012 {
02013
02014 if (!fmp23_) {
02015
02016 PMatrix P2;
02017 PMatrix P3;
02018 compute_P_matrices(&P2, &P3);
02019 FMatrix f23(P2,P3);
02020
02021 fmp23_ = new FManifoldProject(f23);
02022 }
02023 return fmp23_;
02024 }
02025
02026
02027 void TriTensor::compute_P_matrices(const vnl_double_3& x, double alpha, double beta, PMatrix* P2, PMatrix* P3) const
02028 {
02029 HomgPoint2D e2 = get_epipole_12();
02030 HomgPoint2D e3 = get_epipole_13();
02031
02032 vnl_double_3x3 Te3 = dot3t(e3.as_ref());
02033 vnl_double_3x3 TTe2 = dot2t(e2.as_ref());
02034
02035 MATLABPRINT((vnl_matrix<double> const&)Te3);
02036 MATLABPRINT((vnl_matrix<double> const&)TTe2);
02037
02038 vnl_double_3x3 M = vnl_identity_3x3() - OuterProduct3x3(e3,e3);
02039
02040 vnl_double_3x3 B0 = -M * TTe2;
02041
02042 vnl_double_3x3 DIFF = B0 + TTe2 - OuterProduct3x3(e3, TTe2.transpose()*e3);
02043 double diffmag = DIFF.fro_norm();
02044 if (diffmag > 1e-12) {
02045 vcl_cerr << "TriTensor::compute_P_matrices: DIFF = " << DIFF << '\n';
02046 }
02047
02048 vnl_double_3x3& A0 = Te3;
02049
02050
02051
02052
02053
02054 P2->set(A0 + OuterProduct3x3(e2, x), beta*e2);
02055 P3->set(B0 + OuterProduct3x3(e3, x), alpha*e3);
02056
02057 vcl_cerr << *P2 << '\n'
02058 << *P3 << '\n';
02059
02060
02061 this->check_equal_up_to_scale(TriTensor(*P2, *P3));
02062 }
02063
02064 struct maxabs
02065 {
02066 int i, j, k;
02067 double maxval;
02068 maxabs(const TriTensor& T);
02069 };
02070
02071 maxabs::maxabs(const TriTensor& T) : i(0), j(0), k(0), maxval(0.0)
02072 {
02073 for (int i = 0; i < 3; ++i)
02074 for (int j = 0; j < 3; ++j)
02075 for (int k = 0; k < 3; ++k) {
02076 double v = vcl_fabs(T(i,j,k));
02077 if (v >= maxval) {
02078 maxval = v;
02079 this->i = i;
02080 this->j = j;
02081 this->k = k;
02082 }
02083 }
02084 }
02085
02086 static bool check_same(const TriTensor& T1, const TriTensor& T2)
02087 {
02088 maxabs m1(T1);
02089 double scale1 = 1/m1.maxval;
02090 double scale2 = 1/vcl_fabs(T2(m1.i,m1.j,m1.k));
02091
02092 double rms = 0;
02093 for (int i = 0; i < 3; ++i)
02094 for (int j = 0; j < 3; ++j)
02095 for (int k = 0; k < 3; ++k) {
02096 double d = T1(i,j,k)*scale1 - T2(i,j,k) * scale2;
02097 rms += d*d;
02098 }
02099
02100 rms /= 27;
02101
02102 if (rms > 1e-15) {
02103 vcl_cerr << "check_same: different TriTensors\n"
02104 << "T1 =\n" << T1
02105 << "T2 =\n" << T2;
02106 return false;
02107 }
02108
02109 return true;
02110 }
02111
02112
02113
02114
02115
02116 bool TriTensor::check_equal_up_to_scale(const TriTensor& that) const
02117 {
02118 return check_same(*this, that);
02119 }