Advertisement
faunuss

Untitled

Nov 9th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.27 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <iomanip>
  4. using namespace std;
  5.  
  6. const double SMALL_NUM = 0.000001;  // Очень малое число
  7.  
  8. // Структура точки
  9. struct Dot{
  10.     double x;   // Координата x
  11.     double y;   // Координата y
  12.     double z;   // Координата z
  13.  
  14.     explicit Dot(double X, double Y, double Z) : x(X), y(Y), z(Z) {}  // Конструктор
  15. };
  16.  
  17. Dot operator - (const Dot& first, const Dot& second){
  18.     Dot tmp(first.x - second.x, first.y - second.y, first.z - second.z);
  19.     return tmp;
  20. }
  21.  
  22. // Структура отрезка.
  23. struct Segment{
  24.     Dot P0;     // Точка начала
  25.     Dot P1;     // Точка конца
  26.  
  27.     explicit Segment(Dot p0, Dot p1): P0(p0), P1(p1) {}  // Конструктор
  28. };
  29.  
  30. // Структура Геометрического вектора ( = Сегмент, где P0 = 0,0,0)
  31. struct Vect{
  32.     double x;
  33.     double y;
  34.     double z;
  35.  
  36.     explicit Vect(Dot u) : x(u.x), y(u.y), z(u.z) {}
  37. };
  38.  
  39. // Сложить два вектора - сложить их координаты
  40. Vect operator + (const Vect& v, const Vect& u){
  41.     return Vect(Dot(v.x + u.x, v.y + u.y,v.z + u.z));
  42. }
  43.  
  44. // Умножить вектор на число - умножить каждую координату на это число
  45. Vect operator * (const double& a, const Vect& v){
  46.     return Vect(Dot(a*v.x, a*v.y,a*v.z));
  47. }
  48.  
  49. // Разность двух векторов - u+(-1)*v
  50. Vect operator - (const Vect& v, const Vect& u){
  51.     return v + (-1.0)*u;
  52. }
  53.  
  54. // Расстояние между векторами (по определению)
  55. double dist_between_dots(Vect u, Vect v){
  56.     return (u.x * v.x + u.y * v.y + u.z * v.z);
  57. }
  58.  
  59. // Длина вектора (по определению)
  60. double length(Vect v){
  61.     return sqrt(dist_between_dots(v,v));
  62. }
  63.  
  64. double dist_between_Segments(Segment S1, Segment S2){
  65.     Vect u(S1.P1-S1.P0);
  66.     Vect v(S2.P1-S2.P0);
  67.     Vect w(S1.P0-S2.P0);
  68.  
  69.     // Переменные для вычислений
  70.     double a = dist_between_dots(u,u);
  71.     double b = dist_between_dots(u,v);
  72.     double c = dist_between_dots(v,v);
  73.     double d = dist_between_dots(u,w);
  74.     double e = dist_between_dots(v,w);
  75.     double f = a*c - b*b;
  76.  
  77.     double    sc = 0;
  78.     double    sN = 0;
  79.     double    sD = f;
  80.     double    tD = f;
  81.     double    tc;
  82.     double    tN;
  83.  
  84.     // Находим нужные точки
  85.     if (f <= SMALL_NUM) {
  86.         sN = 0.0;
  87.         sD = 1.0;
  88.         tN = e;
  89.         tD = c;
  90.     }
  91.     else {
  92.         sN = (b*e - c*d);
  93.         tN = (a*e - b*d);
  94.         if (sN < 0.0) {
  95.             sN = 0.0;
  96.             tN = e;
  97.             tD = c;
  98.         }
  99.         else if (sN >= sD) {
  100.             sN = sD;
  101.             tN = e + b;
  102.             tD = c;
  103.         }
  104.     }
  105.  
  106.     if (tN <= 0.0) {
  107.         tN = 0.0;
  108.         if (-d <= 0.0)
  109.             sN = 0.0;
  110.         else if (-d >= a)
  111.             sN = sD;
  112.         else {
  113.             sN = -d;
  114.             sD = a;
  115.         }
  116.     }
  117.     else if (tN >= tD) {
  118.         tN = tD;
  119.         if ((-d + b) <= 0.0)
  120.             sN = 0.0;
  121.         else if ((-d + b) >= a)
  122.             sN = sD;
  123.         else {
  124.             sN = (-d +  b);
  125.             sD = a;
  126.         }
  127.     }
  128.     // Находим точки начала и конца вектора
  129.     if(abs(sN) < SMALL_NUM){
  130.         sc = 0.0;
  131.     } else {
  132.         sc = sN / sD;
  133.     }
  134.  
  135.     if(abs(tN) < SMALL_NUM){
  136.         tc = 0.0;
  137.     } else {
  138.         tc = tN / tD;
  139.     }
  140.  
  141.     Vect dP = (w + (sc * u)) - (tc * v);  // =  Вектор, равный вектору из двух нужных нам точек
  142.  
  143.     return length(dP);   // Возвращаем кратчайшее расстояние
  144. }
  145.  
  146. int main() {
  147.     double x = 0.0;
  148.     double y = 0.0;
  149.     double z = 0.0;
  150.  
  151.     cin >> x; cin >> y; cin >> z;
  152.     Dot P0(x,y,z);
  153.     cin >> x; cin >> y; cin >> z;
  154.     Dot P1(x,y,z);
  155.     Segment S1(P0, P1); // Первый отрезок
  156.  
  157.     cin >> x; cin >> y; cin >> z;
  158.     Dot P2(x,y,z);
  159.     cin >> x; cin >> y; cin >> z;
  160.     Dot P3(x,y,z);
  161.     Segment S2(P2, P3); // Второй отрезок
  162.  
  163.     std::cout << std::setprecision(15) << dist_between_Segments(S1,S2);
  164.     return 0;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement