All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
AffineGT.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/AffineGT.cpp
22 
23  \brief 2D Geometric transformation.
24 */
25 
26 // TerraLib
27 #include "../common/MatrixUtils.h"
28 #include "AffineGT.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::AffineGT::getName() const
45 {
46  static std::string name( "Affine" );
47  return name;
48 }
49 
50 bool te::gm::AffineGT::isValid( const GTParameters& params ) const
51 {
52  return ( ( params.m_directParameters.size() == 6 ) &&
53  ( params.m_inverseParameters.size() == 6 ) );
54 }
55 
56 void te::gm::AffineGT::directMap( const GTParameters& params, const double& pt1X,
57  const double& pt1Y, double& pt2X, double& pt2Y ) const
58 {
59  assert( isValid( params ) );
60 
61  pt2X = ( params.m_directParameters[0] * pt1X ) +
62  ( params.m_directParameters[1] * pt1Y ) +
63  params.m_directParameters[2];
64  pt2Y = ( params.m_directParameters[3] * pt1X ) +
65  ( params.m_directParameters[4] * pt1Y ) +
66  params.m_directParameters[5];
67 }
68 
69 void te::gm::AffineGT::inverseMap( const GTParameters& params, const double& pt2X,
70  const double& pt2Y, double& pt1X, double& pt1Y ) const
71 {
72  assert( isValid( params ) );
73 
74  pt1X = ( params.m_inverseParameters[0] * pt2X ) +
75  ( params.m_inverseParameters[1] * pt2Y ) +
76  params.m_inverseParameters[2];
77  pt1Y = ( params.m_inverseParameters[3] * pt2X ) +
78  ( params.m_inverseParameters[4] * pt2Y ) +
79  params.m_inverseParameters[5];
80 }
81 
83 {
84  return 3;
85 }
86 
88 {
89  te::gm::AffineGT* newTransPtr = new AffineGT;
90  newTransPtr->m_internalParameters = m_internalParameters;
91  return newTransPtr;
92 };
93 
95 {
96  const unsigned int tiepointsSize = static_cast<unsigned int>(params.m_tiePoints.size());
97 
98  if( tiepointsSize < getMinRequiredTiePoints() )
99  return false;
100 
101  boost::numeric::ublas::matrix< double > L( 2*tiepointsSize, 1 );
102  boost::numeric::ublas::matrix< double > A( 2*tiepointsSize, 6 );
103  unsigned int index1 = 0;
104  unsigned int index2 = 0;
105 
106  for ( unsigned int tpIdx = 0 ; tpIdx < tiepointsSize ; ++tpIdx)
107  {
108  const Coord2D& x_y = params.m_tiePoints[ tpIdx ].first;
109  const Coord2D& u_v = params.m_tiePoints[ tpIdx ].second;
110 
111  index1 = tpIdx*2;
112  index2 = index1 + 1;
113 
114  A( index1, 0 ) = x_y.x ;
115  A( index1, 1 ) = x_y.y ;
116  A( index1, 2 ) = 1 ;
117  A( index1, 3 ) = 0 ;
118  A( index1, 4 ) = 0 ;
119  A( index1, 5 ) = 0 ;
120 
121  A( index2, 0 ) = 0 ;
122  A( index2, 1 ) = 0 ;
123  A( index2, 2 ) = 0 ;
124  A( index2, 3 ) = x_y.x ;
125  A( index2, 4 ) = x_y.y ;
126  A( index2, 5 ) = 1 ;
127 
128  L( index1, 0) = u_v.x;
129  L( index2, 0) = u_v.y;
130  }
131 
132  /* At calcule */
133  boost::numeric::ublas::matrix< double > At( boost::numeric::ublas::trans( A ) ) ;
134 
135  /* N calcule */
136  boost::numeric::ublas::matrix< double > N( boost::numeric::ublas::prod( At, A ) );
137 
138  /* U calcule */
139  boost::numeric::ublas::matrix< double > U( boost::numeric::ublas::prod( At, L ) );
140 
141  /* N_inv calcule */
142  boost::numeric::ublas::matrix< double > N_inv;
143 
144  if ( te::common::GetInverseMatrix( N, N_inv ) )
145  {
146  /* direct parameters calcule */
147 
148  boost::numeric::ublas::matrix< double > X(
149  boost::numeric::ublas::prod( N_inv, U ) );
150 
151  params.m_directParameters.resize( 6 );
152  params.m_directParameters[0] = X(0,0);
153  params.m_directParameters[1] = X(1,0);
154  params.m_directParameters[2] = X(2,0);
155  params.m_directParameters[3] = X(3,0);
156  params.m_directParameters[4] = X(4,0);
157  params.m_directParameters[5] = X(5,0);
158 
159  /* inverse parameters calcule */
160 
161  boost::numeric::ublas::matrix< double > XExpanded( 3, 3 );
162  XExpanded( 0, 0 ) = X(0,0);
163  XExpanded( 0, 1 ) = X(1,0);
164  XExpanded( 0, 2 ) = X(2,0);
165  XExpanded( 1, 0 ) = X(3,0);
166  XExpanded( 1, 1 ) = X(4,0);
167  XExpanded( 1, 2 ) = X(5,0);
168  XExpanded( 2, 0 ) = 0;
169  XExpanded( 2, 1 ) = 0;
170  XExpanded( 2, 2 ) = 1;
171 
172  boost::numeric::ublas::matrix< double > XExpandedInv;
173 
174  if( te::common::GetInverseMatrix( XExpanded, XExpandedInv ) )
175  {
176  params.m_inverseParameters.resize( 6 );
177  params.m_inverseParameters[0] = XExpandedInv(0,0);
178  params.m_inverseParameters[1] = XExpandedInv(0,1);
179  params.m_inverseParameters[2] = XExpandedInv(0,2);
180  params.m_inverseParameters[3] = XExpandedInv(1,0);
181  params.m_inverseParameters[4] = XExpandedInv(1,1);
182  params.m_inverseParameters[5] = XExpandedInv(1,2);
183 
184  return true;
185  }
186  else
187  {
188  return false;
189  }
190  }
191  else
192  {
193  return false;
194  }
195 }
196 
197 
198 bool te::gm::AffineGT::decompose( const std::vector< double >& transfParams,
199  double& translationX, double& translationY,
200  double& scalingFactorX, double& scalingFactorY, double& skew,
201  double& squeeze, double& scaling, double& rotation )
202 {
203  assert( transfParams.size() == 6 );
204 
205  double APar = transfParams[ 0 ];
206  double BPar = transfParams[ 1 ];
207  double CPar = transfParams[ 3 ];
208  double DPar = transfParams[ 4 ];
209 
210  double determinant = ( APar * DPar ) - ( BPar * CPar );
211 
212  if( determinant == 0.0 )
213  {
214  return false;
215  }
216  else if( determinant < 0.0 )
217  {
218  APar = transfParams[ 1 ];
219  BPar = transfParams[ 0 ];
220  CPar = transfParams[ 4 ];
221  DPar = transfParams[ 3 ];
222 
223  determinant = ( APar * DPar ) - ( BPar * CPar );
224  }
225 
226  const double FVar = 1.0 / ( ( APar * APar ) +
227  ( CPar * CPar ) );
228 
229  skew = ( ( APar * BPar ) + ( CPar * DPar ) ) * FVar;
230 
231  squeeze = 1.0 / sqrt( FVar * determinant );
232 
233  scaling = sqrt( determinant );
234 
235  scalingFactorX = scaling * squeeze;
236 
237  scalingFactorY = scaling / squeeze;
238 
239  translationX = transfParams[ 2 ];
240 
241  translationY = transfParams[ 5 ];
242 
243  rotation = atan( CPar / APar );
244 
245  return true;
246 }
247 
248 
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
double y
y-coordinate.
Definition: Coord2D.h:87
void directMap(const GTParameters &params, const double &pt1X, const double &pt1Y, double &pt2X, double &pt2Y) const
Direct mapping (from pt1 space into pt2 space).
Definition: AffineGT.cpp:56
double x
x-coordinate.
Definition: Coord2D.h:86
std::vector< double > m_directParameters
Transformation numeric direct parameters.
Definition: GTParameters.h:100
AffineGT()
Default constructor.
Definition: AffineGT.cpp:36
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
2D Geometric transformation base class.
2D Affine Geometric transformation.
Definition: AffineGT.h:65
~AffineGT()
Destructor.
Definition: AffineGT.cpp:40
GTParameters m_internalParameters
The current internal parameters.
const std::string & getName() const
Returns the current transformation name.
Definition: AffineGT.cpp:44
bool isValid() const
Tells if the current instance has a valid transformation.
bool computeParameters(GTParameters &params) const
Calculate the transformation parameters following the new supplied tie-points.
Definition: AffineGT.cpp:94
static bool decompose(const std::vector< double > &transfParams, double &translationX, double &translationY, double &scalingFactorX, double &scalingFactorY, double &skew, double &squeeze, double &scaling, double &rotation)
Returns the basic set of transform parameters given by the decomposition of a given affine transforma...
Definition: AffineGT.cpp:198
void inverseMap(const GTParameters &params, const double &pt2X, const double &pt2Y, double &pt1X, double &pt1Y) const
Inverse mapping (from pt2 space into pt1 space).
Definition: AffineGT.cpp:69
bool GetInverseMatrix(const boost::numeric::ublas::matrix< T > &inputMatrix, boost::numeric::ublas::matrix< T > &outputMatrix)
Matrix inversion.
Definition: MatrixUtils.h:104
std::vector< double > m_inverseParameters
Transformation numeric inverse parameters.
Definition: GTParameters.h:101
2D Geometric transformation parameters.
Definition: GTParameters.h:50
unsigned int getMinRequiredTiePoints() const
Returns the minimum number of required tie-points for the current transformation. ...
Definition: AffineGT.cpp:82
2D Affine Geometric transformation.
GeometricTransformation * clone() const
Creat a clone copy of this instance.
Definition: AffineGT.cpp:87