Projection.cpp
Go to the documentation of this file.
1 
29 
30 
31 #include <iostream>
32 using namespace std;
33 
34 namespace lvr2
35 {
36 
37 Projection::Projection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
38  : m_width(width), m_height(height), m_optimize(optimize), m_system(system)
39 {
40  // Convert degrees to radians
41  m_maxH = maxH / 180.0 * m_ph;
42  m_minH = minH / 180.0 * m_ph;
43  m_maxV = maxV / 180.0 * m_ph;
44  m_minV = minV / 180.0 * m_ph;
45 }
46 
47 
48 
50 {
51  if(((double)m_xSize / m_ySize) != ((double)m_width / m_height))
52  {
53  if(m_optimize)
54  {
55  float tWidth;
56  float tHeight;
57 
58  tWidth = m_height * m_xSize / m_ySize;
59  tHeight = m_width * m_ySize / m_xSize;
60 
61  if((double)(m_width/m_height) >= 1)
62  {
63  if((double)(m_xSize / m_ySize) >= 1)
64  {
65  //m_height stays the same
66  if((double)(tWidth / m_height) >= 1)
67  {
68  m_width = tWidth;
69  }
70  //m_width stays the same
71  else if((double)(m_width / tHeight) >= 1)
72  {
73  m_height = tHeight;
74  }
75  }
76  }
77  else
78  {
79  if((double)(m_xSize / m_ySize) < 1)
80  {
81  //m_width stays the same
82  if((double)(m_width / tHeight) <= 1)
83  {
84  m_height = tHeight;
85  }
86  //m_height stays the same
87  else if((double)(tWidth / m_height) <= 1)
88  {
89  m_width = tWidth;
90  }
91  }
92  }
93  }
94  }
95 }
96 
97 
98 
99 EquirectangularProjection::EquirectangularProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
100  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
101 {
102  //adding the longitude to x axis and latitude to y axis
103  m_xSize = m_maxH - m_minH;
104  m_ySize = m_maxV - m_minV;
105 
106  setImageRatio();
107 
108  m_xFactor = (float)m_width / m_xSize;
109  m_yFactor = (float)m_height / m_ySize;
110 
111  m_maxWidth = m_width - 1;
112  m_maxHeight = m_height - 1;
113 
114  //shift all the valuse to positive points on image
115  m_lowShift = m_minV;
116 
117 }
118 
119 void EquirectangularProjection::project(int& i, int& j, float& range, float x, float y, float z)
120 {
121  float kart[3];
122 
123  switch(m_system)
124  {
126  kart[0] = z;
127  kart[1] = -x;
128  kart[2] = y;
129  break;
130  case ModelToImage::UOS:
131  kart[0] = x;
132  kart[1] = -z;
133  kart[2] = y;
134  break;
136  default:
137  kart[0] = x;
138  kart[1] = y;
139  kart[2] = z;
140 
141  }
142 
143 
144 // if(m_system)
145 // {
146 // kart[0] = z;
147 // kart[1] = -x;
148 // kart[2] = y;
149 // }
150 // else
151 // {
155 
156 // kart[0] = x;
157 // kart[1] = y;
158 // kart[2] = z;
159 
160 // }
161 
162 
163  float polar[3] = {0, 0, 0};
164 
165  // Convert to polar coordinates
166  if(kart[0] != 0 && kart[1] != 0 && kart[2] != 0)
167  {
168  toPolar(kart, polar);
169  }
170  else
171  {
172  i = 0;
173  j = 0;
174  return;
175  }
176 
177  float theta = polar[0];
178  float phi = polar[1];
179  range = polar[2];
180 
181  // Horizantal angle of view of [0:360][minHorzAngle_:maxHorzAngle_] and vertical of [-40:60][minVertAngle_:maxVertAngle]
182  // phi == longitude == horizantal angle of view of [0:360]
183  // shift it to clockwise instead of counter clockwise
184  phi = (2 * M_PI) - phi;
185 
186  // Theta == latitude == vertical angle of view of [-40:60]
187  // shift the vertical angle instead of -90:90 to 0:180 from north to south pole
188  theta -= M_PI/2.0;
189  theta *= -1;
190 
191  i = (int) ( m_xFactor * phi);
192  if (i < 0)
193  {
194  i = 0;
195  }
196 
197  if (i > m_maxWidth)
198  {
199  i = m_maxWidth;
200  }
201 
202  j = (int) ( m_yFactor * (theta - m_lowShift) );
203  j = m_maxHeight - j;
204 
205  if (j < 0)
206  {
207  j = 0;
208  }
209 
210  if (j > m_maxHeight)
211  {
212  j = m_maxHeight;
213  }
214  //cout << i << " " << j << " " << range << " / " << m_maxWidth << " " << m_maxHeight << endl;
215 }
216 
217 ConicProjection::ConicProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
218  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
219 {
220  // Set up initial parameters according to MathWorld:
221  // http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
222  m_lat0 = (m_minV + m_maxV) / 2;
223  m_long0 = (m_minH + m_maxH) / 2;
224  m_phi1 = m_minV;
225  m_phi2 = m_maxV;
226  m_n = (sin(m_phi1) + sin(m_phi2)) / 2.;
227  m_c = pow((cos(m_phi1)) + 2 * m_n * sin(m_phi1), 2);
228  m_rho0 = sqrt(m_c - 2 * m_n * sin(m_lat0)) / m_n;
229 
230  // Set up max values for x and y and add the longitude to x axis and latitude to y axis
231  m_maxX = (1./m_n * sqrt(m_c - 2*m_n * sin( m_minV)) ) * sin(m_n * (m_maxH - m_long0));
232  m_minX = (1./m_n * sqrt(m_c - 2*m_n * sin( m_minV)) ) * sin(m_n * (m_minH - m_long0));
233  m_xSize = ( m_maxX - m_minX );
234 
235  m_maxY = m_rho0 - (1./m_n * sqrt(m_c - 2*m_n * sin(m_maxV)) ) * cos(m_n * (m_maxH - m_long0 ));
236  m_minY = m_rho0 - (1./m_n * sqrt(m_c - 2*m_n * sin(m_minV)) ) * cos(m_n * ((m_minH + m_maxH)/2 - m_long0 ));
237  m_ySize = ( m_maxY - m_minY );
238 
239  setImageRatio();
240 
241  m_xFactor = (float) m_width / m_xSize;
242  m_yFactor = (float) m_height / m_ySize;
243  m_maxWidth = m_width- 1;
244 
245 
246  // Shift all values to positive points on image
247  m_maxHeight = m_height - 1;
248 }
249 
250 CylindricalProjection::CylindricalProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
251  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
252 {
253  //adding the longitude to x and tan(latitude) to y
254  m_xSize = m_maxH - m_minH;
255  m_ySize = tan(m_maxV) - tan(m_minV);
256 
257  setImageRatio();
258 
259  //find the x and y range
260  m_xFactor = (double) m_width / m_xSize;
261  m_maxWidth = m_width - 1;
262  m_yFactor = (double) m_height / m_ySize;
264  m_maxHeight = m_height - 1;
265 }
266 
267 MercatorProjection::MercatorProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
268  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
269 {
270  //find the x and y range
271  m_xSize = m_maxH - m_minH;
272  m_ySize = ( log( tan( m_maxV) + ( 1 / cos( m_maxV) ) ) - log ( tan( m_minV) + (1 / cos(m_minV) ) ) );
273 
274  setImageRatio();
275 
276  m_xFactor = (double) m_width / m_xSize;
277  m_maxWidth = m_width - 1;
278  m_yFactor = (double) m_height / m_ySize;
279  m_heightLow = log(tan(m_minV) + (1/cos(m_minV)));
280  m_maxHeight = m_height - 1;
281 }
282 
283 RectilinearProjection::RectilinearProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
284  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
285 {
286  int numberOfImages = 3;
287  m_interval = (m_maxH - m_minH) / numberOfImages;
288  m_iMinY = m_minV;
289  m_iMaxY = m_maxV;
290 
291  // Latitude of projection center
292  m_p1 = 0;
293 
294  m_iMinX = m_minH;
296 
297  // Longitude of projection center
298  m_l0 = m_iMinX + m_interval / 2;
299 
300  // Finding min and max of the x direction
301  m_coscRectlinear = sin(m_p1) * sin(m_iMaxY) + cos(m_p1) * cos(m_iMaxY) * cos(m_iMaxX - m_l0);
302  m_max = (cos(m_iMaxY) * sin(m_iMaxX - m_l0) / m_coscRectlinear);
303  m_coscRectlinear = sin(m_p1) * sin(m_iMinY) + cos(m_p1) * cos(m_iMinY) * cos(m_iMinX - m_l0);
304  m_min = (cos(m_iMinY) * sin(m_iMinX - m_l0) / m_coscRectlinear);
305  m_xSize = (m_max - m_min);
306 
307  // Finding the min and max of y direction
308  m_coscRectlinear = sin(m_p1) * sin(m_iMaxY) + cos(m_p1) * cos(m_iMaxY) * cos(m_iMaxX - m_l0);
309  m_max = ( (cos(m_p1) * sin(m_iMaxY) - sin(m_p1) * cos(m_iMaxY) * cos(m_iMaxX - m_l0) )/ m_coscRectlinear);
310  m_coscRectlinear = sin(m_p1) * sin(m_iMinY) + cos(m_p1) * cos(m_iMinY) * cos(m_iMinX - m_l0);
311  m_min = ( (cos(m_p1) * sin(m_iMinY) - sin(m_p1) * cos(m_iMinY) * cos(m_iMinX - m_l0) )/ m_coscRectlinear);
312  m_ySize = (m_max - m_min);
313 
314  setImageRatio();
315 }
316 
317 PanniniProjection::PanniniProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
318  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
319 {
320  //default values for numberOfIMages and dPannini==param
321  int param = 1;
322  int numberOfIMages = 2;
323 
324  m_interval = (m_maxH - m_minH) / numberOfIMages;
325  m_iMinY = m_minV;
326  m_iMaxY = m_maxV;
327  //latitude of projection center
328  m_p1 = 0;
329 
330  m_iMinX = m_minH + (0 * m_interval);
331  m_iMaxX = m_minH + ((0 + 1) * m_interval);
332  //the longitude of projection center
333  m_l0 = m_iMinX + m_interval / 2;
334 
335  //use the S variable of pannini projection mentioned in the thesis
336  //finding the min and max of the x direction
337  m_sPannini = (param + 1) / (param + sin(m_p1) * tan(m_iMaxY) + cos(m_p1) * cos(m_iMaxX - m_l0));
338  m_max = m_sPannini * (sin(m_iMaxX - m_l0));
339  m_sPannini = (param + 1) / (param + sin(m_p1) * tan(m_iMinY) + cos(m_p1) * cos(m_iMinX - m_l0));
340  m_min = m_sPannini * (sin(m_iMinX - m_l0));
341  m_xSize = m_max - m_min;
342  //finding the min and max of y direction
343  m_sPannini = (param + 1) / (param + sin(m_p1) * tan(m_iMaxY) + cos(m_p1) * cos(m_iMaxX - m_l0));
344  m_max = m_sPannini * (tan(m_iMaxY) * (cos(m_p1) - sin(m_p1) * 1/tan(m_iMaxY) * cos(m_iMaxX - m_l0)));
345  m_sPannini = (param + 1) / (param + sin(m_p1) * tan(m_iMinY) + cos(m_p1) * cos(m_iMinX - m_l0));
346  m_min = m_sPannini * (tan(m_iMinY) * (cos(m_p1) - sin(m_p1) * 1/tan(m_iMinY) * cos(m_iMinX - m_l0)));
347  m_ySize = m_max - m_min;
348 
349  setImageRatio();
350 }
351 
352 StereographicProjection::StereographicProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
353  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
354 {
355  // Default values for numberOfIMages and rStereographic==param
356  int param = 2;
357  int numberOfIMages = 2;
358 
359  // m_l0 and m_p1 are the center of projection iminx, imaxx, iminy, imaxy are the bounderis of m_intervals
360  m_interval = (m_maxH - m_minH) / numberOfIMages;
361  m_iMinY = m_minV;
362  m_iMaxY = m_maxV;
363 
364  // Latitude of projection center
365  m_p1 = 0;
366 
367  m_iMinX = m_minH + (0 * m_interval);
368  m_iMaxX = m_minH + ((0 + 1) * m_interval);
369 
370  // Longitude of projection center
371  m_l0 = m_iMinX + m_interval / 2;
372 
373  // Use the R variable of stereographic projection mentioned in the thesis
374  // finding the min and max of x direction
375  m_k = (2 * param) / (1 + sin(m_p1) * sin(m_p1) + cos(m_p1) * cos(m_p1) * cos(m_iMaxX - m_l0));
376  m_max = m_k * cos(m_p1) * sin (m_iMaxX - m_l0);
377  m_k = (2 * param) / (1 + sin (m_p1) * sin(m_p1) + cos(m_p1) * cos(m_p1) * cos(m_iMinX -m_l0));
378  m_min = m_k * cos(m_p1) * sin (m_iMinX -m_l0);
379  m_xSize = (m_max - m_min);
380 
381  // Finding the min and max of y direction
382  m_k = (2 * param) / (1 + sin(m_p1) * sin(m_iMaxY) + cos(m_p1) * cos(m_iMaxY) * cos(m_iMaxX - m_l0));
383  m_max = m_k * (cos(m_p1) * sin(m_iMaxY) - sin(m_p1) * cos(m_iMaxY) * cos(m_iMaxX - m_l0));
384  m_k = (2 * param) / (1 + sin(m_p1) * sin(m_iMinY) + cos(m_p1) * cos(m_iMinY) * cos(m_iMinX - m_l0));
385  m_min = m_k * (cos(m_p1) * sin(m_iMinY) - sin(m_p1) * cos(m_iMinY) * cos(m_iMinX - m_l0));
386  m_ySize = (m_max - m_min);
387 
388  setImageRatio();
389 }
390 
391 AzimuthalProjection::AzimuthalProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system)
392  : Projection(width, height, minH, maxH, minV, maxV, optimize, system)
393 {
394  // set up initial parameters according to MathWorld: http://mathworld.wolfram.com/LambertAzimuthalEqual-AreaProjection.html
395  m_long0 = (m_minH + m_maxH) / 2;
396  m_phi1 = (m_minV + m_maxV) / 2;
397 
398  // set up max values for x and y and add the longitude to x axis and latitude to y axis
399  // sqrt(2/(1+sin(m_phi1)*sin(theta)+cos(m_phi1)*cos(theta)*cos(phi-m_long0)));
400  m_maxX = sqrt(2/(1+sin(m_phi1)*sin(m_maxH)+cos(m_phi1)*cos(m_maxH)*cos((m_minV/2+m_maxV/2)-m_long0)))*cos(m_maxH)*sin((m_minV/2+m_maxV/2)-m_long0);
401  m_minX = sqrt(2/(1+sin(m_phi1)*sin(m_minH)+cos(m_phi1)*cos(m_minH)*cos((m_minV/2+m_maxV/2)-m_long0)))*cos(m_minH)*sin((m_minV/2+m_maxV/2)-m_long0);
402  m_xSize = ( m_maxX - m_minX );
403 
404  m_minY = m_minX; // the thing is supposed to be circular, isn't it?
405  m_maxY = m_maxX;
406  m_ySize = ( m_maxY - m_minY );
407 
408  setImageRatio();
409 
410  m_xSize=1/2.;
411  m_ySize=1/2.;
412 
413  m_xFactor = (double) m_width / 2*m_xSize;
414  m_maxWidth = m_width - 1;
415  m_yFactor = (double) m_height / 2*m_ySize;
416  //shift all the values to positive points on image
417  m_maxHeight = m_height - 1;
418 }
419 
420 void Projection::toPolar(const float _cartesian[], float polar[])
421 {
422  float phi, theta, rho;
423 
424  float x_sqr, y_sqr, z_sqr;
425  x_sqr = _cartesian[0] * _cartesian[0];
426  y_sqr = _cartesian[1] * _cartesian[1];
427  z_sqr = _cartesian[2] * _cartesian[2];
428 
429  rho = std::sqrt(x_sqr + y_sqr + z_sqr);
430 
431  float cartesian[3];
432  cartesian[0] = _cartesian[0] / rho;
433  cartesian[1] = _cartesian[1] / rho;
434  cartesian[2] = _cartesian[2] / rho;
435 
436  phi = std::acos(cartesian[2]);
437 
438  float theta0;
439 
440  if(std::abs(phi) < 0.0001)
441  {
442  theta = 0.0;
443  }
444  else if(std::abs(M_PI - phi) < 0.0001)
445  {
446  theta = 0.0;
447  }
448  else
449  {
450  if(std::abs(cartesian[0]/std::sin(phi)) > 1.0)
451  {
452  if(cartesian[0]/std::sin(phi) < 0)
453  {
454  theta0 = M_PI;
455  }
456  else
457  {
458  theta0 = 0.0;
459  }
460  }
461  else
462  {
463  theta0 = acos(cartesian[0]/std::sin(phi));
464 
465  }
466 
467  float sintheta = cartesian[1]/std::sin(phi);
468  float EPS = 0.0001;
469 
470  if(std::abs(std::sin(theta0) - sintheta) < EPS)
471  {
472  theta = theta0;
473  }
474  else if(std::abs( std::sin( 2*M_PI - theta0 ) - sintheta ) < EPS)
475  {
476  theta = 2*M_PI - theta0;
477  }
478  else
479  {
480  theta = 0;
481  }
482  }
483  polar[0] = phi;
484  polar[1] = theta;
485  polar[2] = rho;
486 }
487 
488 } // namespace lvr2
CylindricalProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:250
StereographicProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:352
PanniniProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:317
#define M_PI
Definition: Matrix4.hpp:52
ConicProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:217
void setImageRatio()
Definition: Projection.cpp:49
RectilinearProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:283
T abs(T x)
Definition: nanoflann.hpp:237
AzimuthalProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:391
EquirectangularProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:99
virtual void project(int &i, int &j, float &r, float x, float y, float z) override
Definition: Projection.cpp:119
ModelToImage::CoordinateSystem m_system
Definition: Projection.hpp:64
MercatorProjection(int width, int height, int minH, int maxH, int minV, int maxV, bool optimize, ModelToImage::CoordinateSystem system=ModelToImage::NATIVE)
Definition: Projection.cpp:267
void toPolar(const float point[], float polar[])
Definition: Projection.cpp:420
static constexpr float m_ph
Definition: Projection.hpp:68


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Mon Feb 28 2022 22:46:08