OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossim2dTo2dTransform.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Garrett Potts
9 //
10 //*************************************************************************
11 // $Id: ossim2dTo2dTransform.cpp 15766 2009-10-20 12:37:09Z gpotts $
12 
13 #include <cstdlib>
14 #include <sstream>
16 
17 
18 RTTI_DEF1(ossim2dTo2dTransform, "ossim2dTo2dTransform", ossimObject);
19 
23 
24 // ### CREATE_COPY ###
25 // Implementation of static factory method createCopy() requires includes here of ALL 2D-to-2D
26 // transform types that need a deep copy capability:
33 
34 //***
35 // Define Trace flags for use within this file:
36 //***
37 #include <ossim/base/ossimTrace.h>
38 static ossimTrace traceExec ("ossim2dTo2dTransform:exec");
39 static ossimTrace traceDebug ("ossim2dTo2dTransform:debug");
40 
41 static const double DEFAULT_THRESHOLD = 1000.0*DBL_EPSILON;
42 static const int DEFAULT_MAX_ITERATIONS = 10;
43 
44 //*****************************************************************************
45 // CONSTRUCTOR:
46 //*****************************************************************************
48  :
49  theConvergenceThreshold (DEFAULT_THRESHOLD),
50  theMaxIterations (DEFAULT_MAX_ITERATIONS),
51  theDxDy(1.0, 1.0)
52 {
53 }
54 
55 //*****************************************************************************
56 // METHOD:
57 //*****************************************************************************
59  ossimDpt& output) const
60 {
61  static const char MODULE[] = "ossim2dTo2dTransform::inverse";
62  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", entering...\n";
63 
64  //***
65  // Begin with guess. Forward transform is defined as trasforming left to
66  // right. We are therefore solving for left:
67  //***
68  ossimDpt left = getOrigin();
69  ossimDpt left_dx;
70  ossimDpt left_dy;
71  ossimDpt right;
72  ossimDpt right_dx;
73  ossimDpt right_dy;
74  ossimDpt dr_dx;
75  ossimDpt dr_dy;
76  ossimDpt r_diff;
77  ossimDpt l_diff;
78  double inverse_norm;
79  int iters=0;
80  //***
81  // Begin iterations:
82  //***
83  do
84  {
85  //***
86  // establish perturbed image points about the guessed point:
87  //***
88  left_dx.x = left.x + theDxDy.x;
89  left_dx.y = left.y;
90  left_dy.x = left.x;
91  left_dy.y = left.y + theDxDy.y;
92 
93  //***
94  // Compute numerical partials at current guessed point:
95  //***
96  forward(left, right);
97  forward(left_dx, right_dx);
98  forward(left_dy, right_dy);
99 
100  dr_dx.x = (right_dx.x - right.x)/theDxDy.x; //e
101  dr_dx.y = (right_dx.y - right.y)/theDxDy.y; //g
102  dr_dy.x = (right_dy.x - right.x)/theDxDy.x; //f
103  dr_dy.y = (right_dy.y - right.y)/theDxDy.y; //h
104 
105  //***
106  // Test for convergence:
107  //***
108  r_diff = input - right;
109 
110  //***
111  // Compute linearized estimate of image point given gp delta:
112  //***
113  inverse_norm = dr_dy.x*dr_dx.y - dr_dx.x*dr_dy.y; // fg-eh
114 
115  if (inverse_norm != 0)
116  {
117  l_diff.x = (-dr_dy.y*r_diff.x + dr_dy.x*r_diff.y)/inverse_norm;
118  l_diff.y = ( dr_dx.y*r_diff.x - dr_dx.x*r_diff.y)/inverse_norm;
119 
120  left += l_diff;
121  }
122  else
123  {
124  l_diff.x = 0;
125  l_diff.y = 0;
126  }
127 
128  iters++;
129 
130  } while (((fabs(l_diff.x) > theConvergenceThreshold) ||
131  (fabs(l_diff.y) > theConvergenceThreshold)) &&
132  (iters < theMaxIterations));
133 
134  //***
135  // Note that this error mesage appears only if max count was reached while
136  // iterating. A linear (no iteration) solution would finish with iters =
137  // MAX_NUM_ITERATIONS + 1:
138  //***
139  if (iters == theMaxIterations)
140  {
141  ossimNotify(ossimNotifyLevel_WARN) << "WARNING: " << MODULE << ", exceeded max number of iterations computing inverse "
142  << "transform for point: " << input << "\n";
143  }
144 
145  output = left;
146  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG: " << MODULE << ", returning...\n";
147  return;
148 
149 }
150 
151 //*****************************************************************************
152 // METHOD:
153 //*****************************************************************************
155  const char* prefix) const
156 {
157  kwl.add(prefix,
160  true);
161  kwl.add(prefix,
164  true);
165  kwl.add(prefix,
166  "dxdy",
169  true);
170 
171  return ossimObject::saveState(kwl, prefix);
172 }
173 
174 //*****************************************************************************
175 // METHOD:
176 //*****************************************************************************
178  const char* prefix)
179 {
180  bool result = true;
181 
182  const char* buf;
183 
185 
186  if (buf)
187  {
188  theConvergenceThreshold = atof(buf);
189  }
190  else
191  {
192  theConvergenceThreshold = .00000000000002;
193  }
194 
195  buf= kwl.find(prefix, ossimKeywordNames::MAX_ITERATIONS_KW);
196  if(buf)
197  {
198  theMaxIterations = atoi(buf);
199  }
200  else
201  {
202  theMaxIterations = 10;
203  }
204  const char* dxdy = kwl.find(prefix, "dxdy");
205  if(dxdy)
206  {
207  ossimString tempString(dxdy);
208  std::vector<ossimString> splitArray;
209  tempString = tempString.trim();
210  tempString.split(splitArray, " ");
211  if(splitArray.size()==2)
212  {
213  theDxDy.x = splitArray[0].toDouble();
214  theDxDy.y = splitArray[1].toDouble();
215  }
216  }
217  if(result)
218  {
219  ossimObject::loadState(kwl, prefix);
220  }
221 
222  return result;
223 }
224 
225 void ossim2dTo2dTransform::forward(ossimDpt& modify_this) const
226 {
227  ossimDpt output;
228  forward(modify_this, output);
229  modify_this = output;
230 }
231 
232 void ossim2dTo2dTransform::inverse(ossimDpt& modify_this) const
233 {
234  ossimDpt output;
235  inverse(modify_this, output);
236  modify_this = output;
237 }
238 
240 {
241  return ossimDpt(0,0);
242 }
243 
244 void ossim2dTo2dTransform::setConvergenceThreshold(const double& new_threshold)
245 {
246  theConvergenceThreshold = new_threshold;
247 }
248 
250 {
251  theMaxIterations = new_max_iters;
252 }
253 
255 {
256  theDxDy.x = dxdy.x;
257  theDxDy.y = dxdy.y;
258 }
259 
261 {
262  if (this != &rhs)
263  {
265 
268  theDxDy = rhs.theDxDy;
269  }
270  return *this;
271 }
272 
274 {
275  out << "convergenceThreshold: " << theConvergenceThreshold << "\n"
276  << "maxIterations: " << theMaxIterations << "\n"
277  << "dxdy: " << theDxDy << "\n";
278  return out;
279 }
280 
void setConvergenceThreshold(const double &new_threshold)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
void setMaxIterations(int new_max_iters)
virtual void forward(const ossimDpt &input, ossimDpt &output) const =0
Represents serializable keyword/value map.
const char * find(const char *key) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Definition: ossimObject.cpp:95
double y
Definition: ossimDpt.h:165
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
void setDxDy(const ossimDpt &dxdy)
static ossimString toString(bool aValue)
Numeric to string methods.
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual const ossim2dTo2dTransform & operator=(const ossim2dTo2dTransform &rhs)
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual void inverse(const ossimDpt &input, ossimDpt &output) const
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
static const char * MAX_ITERATIONS_KW
#define DBL_EPSILON
virtual ossimDpt getOrigin() const
ossimReferenced & operator=(const ossimReferenced &)
double x
Definition: ossimDpt.h:164
static const char * CONVERGENCE_THRESHOLD_KW
virtual std::ostream & print(std::ostream &out) const
Generic print method.
RTTI_DEF1(ossim2dTo2dTransform, "ossim2dTo2dTransform", ossimObject)
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23