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 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 
35 {
36 }
37 
39 {
40 }
41 
42 const std::string& te::gm::AffineGT::getName() const
43 {
44  static std::string name( "Affine" );
45  return name;
46 }
47 
48 bool te::gm::AffineGT::isValid( const GTParameters& params ) const
49 {
50  return ( ( params.m_directParameters.size() == 6 ) &&
51  ( params.m_inverseParameters.size() == 6 ) );
52 }
53 
54 void te::gm::AffineGT::directMap( const GTParameters& params, const double& pt1X,
55  const double& pt1Y, double& pt2X, double& pt2Y ) const
56 {
57  assert( isValid( params ) );
58 
59  pt2X = ( params.m_directParameters[0] * pt1X ) +
60  ( params.m_directParameters[1] * pt1Y ) +
61  params.m_directParameters[2];
62  pt2Y = ( params.m_directParameters[3] * pt1X ) +
63  ( params.m_directParameters[4] * pt1Y ) +
64  params.m_directParameters[5];
65 }
66 
67 void te::gm::AffineGT::inverseMap( const GTParameters& params, const double& pt2X,
68  const double& pt2Y, double& pt1X, double& pt1Y ) const
69 {
70  assert( isValid( params ) );
71 
72  pt1X = ( params.m_inverseParameters[0] * pt2X ) +
73  ( params.m_inverseParameters[1] * pt2Y ) +
74  params.m_inverseParameters[2];
75  pt1Y = ( params.m_inverseParameters[3] * pt2X ) +
76  ( params.m_inverseParameters[4] * pt2Y ) +
77  params.m_inverseParameters[5];
78 }
79 
81 {
82  return 3;
83 }
84 
86 {
87  te::gm::AffineGT* newTransPtr = new AffineGT;
88  newTransPtr->m_internalParameters = m_internalParameters;
89  return newTransPtr;
90 }
91 
93 {
94  m_computeParameters_tiepointsSize = static_cast<unsigned int>(params.m_tiePoints.size());
95 
96  if( m_computeParameters_tiepointsSize < getMinRequiredTiePoints() )
97  return false;
98 
99  m_computeParameters_L.resize( 2*m_computeParameters_tiepointsSize, 1 );
100  m_computeParameters_A.resize( 2*m_computeParameters_tiepointsSize, 6 );
101  m_computeParameters_index1 = 0;
102  m_computeParameters_index2 = 0;
103 
104  for ( m_computeParameters_tpIdx = 0 ; m_computeParameters_tpIdx < m_computeParameters_tiepointsSize ; ++m_computeParameters_tpIdx)
105  {
106  const Coord2D& x_y = params.m_tiePoints[ m_computeParameters_tpIdx ].first;
107  const Coord2D& u_v = params.m_tiePoints[ m_computeParameters_tpIdx ].second;
108 
109  m_computeParameters_index1 = m_computeParameters_tpIdx*2;
110  m_computeParameters_index2 = m_computeParameters_index1 + 1;
111 
112  m_computeParameters_A( m_computeParameters_index1, 0 ) = x_y.x ;
113  m_computeParameters_A( m_computeParameters_index1, 1 ) = x_y.y ;
114  m_computeParameters_A( m_computeParameters_index1, 2 ) = 1 ;
115  m_computeParameters_A( m_computeParameters_index1, 3 ) = 0 ;
116  m_computeParameters_A( m_computeParameters_index1, 4 ) = 0 ;
117  m_computeParameters_A( m_computeParameters_index1, 5 ) = 0 ;
118 
119  m_computeParameters_A( m_computeParameters_index2, 0 ) = 0 ;
120  m_computeParameters_A( m_computeParameters_index2, 1 ) = 0 ;
121  m_computeParameters_A( m_computeParameters_index2, 2 ) = 0 ;
122  m_computeParameters_A( m_computeParameters_index2, 3 ) = x_y.x ;
123  m_computeParameters_A( m_computeParameters_index2, 4 ) = x_y.y ;
124  m_computeParameters_A( m_computeParameters_index2, 5 ) = 1 ;
125 
126  m_computeParameters_L( m_computeParameters_index1, 0) = u_v.x;
127  m_computeParameters_L( m_computeParameters_index2, 0) = u_v.y;
128  }
129 
130  /* At calcule */
131  m_computeParameters_At = boost::numeric::ublas::trans( m_computeParameters_A );
132 
133  /* N calcule */
134  m_computeParameters_N = boost::numeric::ublas::prod( m_computeParameters_At, m_computeParameters_A );
135 
136  /* U calcule */
137  m_computeParameters_U = boost::numeric::ublas::prod( m_computeParameters_At, m_computeParameters_L );
138 
139  /* N_inv calcule */
140 
141  if ( te::common::GetInverseMatrix( m_computeParameters_N, m_computeParameters_N_inv ) )
142  {
143  /* direct parameters calcule */
144 
145  m_computeParameters_X = boost::numeric::ublas::prod( m_computeParameters_N_inv,
146  m_computeParameters_U );
147 
148  params.m_directParameters.resize( 6 );
149  params.m_directParameters[0] = m_computeParameters_X(0,0);
150  params.m_directParameters[1] = m_computeParameters_X(1,0);
151  params.m_directParameters[2] = m_computeParameters_X(2,0);
152  params.m_directParameters[3] = m_computeParameters_X(3,0);
153  params.m_directParameters[4] = m_computeParameters_X(4,0);
154  params.m_directParameters[5] = m_computeParameters_X(5,0);
155 
156  /* inverse parameters calcule */
157 
158  m_computeParameters_XExpanded.resize( 3, 3 );
159  m_computeParameters_XExpanded( 0, 0 ) = m_computeParameters_X(0,0);
160  m_computeParameters_XExpanded( 0, 1 ) = m_computeParameters_X(1,0);
161  m_computeParameters_XExpanded( 0, 2 ) = m_computeParameters_X(2,0);
162  m_computeParameters_XExpanded( 1, 0 ) = m_computeParameters_X(3,0);
163  m_computeParameters_XExpanded( 1, 1 ) = m_computeParameters_X(4,0);
164  m_computeParameters_XExpanded( 1, 2 ) = m_computeParameters_X(5,0);
165  m_computeParameters_XExpanded( 2, 0 ) = 0;
166  m_computeParameters_XExpanded( 2, 1 ) = 0;
167  m_computeParameters_XExpanded( 2, 2 ) = 1;
168 
169  if( te::common::GetInverseMatrix( m_computeParameters_XExpanded, m_computeParameters_XExpandedInv ) )
170  {
171  params.m_inverseParameters.resize( 6 );
172  params.m_inverseParameters[0] = m_computeParameters_XExpandedInv(0,0);
173  params.m_inverseParameters[1] = m_computeParameters_XExpandedInv(0,1);
174  params.m_inverseParameters[2] = m_computeParameters_XExpandedInv(0,2);
175  params.m_inverseParameters[3] = m_computeParameters_XExpandedInv(1,0);
176  params.m_inverseParameters[4] = m_computeParameters_XExpandedInv(1,1);
177  params.m_inverseParameters[5] = m_computeParameters_XExpandedInv(1,2);
178 
179  return true;
180  }
181  else
182  {
183  return false;
184  }
185  }
186  else
187  {
188  return false;
189  }
190 }
191 
192 
193 bool te::gm::AffineGT::decompose( const std::vector< double >& transfParams,
194  double& translationX, double& translationY,
195  double& scalingFactorX, double& scalingFactorY, double& skew,
196  double& squeeze, double& scaling, double& rotation )
197 {
198  assert( transfParams.size() == 6 );
199 
200  double APar = transfParams[ 0 ];
201  double BPar = transfParams[ 1 ];
202  double CPar = transfParams[ 3 ];
203  double DPar = transfParams[ 4 ];
204 
205  double determinant = ( APar * DPar ) - ( BPar * CPar );
206 
207  if( determinant == 0.0 )
208  {
209  return false;
210  }
211  else if( determinant < 0.0 )
212  {
213  APar = transfParams[ 1 ];
214  BPar = transfParams[ 0 ];
215  CPar = transfParams[ 4 ];
216  DPar = transfParams[ 3 ];
217 
218  determinant = ( APar * DPar ) - ( BPar * CPar );
219 
220  const double FVar = 1.0 / ( ( APar * APar ) +
221  ( CPar * CPar ) );
222 
223  skew = ( ( APar * BPar ) + ( CPar * DPar ) ) * FVar;
224 
225  squeeze = 1.0 / sqrt( FVar * determinant );
226 
227  scaling = sqrt( determinant );
228 
229  scalingFactorX = scaling / squeeze;
230 
231  scalingFactorY = scaling * squeeze;
232 
233  rotation = atan( APar / CPar );
234  }
235  else
236  {
237  const double FVar = 1.0 / ( ( APar * APar ) +
238  ( CPar * CPar ) );
239 
240  skew = ( ( APar * BPar ) + ( CPar * DPar ) ) * FVar;
241 
242  squeeze = 1.0 / sqrt( FVar * determinant );
243 
244  scaling = sqrt( determinant );
245 
246  scalingFactorX = scaling * squeeze;
247 
248  scalingFactorY = scaling / squeeze;
249 
250  rotation = atan( CPar / APar );
251  }
252 
253  translationX = transfParams[ 2 ];
254 
255  translationY = transfParams[ 5 ];
256 
257  return true;
258 }
259 
260 
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
double y
y-coordinate.
Definition: Coord2D.h:114
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:54
double x
x-coordinate.
Definition: Coord2D.h:113
std::vector< double > m_directParameters
Transformation numeric direct parameters.
Definition: GTParameters.h:100
AffineGT()
Default constructor.
Definition: AffineGT.cpp:34
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
2D Geometric transformation base class.
2D Affine Geometric transformation.
Definition: AffineGT.h:66
~AffineGT()
Destructor.
Definition: AffineGT.cpp:38
GTParameters m_internalParameters
The current internal parameters.
const std::string & getName() const
Returns the current transformation name.
Definition: AffineGT.cpp:42
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:92
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:193
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:67
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:80
2D Affine Geometric transformation.
GeometricTransformation * clone() const
Creat a clone copy of this instance.
Definition: AffineGT.cpp:85