anutka

Untitled

Oct 25th, 2020 (edited)
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.75 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <assert.h>
  5. const double pi = 3.141592653589793238462643;
  6. const double accuracy = 0.0000001;
  7.  
  8. class Vector {
  9. public:
  10.     double x;
  11.     double y;
  12.     double z;
  13.     Vector() = default;
  14.     Vector(double x,double y, double z) : x(x), y(y), z(z){}
  15.     Vector(const Vector& vector) = default;
  16.    
  17.     friend bool operator == (const Vector& left, const Vector& right);
  18.     friend bool operator != (const Vector& left, const Vector& right);
  19.     friend Vector operator + (const Vector& left, const Vector& right);
  20.     friend bool operator < (const Vector& left, const Vector& right);
  21.     friend bool operator > (const Vector& left, const Vector& right);
  22.     friend bool operator >= (const Vector& left, const Vector& right);
  23.     friend bool operator <= (const Vector& left, const Vector& right);
  24.     friend Vector operator - (const Vector& left, const Vector& right);
  25.     friend Vector operator / (const Vector& left, const double& right);
  26.  
  27.     void operator += (const Vector& other){
  28.         x += other.x;
  29.         y += other.y;
  30.         z += other.z;
  31.     }
  32.     void operator -= (const Vector& other){
  33.         x -= other.x;
  34.         y -= other.y;
  35.         z -= other.z;
  36.     }
  37.     void operator /= (const double& c){
  38.         assert(c >0);
  39.         x /= c;
  40.         y /= c;
  41.         z /= c;
  42.     }
  43.     void operator *= (const double& c) {
  44.         x *= c;
  45.         y *= c;
  46.         z *= c;
  47.     }
  48. };
  49.  
  50. /*
  51.  * Арифметические операции
  52.  */
  53. Vector operator + (const Vector& left, const Vector& right){
  54.     Vector data = left;
  55.     data += right;
  56.     return data;
  57. }
  58. Vector operator - (const Vector& left, const Vector& right){
  59.     Vector data = left;
  60.     data -= right;
  61.     return data;
  62. }
  63. Vector operator / (const Vector& left, const double& right){
  64.     assert(right != 0);
  65.     Vector data = left;
  66.     data /= right;
  67.     return data;
  68. }
  69. Vector operator * (const Vector& left, const double right){
  70.     Vector data = left;
  71.     data *= right;
  72.     return data;
  73. }
  74.  
  75. /*
  76.  * Операции сравнения
  77.  */
  78. bool operator > (const Vector& left, const Vector& right) {
  79.     return (left.x>right.x) && (left.y > right.y) && (left.z > right.z);
  80. }
  81. bool operator < (const Vector& left, const Vector& right) {
  82.     return (left.x<right.x) && (left.y < right.y) && (left.z < right.z);
  83. }
  84. bool operator <= (const Vector& left, const Vector& right) {
  85.     return (left.x<=right.x) && (left.y <= right.y) && (left.z <= right.z);
  86. }
  87. bool operator >= (const Vector& left, const Vector& right) {
  88.     return (left.x>=right.x) && (left.y >= right.y) && (left.z >= right.z);
  89. }
  90.  
  91. bool operator == (const Vector& left, const Vector& right) {
  92.     return fabs(left.x - right.x) < accuracy && fabs(left.y - right.y) < accuracy;
  93. }
  94. bool operator != (const Vector& left, const Vector& right) {
  95.     return !(left == right);
  96. }
  97.  
  98.  
  99. double scalarMul (const Vector& first, const Vector& second) {
  100.     return first.x * second.x + first.y * second.y + first.z * second.z;
  101. }
  102. Vector vectorMul (const Vector& first, const Vector& second) {
  103.     return Vector(first.y*second.z - first.z*second.y,
  104.                 first.z*second.x - first.x*second.z,
  105.                 first.x*second.y - first.y*second.x);
  106. }
  107. double distance (const Vector& first, const Vector& second) {
  108.     return sqrt( 256 *((first.x-second.x)*(first.x-second.x)
  109.                 + (first.y-second.y)*(first.y-second.y) +
  110.                 (first.z-second.z)*(first.z-second.z)))/16;
  111. }
  112.  
  113. class Plane {
  114. public:
  115.     Vector normal;
  116.     double D;
  117.     Plane (const Vector& firstP, const Vector& secondP, const Vector& thirdP) {
  118.         Vector firstV =  firstP - thirdP, secondV = secondP - thirdP;
  119.         normal = vectorMul(firstV, secondV);
  120.         D = - scalarMul(normal, thirdP);
  121.     }
  122.  
  123. };
  124. double distance(Vector& point, Plane& plane) {
  125.     assert(plane.normal!= Vector(0,0,0));
  126.     return fabs(scalarMul(plane.normal, point) + plane.D)/distance(plane.normal, Vector(0, 0, 0));
  127. }
  128. Vector proection(Vector& point, Plane& plane) {
  129.     return point - plane.normal*(scalarMul(point, plane.normal) + plane.D)/scalarMul(plane.normal, plane.normal);
  130. }
  131.  
  132. class Segment{
  133. public:
  134.     Vector firstP;
  135.     Vector secondP;
  136.     Segment(Vector& firstP, Vector& secondP) : firstP(firstP), secondP(secondP) {
  137.     }
  138. };
  139.  
  140. bool isSameSign(double x, double y) {
  141.     return (x >= 0 && y >= 0) || (x <= 0 && y <= 0);
  142. }
  143.  
  144. bool Intersect(Segment& first, Segment& second) {
  145.     Vector segment = first.firstP - first.secondP;
  146.     Vector fTriangle = second.firstP - first.secondP;
  147.     Vector sTriangle = second.secondP - first.secondP;
  148.     Vector firstNormal = vectorMul(segment, fTriangle);
  149.     Vector secondNormal = vectorMul(segment, sTriangle);
  150.     if (firstNormal != Vector(0,0,0) && secondNormal != Vector(0,0,0)) {
  151.         return  !isSameSign(firstNormal.x, secondNormal.x) ||
  152.                 !isSameSign(firstNormal.y, secondNormal.y) ||
  153.                 !isSameSign(firstNormal.z, secondNormal.z);
  154.     } else {
  155.         if (firstNormal == Vector(0,0,0) && (second.firstP <= first.firstP&& second.firstP >= first.secondP||
  156.                                                     second.firstP >= first.firstP&& second.firstP <= first.secondP)) {
  157.             return true;
  158.         }
  159.         if (secondNormal == Vector(0,0,0) && (second.secondP <= first.firstP&& second.secondP >= first.secondP||
  160.                                              second.secondP >= first.firstP&& second.secondP <= first.secondP)) {
  161.             return true;
  162.         }
  163.         if (firstNormal == Vector(0,0,0) && secondNormal == Vector(0,0,0)
  164.                                                 && (first.firstP <= second.firstP && first.firstP >= second.secondP||
  165.                                                     first.firstP >= second.firstP && first.firstP <= second.secondP)) {
  166.             return true;
  167.         }
  168.         return false;
  169.     }
  170. }
  171.  
  172. int main() {
  173.     int x, y, z;
  174.     std::cout.precision(7);
  175.     std::vector<Vector> points (4) ;
  176.     for (int i = 0; i < 4; i++) {
  177.         std::cin >> x >> y >> z;
  178.         points[i] = Vector(x, y, z);
  179.     }
  180.     /*if (points[0] == points[1] && points[2] == points[3]) {
  181.         std::cout << distance(points[0], points[2]);
  182.     } else{*/
  183.     if (vectorMul(points[1] - points[0], points[3]- points[2]) == Vector(0, 0, 0)) {
  184.         Vector normal = vectorMul(vectorMul(points[1] - points[0], points[2] - points[0]), points[1] - points[0])
  185.                                                                     /scalarMul(points[1] - points[0], points[1] - points[0]);
  186.         Vector d = normal + points[0], e = normal + points[1];
  187.         Segment a(points[2], points[3]), b(d, e);
  188.         if (Intersect(a, b)) {
  189.             std::cout <<fabs(distance(vectorMul(points[1] - points[0], points[2] - points[0]),
  190.                     Vector(0,0,0)))/distance(points[1] - points[0], Vector(0,0,0));
  191.         } else {
  192.             std::cout << std::min(std::min(distance(points[0], points[3]), distance(points[1], points[3])),
  193.                                   std::min(distance(points[0], points[2]), distance(points[1], points[2])));
  194.             std::cout << std::endl;
  195.         }
  196.     } else {
  197.         Plane c(points[0], points[1], points[0] + points[2] - points[3]);
  198.         Segment a(points[0], points[1]);
  199.         Vector d = proection(points[2], c), e = proection(points[3], c);
  200.         Segment b(d, e);
  201.         if (Intersect(a, b)) {
  202.             std::cout << distance(points[3], c);
  203.         } else {
  204.             std::cout << std::min(std::min(distance(points[0], points[3]), distance(points[1], points[3])),
  205.                                   std::min(distance(points[0], points[2]), distance(points[1], points[2])));
  206.             std::cout << std::endl;
  207.         }
  208.     }
  209.     return 0;
  210. }
Add Comment
Please, Sign In to add comment