Guest User

Untitled

a guest
Nov 16th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.96 KB | None | 0 0
  1. /*
  2. Есть определенные модели на матлабе, которые написаны кем-то и когда-то. Иногда нужно что-то переписывать для ускорения, но при переписывании возникают опечатки. Да и модели не факт, что правильные, так что юнит-тесты не панацея, почему бы статической типизации не помочь?
  3. Удобно при этом задавать исходные как они даны - в миллиметрах или метрах:
  4. */
  5. //радиус диафрагмы в основании бленды
  6. coord r0(9.5 / 2 * mm);
  7. //радиус диафрагмы 1
  8. coord r1(28.9503 / 2 * mm);
  9. //радиус диафрагмы 2
  10. coord r2(46.3001 / 2 * mm);
  11. //расстояние между диафрагмами 0 и 1
  12. coord d1(5.2 * mm);
  13. //расстояние между диафрагмами 1 и 2
  14. coord d2(4.7 * mm);
  15. //высота диафрагмы 0 от плоскости ФПУ
  16. coord h0(hd + f);
  17. //высота диафрагмы 1 от плоскости ФПУ
  18. coord h1(d1 + hd + f);
  19. //высота диафрагмы 2 от плоскости ФПУ
  20. coord h2(d1 + d2 + hd + f);
  21. //Положение небесных тел
  22. coord Hz(500e3 * meter);
  23. coord Rz(6371e3 * meter);
  24. Angle fi_z(asin( Rz / (Rz + Hz)));
  25. Angle alf_z(0.0 * degree);
  26. Angle bet_z(0.0 * degree);
  27. /*
  28. Что должны из себя представлять типы coord и Angle? Можно сделать
  29. */
  30. typedef double coord;
  31. typedef double Angle;
  32. coord mm = 10E-3.
  33. coord degree = pi / 180.0;
  34. /*
  35. Нормальный выход для динамического языка. Но в этом случае можно где-то в коде умножить два раза:
  36. */
  37. Angle alpha = 5 * degrees;
  38. Angle beta = alpha * degrees;
  39. /*
  40. На помощь приходит библиотека boost::units:
  41. */
  42. #include <boost/math/constants/constants.hpp>
  43. #include <boost/units/io.hpp>
  44. #include <boost/units/pow.hpp>
  45. #include <boost/units/systems/cgs.hpp>
  46. #include <boost/units/systems/cgs/io.hpp>
  47. #include <boost/units/systems/si.hpp>
  48. #include <boost/units/systems/si/io.hpp>
  49. #include <boost/units/cmath.hpp>
  50. #include <boost/units/systems/si/plane_angle.hpp>
  51. const double pi = boost::math::constants::pi<double>();
  52. typedef boost::units::quantity<boost::units::si::plane_angle> Angle;
  53. typedef boost::units::quantity<boost::units::si::length> coord;
  54. using boost::units::si::radians;
  55. using boost::units::si::meter;
  56. coord mm = 10e-3 * boost::units::si::meter;
  57. Angle degree = pi / 180.0 * boost::units::si::radians;
  58. /*
  59. Все, в этом случае мы в большой степени застрахованы от опечаток в исходных данных.
  60. Но код не хотелось бы закладывать на эту библиотеку - шаблоны на MPL долго собираются, собираются не везде и вообще не понятно, зачем это делать. Вся логика обобщена таким образом.
  61. */
  62. template<class T> class Ray
  63. {
  64. private:
  65.         bool f_intersected;
  66. public:
  67.         V<T> r;
  68.         V<T> d;
  69.         template<class Ang> bool intersectsSphere(const T& tH, const T& tR, const Ang& salf, const Ang& sbet)
  70.         {
  71. //Код из матлаба почти 1 в 1
  72.                 T l = tH + tR;
  73.                 T fx = l * sin(salf) / sqrt(1.0 + tan(sbet)*tan(sbet) * cos(salf)*cos(salf));
  74.                 T fy = l * sin(sbet) / sqrt(1.0 + tan(salf)*tan(salf) * cos(sbet)*cos(sbet));
  75.                 double sgn = 1;
  76.                 if (cos(salf) < 0.0 || cos(sbet) < 0.0)
  77.                 {
  78.                         sgn = -1.0;
  79.                 }
  80.                 T fz = sgn * l / sqrt(1.0 + tan(salf) * tan(salf) + tan(sbet) * tan(sbet));
  81.  
  82.                 auto as = d.x * d.x + d.y * d.y + d.z * d.z;
  83.                 auto bs = 2.0 * (d.x * (r.x - fx) + d.y * (r.y - fy) + d.z * (r.z - fz));
  84.                 auto cs = (r.x - fx) * (r.x - fx) +
  85.                               (r.y - fy) * (r.y - fy) +
  86.                                   (r.z - fz) * (r.z - fz)- tR * tR;
  87.  
  88.                 bool intrsct = false;
  89.                 auto Ds = (bs * bs - 4.0 * as * cs);
  90.                 decltype(Ds) zero(0);
  91.                 if (Ds >= zero)
  92.                 {
  93.                         auto tau = (-bs + sqrt(Ds)) / 2.0 / as;
  94.                         T x = r.x + tau * d.x;
  95.                         T y = r.y + tau * d.y;
  96.                         T z = r.z + tau * d.z;
  97.                         intrsct = z >= T(0);
  98.                 }
  99.                 f_intersected = f_intersected && intrsct;
  100.                 return intrsct;
  101.         }
  102. };
  103.  
  104. /*
  105. Вычисления практически ортогональны языку, не считая глобального стейта f_intersected.
  106. */
Add Comment
Please, Sign In to add comment