21 #ifndef otbLineOfSightOptimizer_hxx
22 #define otbLineOfSightOptimizer_hxx
26 #include "vnl/vnl_inverse.h"
31 template <
class TPrecision,
class TLabel>
38 m_InvCumul = vnl_matrix<PrecisionType>(3, 3);
40 m_Identity = vnl_matrix<PrecisionType>(3, 3);
42 m_Identity.fill_diagonal(1.);
44 m_SecCumul = vnl_vector<PrecisionType>(3);
47 template <
class TPrecision,
class TLabel>
56 vnl_matrix<PrecisionType> idMinusViViT(3, 3);
57 vnl_matrix<PrecisionType> vi(3, 1);
58 vnl_vector<PrecisionType> si(3);
63 if (pointA->GetNumberOfPoints() != pointB->GetNumberOfPoints() || pointA->GetNumberOfPoints() < 2)
65 itkExceptionMacro(<<
"Points are missing in at least one of the input point sets.");
73 while (itPointA != pointA->GetPoints()->End() && itPointB != pointB->GetPoints()->End())
75 vi(0, 0) = itPointB.Value()[0] - itPointA.Value()[0];
76 vi(1, 0) = itPointB.Value()[1] - itPointA.Value()[1];
77 vi(2, 0) = itPointB.Value()[2] - itPointA.Value()[2];
79 PrecisionType norm_inv = 1. / std::sqrt(vi(0, 0) * vi(0, 0) + vi(1, 0) * vi(1, 0) + vi(2, 0) * vi(2, 0));
85 si(0) = itPointA.Value()[0];
86 si(1) = itPointA.Value()[1];
87 si(2) = itPointA.Value()[2];
89 idMinusViViT = m_Identity - (vi * vi.transpose());
91 m_InvCumul += idMinusViViT;
92 m_SecCumul += (idMinusViViT * si);
98 vnl_vector<PrecisionType> intersection = vnl_inverse(m_InvCumul) * m_SecCumul;
100 result[0] = intersection[0];
101 result[1] = intersection[1];
102 result[2] = intersection[2];
107 vnl_vector<PrecisionType> AB(3);
108 vnl_vector<PrecisionType> AC(3);
110 itPointA = pointA->GetPoints()->Begin();
111 itPointB = pointB->GetPoints()->Begin();
112 while (itPointA != pointA->GetPoints()->End() && itPointB != pointB->GetPoints()->End())
114 AB[0] = itPointB.Value()[0] - itPointA.Value()[0];
115 AB[1] = itPointB.Value()[1] - itPointA.Value()[1];
116 AB[2] = itPointB.Value()[2] - itPointA.Value()[2];
118 AC[0] = intersection[0] - itPointA.Value()[0];
119 AC[1] = intersection[1] - itPointA.Value()[1];
120 AC[2] = intersection[2] - itPointA.Value()[2];
122 res2 = std::max(0.0, dot_product(AC, AC) - (dot_product(AB, AC) * dot_product(AB, AC)) / (dot_product(AB, AB)));
124 m_Residues.push_back(std::sqrt(res2));
125 m_GlobalResidue += res2;
131 m_GlobalResidue = std::sqrt(m_GlobalResidue);