ohwhatalovelyday

Geometry

Nov 12th, 2021 (edited)
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.57 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define FASTER() ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  4. #define ff first
  5. #define ss second
  6. #define pb push_back
  7. #define all(a) a.begin(), a.end()
  8. #define dbg(x) cerr<<" "<<#x<<" "<<x<<endl
  9.  
  10. typedef long double ld;
  11. typedef long long ll;
  12.  
  13. using namespace std;
  14.  
  15. struct point {
  16.     ld x, y;
  17.     point() {}
  18.     point(ld x, ld y) : x(x), y(y) {}
  19.  
  20.     point operator - (point p) {
  21.         return point(x - p.x, y - p.y);
  22.     }
  23.  
  24.     ld len() {
  25.         return sqrtl(x * x + y * y);
  26.     }
  27. };
  28.  
  29. istream &operator >> (istream &in, point &p) {
  30.     in >> p.x >> p.y;
  31.     return in;
  32. }
  33.  
  34. ld dot(point a, point b) {
  35.     return a.x * b.x + a.y * b.y;
  36. }
  37.  
  38. ld cross(point a, point b) {
  39.     return a.x * b.y - a.y * b.x;
  40. }
  41.  
  42. struct line {
  43.     ld a, b, c;
  44.     line() {}
  45.     line(point p1, point p2) {
  46.         a = p2.y - p1.y;
  47.         b = p1.x - p2.x;
  48.         c = p1.y * p2.x - p2.y * p1.x;
  49.     }
  50.  
  51.     ld dist(point p) {
  52.         return abs((ld)(a * p.x + b * p.y + c) / sqrtl(a * a + b * b));
  53.     }
  54. };
  55.  
  56. const ld eps = 1e-6;
  57.  
  58. bool equals(ld a, ld b) {
  59.     return abs(a - b) < eps;
  60. }
  61.  
  62. bool positive(ld a) {
  63.     return a - eps >= 0;
  64. }
  65.  
  66. point intersec(line fi, line se) {
  67.     ld d = (ld)fi.a * se.b - fi.b * se.a;
  68.     ld x = (ld)(-fi.c * se.b + se.c * fi.b) / d, y = (ld)(-fi.a * se.c + se.a * fi.c) / d;
  69.     return point(x, y);
  70. }
  71.  
  72. ld pointToRay(point p, point a, point b) {
  73.     point ap = p - a;
  74.     if(dot(b - a, p - a) <= 0) {
  75.         return ap.len();
  76.     }
  77.     point ab = b - a;
  78.     return (ld)abs(cross(b - a, p - a)) / ab.len();
  79. }
  80.  
  81. ld pointToSegment(point p, point a, point b) {
  82.     if(dot(b - a, p - a) <= 0) {
  83.         point ap = p - a;
  84.         return ap.len();
  85.     }
  86.     if(dot(a - b, p - b) <= 0) {
  87.         point bp = p - b;
  88.         return bp.len();
  89.     }
  90.     point ab = a - b;
  91.     return (ld)abs(cross(b - a, p - a)) / ab.len();
  92. }
  93.  
  94. ld pointToLine(point p, point a, point b) {
  95.     line l(a, b);
  96.     return l.dist(p);
  97. }
  98.  
  99. bool pointOnRay(point p, point a, point b) {
  100.     return positive(dot(p - a, b - a));
  101. }
  102.  
  103. bool pointOnSegment(point p, point a, point b) {
  104.     return pointOnRay(p, a, b) && pointOnRay(p, b, a);
  105. }
  106.  
  107. ld rayToRay(point a, point b, point c, point d) {
  108.     ld dist = min(pointToRay(a, c, d), pointToRay(c, a, b));
  109.     line ab(a, b), cd(c, d);
  110.     point in = intersec(ab, cd);
  111.     if(pointOnRay(in, a, b) && pointOnRay(in, c, d)) {
  112.         dist = 0;
  113.     }
  114.     return dist;
  115. }
  116.  
  117. ld segToRay(point a, point b, point c, point d) {
  118.     ld dist = min(pointToRay(a, c, d), pointToRay(b, c, d));
  119.     line ab(a, b), cd(c, d);
  120.     point in = intersec(ab, cd);
  121.     if(pointOnSegment(in, a, b) && pointOnRay(in, c, d)) {
  122.         dist = 0;
  123.     }
  124.     return dist;
  125. }
  126.  
  127. ld segToSeg(point a, point b, point c, point d) {
  128.     ld dist = min(pointToSegment(a, c, d), pointToSegment(b, c, d));
  129.     dist = min(dist, min(pointToSegment(c, a, b), pointToSegment(d, a, b)));
  130.     if(cross(d - c, a - c) * cross(d - c, b - c) <= 0 &&
  131.        cross(b - a, c - a) * cross(b - a, d - c) <= 0) {
  132.         dist = 0;
  133.     }
  134.     return dist;
  135. }
  136.  
  137. ld rayToLine(point a, point b, point c, point d) {
  138.     line ab(a, b), cd(c, d);
  139.     ld dist = cd.dist(a);
  140.     point in = intersec(ab, cd);
  141.     if(pointOnRay(in, a, b)) {
  142.         dist = 0;
  143.     }
  144.     return dist;
  145. }
  146.  
  147. ld segToLine(point a, point b, point c, point d) {
  148.     line ab(a, b), cd(c, d);
  149.     ld dist = min(pointToLine(a, c, d), pointToLine(b, c, d));
  150.     point in = intersec(ab, cd);
  151.     if(pointOnSegment(in, a, b)) {
  152.         dist = 0;
  153.     }
  154.     return dist;
  155. }
  156.  
  157. ld lineToLine(point a, point b, point c, point d) {
  158.     if(cross(b - a, d - c) != 0) {
  159.         return 0;
  160.     }
  161.     return pointToLine(a, c, d);
  162. }
  163.  
  164. int main() {
  165.     FASTER();
  166.     cout.precision(30);
  167.     point a, b, c, d;
  168.     cin >> a >> b >> c >> d;
  169.  
  170.     point ac = c - a; //1. Расстояние от точки A до точки C.
  171.     cout << ac.len() << '\n';
  172.     cout << pointToSegment(a, c, d) << '\n'; //2. Расстояние от точки A до отрезка CD.
  173.     cout << pointToRay(a, c, d) << '\n'; //3. Расстояние от точки A до луча CD.
  174.     cout << pointToLine(a, c, d) << '\n'; //4. Расстояние от точки A до прямой CD.
  175.     cout << pointToSegment(c, a, b) << '\n'; //5. Расстояние от отрезка AB до точки C
  176.     cout << segToSeg(a, b, c, d) << '\n'; //6. Расстояние от отрезка AB до отрезка CD
  177.     cout << segToRay(a, b, c, d) << '\n'; //7. Расстояние от отрезка AB до луча CD.
  178.     cout << segToLine(a, b, c, d) << '\n'; //8. Расстояние от отрезка AB до прямой CD.
  179.     cout << pointToRay(c, a, b) << '\n'; //9. Расстояние от луча AB до точки C.
  180.     cout << segToRay(c, d, a, b) << '\n'; //10. Расстояние от луча AB до отрезка CD.
  181.     cout << rayToRay(a, b, c, d) << '\n'; //11. Расстояние от луча AB до луча CD.
  182.     cout << rayToLine(a, b, c, d) << '\n'; //12. Расстояние от луча AB до прямой CD
  183.     cout << pointToLine(c, a, b) << '\n'; //13. Расстояние от прямой AB до точки C
  184.     cout << segToLine(c, d, a, b) << '\n'; //14. Расстояние от прямой AB до отрезка CD
  185.     cout << rayToLine(c, d, a, b) << '\n'; //15. Расстояние от прямой AB до луча CD.
  186.     cout << lineToLine(a, b, c, d); //16. Расстояние от прямой AB до прямой CD.
  187. }
Add Comment
Please, Sign In to add comment