All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ThirdDegreePolynomialGT.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 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 
35 {
36 }
37 
39 {
40 }
41 
42 const std::string& te::gm::ThirdDegreePolynomialGT::getName() const
43 {
44  static std::string name( "ThirdDegreePolynomial" );
45  return name;
46 }
47 
49 {
50  return ( ( params.m_directParameters.size() == 20 ) &&
51  ( params.m_inverseParameters.size() == 20 ) );
52 }
53 
54 void te::gm::ThirdDegreePolynomialGT::directMap( const GTParameters& params, const double& pt1X,
55  const double& pt1Y, double& pt2X, double& pt2Y ) const
56 {
57  assert( isValid( params ) );
58 
59  pt2X =
60  params.m_directParameters[ 0 ] +
61  ( params.m_directParameters[ 1 ] * pt1X ) +
62  ( params.m_directParameters[ 2 ] * pt1Y ) +
63  ( params.m_directParameters[ 3 ] * pt1X * pt1X ) +
64  ( params.m_directParameters[ 4 ] * pt1X * pt1Y ) +
65  ( params.m_directParameters[ 5 ] * pt1Y * pt1Y ) +
66  ( params.m_directParameters[ 6 ] * pt1X * pt1X * pt1X ) +
67  ( params.m_directParameters[ 7 ] * pt1X * pt1X * pt1Y ) +
68  ( params.m_directParameters[ 8 ] * pt1X * pt1Y * pt1Y ) +
69  ( params.m_directParameters[ 9 ] * pt1Y * pt1Y * pt1Y );
70 
71  pt2Y =
72  params.m_directParameters[ 10 ] +
73  ( params.m_directParameters[ 11 ] * pt1X ) +
74  ( params.m_directParameters[ 12 ] * pt1Y ) +
75  ( params.m_directParameters[ 13 ] * pt1X * pt1X ) +
76  ( params.m_directParameters[ 14 ] * pt1X * pt1Y ) +
77  ( params.m_directParameters[ 15 ] * pt1Y * pt1Y ) +
78  ( params.m_directParameters[ 16 ] * pt1X * pt1X * pt1X ) +
79  ( params.m_directParameters[ 17 ] * pt1X * pt1X * pt1Y ) +
80  ( params.m_directParameters[ 18 ] * pt1X * pt1Y * pt1Y ) +
81  ( params.m_directParameters[ 19 ] * pt1Y * pt1Y * pt1Y );
82 }
83 
84 void te::gm::ThirdDegreePolynomialGT::inverseMap( const GTParameters& params, const double& pt2X,
85  const double& pt2Y, double& pt1X, double& pt1Y ) const
86 {
87  assert( isValid( params ) );
88 
89  pt1X =
90  params.m_inverseParameters[ 0 ] +
91  ( params.m_inverseParameters[ 1 ] * pt2X ) +
92  ( params.m_inverseParameters[ 2 ] * pt2Y ) +
93  ( params.m_inverseParameters[ 3 ] * pt2X * pt2X ) +
94  ( params.m_inverseParameters[ 4 ] * pt2X * pt2Y ) +
95  ( params.m_inverseParameters[ 5 ] * pt2Y * pt2Y ) +
96  ( params.m_inverseParameters[ 6 ] * pt2X * pt2X * pt2X ) +
97  ( params.m_inverseParameters[ 7 ] * pt2X * pt2X * pt2Y ) +
98  ( params.m_inverseParameters[ 8 ] * pt2X * pt2Y * pt2Y ) +
99  ( params.m_inverseParameters[ 9 ] * pt2Y * pt2Y * pt2Y );
100 
101  pt1Y =
102  params.m_inverseParameters[ 10 ] +
103  ( params.m_inverseParameters[ 11 ] * pt2X ) +
104  ( params.m_inverseParameters[ 12 ] * pt2Y ) +
105  ( params.m_inverseParameters[ 13 ] * pt2X * pt2X ) +
106  ( params.m_inverseParameters[ 14 ] * pt2X * pt2Y ) +
107  ( params.m_inverseParameters[ 15 ] * pt2Y * pt2Y ) +
108  ( params.m_inverseParameters[ 16 ] * pt2X * pt2X * pt2X ) +
109  ( params.m_inverseParameters[ 17 ] * pt2X * pt2X * pt2Y ) +
110  ( params.m_inverseParameters[ 18 ] * pt2X * pt2Y * pt2Y ) +
111  ( params.m_inverseParameters[ 19 ] * pt2Y * pt2Y * pt2Y );
112 
113 }
114 
116 {
117  return 11;
118 }
119 
121 {
123  newTransPtr->m_internalParameters = m_internalParameters;
124  return newTransPtr;
125 }
126 
128 {
129  // Creating the equation system parameters
130 
131  m_computeParameters_tiepointsSize = params.m_tiePoints.size();
132  if( m_computeParameters_tiepointsSize < getMinRequiredTiePoints() ) return false;
133 
134  m_computeParameters_W.resize( m_computeParameters_tiepointsSize, 10 );
135  m_computeParameters_WI.resize( m_computeParameters_tiepointsSize, 10 );
136  m_computeParameters_X.resize( m_computeParameters_tiepointsSize, 1 );
137  m_computeParameters_XI.resize( m_computeParameters_tiepointsSize, 1 );
138  m_computeParameters_Y.resize( m_computeParameters_tiepointsSize, 1 );
139  m_computeParameters_YI.resize( m_computeParameters_tiepointsSize, 1 );
140 
141  for ( m_computeParameters_tpIdx = 0 ; m_computeParameters_tpIdx < m_computeParameters_tiepointsSize ; ++m_computeParameters_tpIdx )
142  {
143  const Coord2D& pt1 = params.m_tiePoints[ m_computeParameters_tpIdx ].first;
144 
145  m_computeParameters_W( m_computeParameters_tpIdx, 0 ) = 1;
146  m_computeParameters_W( m_computeParameters_tpIdx, 1 ) = pt1.x;
147  m_computeParameters_W( m_computeParameters_tpIdx, 2 ) = pt1.y;
148  m_computeParameters_W( m_computeParameters_tpIdx, 3 ) = pt1.x * pt1.x;
149  m_computeParameters_W( m_computeParameters_tpIdx, 4 ) = pt1.x * pt1.y;
150  m_computeParameters_W( m_computeParameters_tpIdx, 5 ) = pt1.y * pt1.y;
151  m_computeParameters_W( m_computeParameters_tpIdx, 6 ) = pt1.x * pt1.x * pt1.x;
152  m_computeParameters_W( m_computeParameters_tpIdx, 7 ) = pt1.x * pt1.x * pt1.y;
153  m_computeParameters_W( m_computeParameters_tpIdx, 8 ) = pt1.x * pt1.y * pt1.y;
154  m_computeParameters_W( m_computeParameters_tpIdx, 9 ) = pt1.y * pt1.y * pt1.y;
155 
156  const Coord2D& pt2 = params.m_tiePoints[ m_computeParameters_tpIdx ].second;
157 
158  m_computeParameters_WI( m_computeParameters_tpIdx, 0 ) = 1;
159  m_computeParameters_WI( m_computeParameters_tpIdx, 1 ) = pt2.x;
160  m_computeParameters_WI( m_computeParameters_tpIdx, 2 ) = pt2.y;
161  m_computeParameters_WI( m_computeParameters_tpIdx, 3 ) = pt2.x * pt2.x;
162  m_computeParameters_WI( m_computeParameters_tpIdx, 4 ) = pt2.x * pt2.y;
163  m_computeParameters_WI( m_computeParameters_tpIdx, 5 ) = pt2.y * pt2.y;
164  m_computeParameters_WI( m_computeParameters_tpIdx, 6 ) = pt2.x * pt2.x * pt2.x;
165  m_computeParameters_WI( m_computeParameters_tpIdx, 7 ) = pt2.x * pt2.x * pt2.y;
166  m_computeParameters_WI( m_computeParameters_tpIdx, 8 ) = pt2.x * pt2.y * pt2.y;
167  m_computeParameters_WI( m_computeParameters_tpIdx, 9 ) = pt2.y * pt2.y * pt2.y;
168 
169  m_computeParameters_X( m_computeParameters_tpIdx, 0 ) = pt2.x;
170 
171  m_computeParameters_XI( m_computeParameters_tpIdx, 0 ) = pt1.x;
172 
173  m_computeParameters_Y( m_computeParameters_tpIdx, 0 ) = pt2.y;
174 
175  m_computeParameters_YI( m_computeParameters_tpIdx, 0 ) = pt1.y;
176  }
177 
178  // Solving...
179 
180  if( ! te::common::GetPseudoInverseMatrix( m_computeParameters_W, m_computeParameters_PinvW ) ) return false;
181 
182  if( ! te::common::GetPseudoInverseMatrix( m_computeParameters_WI, m_computeParameters_PinvWI ) ) return false;
183 
184  m_computeParameters_A = boost::numeric::ublas::prod( m_computeParameters_PinvW, m_computeParameters_X );
185 
186  m_computeParameters_AI = boost::numeric::ublas::prod( m_computeParameters_PinvWI, m_computeParameters_XI );
187 
188  m_computeParameters_B = boost::numeric::ublas::prod( m_computeParameters_PinvW, m_computeParameters_Y );
189 
190  m_computeParameters_BI = boost::numeric::ublas::prod( m_computeParameters_PinvWI, m_computeParameters_YI );
191 
192  // Copying the parameters to output
193 
194  params.m_directParameters.resize( 20 );
195  params.m_directParameters[ 0 ] = m_computeParameters_A( 0, 0 );
196  params.m_directParameters[ 1 ] = m_computeParameters_A( 1, 0 );
197  params.m_directParameters[ 2 ] = m_computeParameters_A( 2, 0 );
198  params.m_directParameters[ 3 ] = m_computeParameters_A( 3, 0 );
199  params.m_directParameters[ 4 ] = m_computeParameters_A( 4, 0 );
200  params.m_directParameters[ 5 ] = m_computeParameters_A( 5, 0 );
201  params.m_directParameters[ 6 ] = m_computeParameters_A( 6, 0 );
202  params.m_directParameters[ 7 ] = m_computeParameters_A( 7, 0 );
203  params.m_directParameters[ 8 ] = m_computeParameters_A( 8, 0 );
204  params.m_directParameters[ 9 ] = m_computeParameters_A( 9, 0 );
205  params.m_directParameters[ 10 ] = m_computeParameters_B( 0, 0 );
206  params.m_directParameters[ 11 ] = m_computeParameters_B( 1, 0 );
207  params.m_directParameters[ 12 ] = m_computeParameters_B( 2, 0 );
208  params.m_directParameters[ 13 ] = m_computeParameters_B( 3, 0 );
209  params.m_directParameters[ 14 ] = m_computeParameters_B( 4, 0 );
210  params.m_directParameters[ 15 ] = m_computeParameters_B( 5, 0 );
211  params.m_directParameters[ 16 ] = m_computeParameters_B( 6, 0 );
212  params.m_directParameters[ 17 ] = m_computeParameters_B( 7, 0 );
213  params.m_directParameters[ 18 ] = m_computeParameters_B( 8, 0 );
214  params.m_directParameters[ 19 ] = m_computeParameters_B( 9, 0 );
215 
216  params.m_inverseParameters.resize( 20 );
217  params.m_inverseParameters[ 0 ] = m_computeParameters_AI( 0, 0 );
218  params.m_inverseParameters[ 1 ] = m_computeParameters_AI( 1, 0 );
219  params.m_inverseParameters[ 2 ] = m_computeParameters_AI( 2, 0 );
220  params.m_inverseParameters[ 3 ] = m_computeParameters_AI( 3, 0 );
221  params.m_inverseParameters[ 4 ] = m_computeParameters_AI( 4, 0 );
222  params.m_inverseParameters[ 5 ] = m_computeParameters_AI( 5, 0 );
223  params.m_inverseParameters[ 6 ] = m_computeParameters_AI( 6, 0 );
224  params.m_inverseParameters[ 7 ] = m_computeParameters_AI( 7, 0 );
225  params.m_inverseParameters[ 8 ] = m_computeParameters_AI( 8, 0 );
226  params.m_inverseParameters[ 9 ] = m_computeParameters_AI( 9, 0 );
227  params.m_inverseParameters[ 10 ] = m_computeParameters_BI( 0, 0 );
228  params.m_inverseParameters[ 11 ] = m_computeParameters_BI( 1, 0 );
229  params.m_inverseParameters[ 12 ] = m_computeParameters_BI( 2, 0 );
230  params.m_inverseParameters[ 13 ] = m_computeParameters_BI( 3, 0 );
231  params.m_inverseParameters[ 14 ] = m_computeParameters_BI( 4, 0 );
232  params.m_inverseParameters[ 15 ] = m_computeParameters_BI( 5, 0 );
233  params.m_inverseParameters[ 16 ] = m_computeParameters_BI( 6, 0 );
234  params.m_inverseParameters[ 17 ] = m_computeParameters_BI( 7, 0 );
235  params.m_inverseParameters[ 18 ] = m_computeParameters_BI( 8, 0 );
236  params.m_inverseParameters[ 19 ] = m_computeParameters_BI( 9, 0 );
237 
238  return true;
239 }
240 
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
double y
y-coordinate.
Definition: Coord2D.h:114
double x
x-coordinate.
Definition: Coord2D.h:113
Third Degree Polynomial Geometric 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).
bool computeParameters(GTParameters &params) const
Calculate the transformation parameters following the new supplied tie-points.
std::vector< double > m_directParameters
Transformation numeric direct parameters.
Definition: GTParameters.h:100
GeometricTransformation * clone() const
Creat a clone copy of this instance.
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
2D Geometric transformation base class.
void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const
Direct mapping (from pt1 space into pt2 space).
bool GetPseudoInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Pseudo matrix inversion.
Definition: MatrixUtils.h:152
GTParameters m_internalParameters
The current internal parameters.
Third Degree Polynomial Geometric transformation.
bool isValid() const
Tells if the current instance has a valid transformation.
const std::string & getName() const
Returns the current transformation name.
std::vector< double > m_inverseParameters
Transformation numeric inverse parameters.
Definition: GTParameters.h:101
2D Geometric transformation parameters.
Definition: GTParameters.h:50
ThirdDegreePolynomialGT()
Default constructor.
unsigned int getMinRequiredTiePoints() const
Returns the minimum number of required tie-points for the current transformation. ...