transform_cs.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Unit Test
  3. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  5. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  6. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  7. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #include <geometry_test_common.hpp>
  12. #include <boost/geometry/strategies/strategy_transform.hpp>
  13. #include <boost/geometry/algorithms/transform.hpp>
  14. #include <boost/geometry/geometries/point.hpp>
  15. #include <boost/geometry/geometries/point_xy.hpp>
  16. template <typename T, typename P>
  17. inline T check_distance(P const& p)
  18. {
  19. T x = bg::get<0>(p);
  20. T y = bg::get<1>(p);
  21. T z = bg::get<2>(p);
  22. return sqrt(x * x + y * y + z * z);
  23. }
  24. template <typename T>
  25. void test_transformations_spherical()
  26. {
  27. T const input_long = 15.0;
  28. T const input_lat = 5.0;
  29. T const expected_long = 0.26179938779914943653855361527329;
  30. T const expected_lat = 0.08726646259971647884618453842443;
  31. // Can be checked using http://www.calc3d.com/ejavascriptcoordcalc.html
  32. // (for phi use long, in radians, for theta use lat, in radians, they are listed there as "theta, phi")
  33. T const expected_polar_x = 0.084186;
  34. T const expected_polar_y = 0.0225576;
  35. T const expected_polar_z = 0.996195;
  36. // Can be checked with same URL using 90-theta for lat.
  37. // So for theta use 85 degrees, in radians: 0.08726646259971647884618453842443
  38. T const expected_equatorial_x = 0.962250;
  39. T const expected_equatorial_y = 0.257834;
  40. T const expected_equatorial_z = 0.0871557;
  41. // 1: Spherical-polar (lat=5, so it is near the pole - on a unit sphere)
  42. bg::model::point<T, 2, bg::cs::spherical<bg::degree> > sp(input_long, input_lat);
  43. // 1a: to radian
  44. bg::model::point<T, 2, bg::cs::spherical<bg::radian> > spr;
  45. bg::transform(sp, spr);
  46. BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
  47. BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
  48. // 1b: to cartesian-3d
  49. bg::model::point<T, 3, bg::cs::cartesian> pc3;
  50. bg::transform(sp, pc3);
  51. BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x, 0.001);
  52. BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y, 0.001);
  53. BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z, 0.001);
  54. BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
  55. // 1c: back
  56. bg::transform(pc3, spr);
  57. BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
  58. BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
  59. // 2: Spherical-equatorial (lat=5, so it is near the equator)
  60. bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::degree> > se(input_long, input_lat);
  61. // 2a: to radian
  62. bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::radian> > ser;
  63. bg::transform(se, ser);
  64. BOOST_CHECK_CLOSE(bg::get<0>(ser), expected_long, 0.001);
  65. BOOST_CHECK_CLOSE(bg::get<1>(ser), expected_lat, 0.001);
  66. bg::transform(se, pc3);
  67. BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x, 0.001);
  68. BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y, 0.001);
  69. BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z, 0.001);
  70. BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
  71. // 2c: back
  72. bg::transform(pc3, ser);
  73. BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001); // expected_long
  74. BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001); // expected_lat
  75. // 3: Spherical-polar including radius
  76. bg::model::point<T, 3, bg::cs::spherical<bg::degree> > sp3(input_long, input_lat, 0.5);
  77. // 3a: to radian
  78. bg::model::point<T, 3, bg::cs::spherical<bg::radian> > spr3;
  79. bg::transform(sp3, spr3);
  80. BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
  81. BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
  82. BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
  83. // 3b: to cartesian-3d
  84. bg::transform(sp3, pc3);
  85. BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x / 2.0, 0.001);
  86. BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y / 2.0, 0.001);
  87. BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z / 2.0, 0.001);
  88. BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
  89. // 3c: back
  90. bg::transform(pc3, spr3);
  91. BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
  92. BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
  93. BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
  94. // 4: Spherical-equatorial including radius
  95. bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::degree> > se3(input_long, input_lat, 0.5);
  96. // 4a: to radian
  97. bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::radian> > ser3;
  98. bg::transform(se3, ser3);
  99. BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
  100. BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
  101. BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
  102. // 4b: to cartesian-3d
  103. bg::transform(se3, pc3);
  104. BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x / 2.0, 0.001);
  105. BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y / 2.0, 0.001);
  106. BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z / 2.0, 0.001);
  107. BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
  108. // 4c: back
  109. bg::transform(pc3, ser3);
  110. BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
  111. BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
  112. BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
  113. }
  114. int test_main(int, char* [])
  115. {
  116. test_transformations_spherical<double>();
  117. return 0;
  118. }