All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ThirdDegreePolynomialGT.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008-2013 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/geometry/ThirdDegreePolynomialGT.cpp
22 
23  \brief Third Degree Polynomial Geometric transformation.
24 */
25 
26 // TerraLib
27 #include "../common/MatrixUtils.h"
29 
30 // STL
31 #include <cmath>
32 
33 // Boost
34 #include <boost/numeric/ublas/matrix.hpp>
35 
37 {
38 }
39 
41 {
42 }
43 
44 const std::string& te::gm::ThirdDegreePolynomialGT::getName() const
45 {
46  static std::string name( "ThirdDegreePolynomial" );
47  return name;
48 }
49 
51 {
52  return ( ( params.m_directParameters.size() == 20 ) &&
53  ( params.m_inverseParameters.size() == 20 ) );
54 }
55 
56 void te::gm::ThirdDegreePolynomialGT::directMap( const GTParameters& params, const double& pt1X,
57  const double& pt1Y, double& pt2X, double& pt2Y ) const
58 {
59  assert( isValid( params ) );
60 
61  pt2X =
62  params.m_directParameters[ 0 ] +
63  ( params.m_directParameters[ 1 ] * pt1X ) +
64  ( params.m_directParameters[ 2 ] * pt1Y ) +
65  ( params.m_directParameters[ 3 ] * pt1X * pt1X ) +
66  ( params.m_directParameters[ 4 ] * pt1X * pt1Y ) +
67  ( params.m_directParameters[ 5 ] * pt1Y * pt1Y ) +
68  ( params.m_directParameters[ 6 ] * pt1X * pt1X * pt1X ) +
69  ( params.m_directParameters[ 7 ] * pt1X * pt1X * pt1Y ) +
70  ( params.m_directParameters[ 8 ] * pt1X * pt1Y * pt1Y ) +
71  ( params.m_directParameters[ 9 ] * pt1Y * pt1Y * pt1Y );
72 
73  pt2Y =
74  params.m_directParameters[ 10 ] +
75  ( params.m_directParameters[ 11 ] * pt1X ) +
76  ( params.m_directParameters[ 12 ] * pt1Y ) +
77  ( params.m_directParameters[ 13 ] * pt1X * pt1X ) +
78  ( params.m_directParameters[ 14 ] * pt1X * pt1Y ) +
79  ( params.m_directParameters[ 15 ] * pt1Y * pt1Y ) +
80  ( params.m_directParameters[ 16 ] * pt1X * pt1X * pt1X ) +
81  ( params.m_directParameters[ 17 ] * pt1X * pt1X * pt1Y ) +
82  ( params.m_directParameters[ 18 ] * pt1X * pt1Y * pt1Y ) +
83  ( params.m_directParameters[ 19 ] * pt1Y * pt1Y * pt1Y );
84 }
85 
86 void te::gm::ThirdDegreePolynomialGT::inverseMap( const GTParameters& params, const double& pt2X,
87  const double& pt2Y, double& pt1X, double& pt1Y ) const
88 {
89  assert( isValid( params ) );
90 
91  pt1X =
92  params.m_inverseParameters[ 0 ] +
93  ( params.m_inverseParameters[ 1 ] * pt2X ) +
94  ( params.m_inverseParameters[ 2 ] * pt2Y ) +
95  ( params.m_inverseParameters[ 3 ] * pt2X * pt2X ) +
96  ( params.m_inverseParameters[ 4 ] * pt2X * pt2Y ) +
97  ( params.m_inverseParameters[ 5 ] * pt2Y * pt2Y ) +
98  ( params.m_inverseParameters[ 6 ] * pt2X * pt2X * pt2X ) +
99  ( params.m_inverseParameters[ 7 ] * pt2X * pt2X * pt2Y ) +
100  ( params.m_inverseParameters[ 8 ] * pt2X * pt2Y * pt2Y ) +
101  ( params.m_inverseParameters[ 9 ] * pt2Y * pt2Y * pt2Y );
102 
103  pt1Y =
104  params.m_inverseParameters[ 10 ] +
105  ( params.m_inverseParameters[ 11 ] * pt2X ) +
106  ( params.m_inverseParameters[ 12 ] * pt2Y ) +
107  ( params.m_inverseParameters[ 13 ] * pt2X * pt2X ) +
108  ( params.m_inverseParameters[ 14 ] * pt2X * pt2Y ) +
109  ( params.m_inverseParameters[ 15 ] * pt2Y * pt2Y ) +
110  ( params.m_inverseParameters[ 16 ] * pt2X * pt2X * pt2X ) +
111  ( params.m_inverseParameters[ 17 ] * pt2X * pt2X * pt2Y ) +
112  ( params.m_inverseParameters[ 18 ] * pt2X * pt2Y * pt2Y ) +
113  ( params.m_inverseParameters[ 19 ] * pt2Y * pt2Y * pt2Y );
114 
115 }
116 
118 {
119  return 11;
120 }
121 
123 {
125  newTransPtr->m_internalParameters = m_internalParameters;
126  return newTransPtr;
127 };
128 
130 {
131  // Creating the equation system parameters
132 
133  const unsigned int tiepointsSize = params.m_tiePoints.size();
134  if( tiepointsSize < getMinRequiredTiePoints() ) return false;
135 
136  boost::numeric::ublas::matrix< double > W( tiepointsSize, 10 );
137  boost::numeric::ublas::matrix< double > WI( tiepointsSize, 10 );
138  boost::numeric::ublas::matrix< double > X( tiepointsSize, 1 );
139  boost::numeric::ublas::matrix< double > XI( tiepointsSize, 1 );
140  boost::numeric::ublas::matrix< double > Y( tiepointsSize, 1 );
141  boost::numeric::ublas::matrix< double > YI( tiepointsSize, 1 );
142 
143  for ( unsigned int tpIdx = 0 ; tpIdx < tiepointsSize ; ++tpIdx )
144  {
145  const Coord2D& pt1 = params.m_tiePoints[ tpIdx ].first;
146 
147  W( tpIdx, 0 ) = 1;
148  W( tpIdx, 1 ) = pt1.x;
149  W( tpIdx, 2 ) = pt1.y;
150  W( tpIdx, 3 ) = pt1.x * pt1.x;
151  W( tpIdx, 4 ) = pt1.x * pt1.y;
152  W( tpIdx, 5 ) = pt1.y * pt1.y;
153  W( tpIdx, 6 ) = pt1.x * pt1.x * pt1.x;
154  W( tpIdx, 7 ) = pt1.x * pt1.x * pt1.y;
155  W( tpIdx, 8 ) = pt1.x * pt1.y * pt1.y;
156  W( tpIdx, 9 ) = pt1.y * pt1.y * pt1.y;
157 
158  const Coord2D& pt2 = params.m_tiePoints[ tpIdx ].second;
159 
160  WI( tpIdx, 0 ) = 1;
161  WI( tpIdx, 1 ) = pt2.x;
162  WI( tpIdx, 2 ) = pt2.y;
163  WI( tpIdx, 3 ) = pt2.x * pt2.x;
164  WI( tpIdx, 4 ) = pt2.x * pt2.y;
165  WI( tpIdx, 5 ) = pt2.y * pt2.y;
166  WI( tpIdx, 6 ) = pt2.x * pt2.x * pt2.x;
167  WI( tpIdx, 7 ) = pt2.x * pt2.x * pt2.y;
168  WI( tpIdx, 8 ) = pt2.x * pt2.y * pt2.y;
169  WI( tpIdx, 9 ) = pt2.y * pt2.y * pt2.y;
170 
171  X( tpIdx, 0 ) = pt2.x;
172 
173  XI( tpIdx, 0 ) = pt1.x;
174 
175  Y( tpIdx, 0 ) = pt2.y;
176 
177  YI( tpIdx, 0 ) = pt1.y;
178  }
179 
180  // Solving...
181 
182  boost::numeric::ublas::matrix< double > PinvW;
183  if( ! te::common::getPseudoInverseMatrix( W, PinvW ) ) return false;
184 
185  boost::numeric::ublas::matrix< double > PinvWI;
186  if( ! te::common::getPseudoInverseMatrix( WI, PinvWI ) ) return false;
187 
188  boost::numeric::ublas::matrix< double > A( boost::numeric::ublas::prod( PinvW, X ) );
189 
190  boost::numeric::ublas::matrix< double > AI( boost::numeric::ublas::prod( PinvWI, XI ) );
191 
192  boost::numeric::ublas::matrix< double > B( boost::numeric::ublas::prod( PinvW, Y ) );
193 
194  boost::numeric::ublas::matrix< double > BI( boost::numeric::ublas::prod( PinvWI, YI ) );
195 
196  // Copying the parameters to output
197 
198  params.m_directParameters.resize( 20 );
199  params.m_directParameters[ 0 ] = A( 0, 0 );
200  params.m_directParameters[ 1 ] = A( 1, 0 );
201  params.m_directParameters[ 2 ] = A( 2, 0 );
202  params.m_directParameters[ 3 ] = A( 3, 0 );
203  params.m_directParameters[ 4 ] = A( 4, 0 );
204  params.m_directParameters[ 5 ] = A( 5, 0 );
205  params.m_directParameters[ 6 ] = A( 6, 0 );
206  params.m_directParameters[ 7 ] = A( 7, 0 );
207  params.m_directParameters[ 8 ] = A( 8, 0 );
208  params.m_directParameters[ 9 ] = A( 9, 0 );
209  params.m_directParameters[ 10 ] = B( 0, 0 );
210  params.m_directParameters[ 11 ] = B( 1, 0 );
211  params.m_directParameters[ 12 ] = B( 2, 0 );
212  params.m_directParameters[ 13 ] = B( 3, 0 );
213  params.m_directParameters[ 14 ] = B( 4, 0 );
214  params.m_directParameters[ 15 ] = B( 5, 0 );
215  params.m_directParameters[ 16 ] = B( 6, 0 );
216  params.m_directParameters[ 17 ] = B( 7, 0 );
217  params.m_directParameters[ 18 ] = B( 8, 0 );
218  params.m_directParameters[ 19 ] = B( 9, 0 );
219 
220  params.m_inverseParameters.resize( 20 );
221  params.m_inverseParameters[ 0 ] = AI( 0, 0 );
222  params.m_inverseParameters[ 1 ] = AI( 1, 0 );
223  params.m_inverseParameters[ 2 ] = AI( 2, 0 );
224  params.m_inverseParameters[ 3 ] = AI( 3, 0 );
225  params.m_inverseParameters[ 4 ] = AI( 4, 0 );
226  params.m_inverseParameters[ 5 ] = AI( 5, 0 );
227  params.m_inverseParameters[ 6 ] = AI( 6, 0 );
228  params.m_inverseParameters[ 7 ] = AI( 7, 0 );
229  params.m_inverseParameters[ 8 ] = AI( 8, 0 );
230  params.m_inverseParameters[ 9 ] = AI( 9, 0 );
231  params.m_inverseParameters[ 10 ] = BI( 0, 0 );
232  params.m_inverseParameters[ 11 ] = BI( 1, 0 );
233  params.m_inverseParameters[ 12 ] = BI( 2, 0 );
234  params.m_inverseParameters[ 13 ] = BI( 3, 0 );
235  params.m_inverseParameters[ 14 ] = BI( 4, 0 );
236  params.m_inverseParameters[ 15 ] = BI( 5, 0 );
237  params.m_inverseParameters[ 16 ] = BI( 6, 0 );
238  params.m_inverseParameters[ 17 ] = BI( 7, 0 );
239  params.m_inverseParameters[ 18 ] = BI( 8, 0 );
240  params.m_inverseParameters[ 19 ] = BI( 9, 0 );
241 
242  return true;
243 }
244 
ThirdDegreePolynomialGT()
Default constructor.
bool getPseudoInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Pseudo matrix inversion.
Definition: MatrixUtils.h:152
unsigned int getMinRequiredTiePoints() const
Returns the minimum number of required tie-points for the current transformation. ...
void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const
Inverse mapping (from pt2 space into pt1 space).
double y
y-coordinate.
Definition: Coord2D.h:87
GeometricTransformation * clone() const
Creat a clone copy of this instance.
Third Degree Polynomial Geometric transformation.
Third Degree Polynomial Geometric transformation.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
bool computeParameters(GTParameters &params) const
Calculate the transformation parameters following the new supplied tie-points.
bool isValid() const
Tells if the current instance has a valid transformation.
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
const std::string & getName() const
Returns the current transformation name.
GTParameters m_internalParameters
The current internal parameters.
std::vector< double > m_inverseParameters
Transformation numeric inverse parameters.
Definition: GTParameters.h:101
2D Geometric transformation base class.
std::vector< double > m_directParameters
Transformation numeric direct parameters.
Definition: GTParameters.h:100
2D Geometric transformation parameters.
Definition: GTParameters.h:50
double x
x-coordinate.
Definition: Coord2D.h:86
void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const
Direct mapping (from pt1 space into pt2 space).