Beingamanforever

geometry template

Nov 8th, 2024
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.36 KB | None | 0 0
  1. int dblcmp(double d) // Compare double to epsilon for zero checking
  2. {
  3.     if (fabs(d) < eps) return 0;
  4.     return d > eps ? 1 : -1;
  5. }
  6.  
  7. inline double sqr(double x) // Square of a number
  8. {
  9.     return x * x;
  10. }
  11.  
  12. struct point
  13. {
  14.     double x, y;
  15.     point() {} // Default constructor
  16.     point(double _x, double _y) : x(_x), y(_y) {} // Parameterized constructor
  17.  
  18.     bool operator==(point a) const // Check if points are equal
  19.     {
  20.         return dblcmp(a.x - x) == 0 && dblcmp(a.y - y) == 0;
  21.     }
  22.  
  23.     bool operator<(point a) const // Compare points lexicographically
  24.     {
  25.         return dblcmp(a.x - x) == 0 ? dblcmp(y - a.y) < 0 : x < a.x;
  26.     }
  27.  
  28.     double len() // Length of the vector from origin
  29.     {
  30.         return hypot(x, y);
  31.     }
  32.  
  33.     double len2() // Square of length from origin
  34.     {
  35.         return x * x + y * y;
  36.     }
  37.  
  38.     double distance(point p) // Distance between two points
  39.     {
  40.         return hypot(x - p.x, y - p.y);
  41.     }
  42.  
  43.     point add(point p) // Vector addition of two points
  44.     {
  45.         return point(x + p.x, y + p.y);
  46.     }
  47.  
  48.     point sub(point p) // Vector subtraction of two points
  49.     {
  50.         return point(x - p.x, y - p.y);
  51.     }
  52.  
  53.     point mul(double b) // Scalar multiplication
  54.     {
  55.         return point(x * b, y * b);
  56.     }
  57.  
  58.     point div(double b) // Scalar division
  59.     {
  60.         return point(x / b, y / b);
  61.     }
  62.  
  63.     double dot(point p) // Dot product
  64.     {
  65.         return x * p.x + y * p.y;
  66.     }
  67.  
  68.     double det(point p) // Determinant (cross product magnitude)
  69.     {
  70.         return x * p.y - y * p.x;
  71.     }
  72.  
  73.     double rad(point a, point b) // Angle between vectors (a, this), (b, this)
  74.     {
  75.         point p = *this;
  76.         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))), a.sub(p).dot(b.sub(p))));
  77.     }
  78.  
  79.     point trunc(double r) // Truncate vector to length r
  80.     {
  81.         double l = len();
  82.         if (!dblcmp(l)) return *this;
  83.         r /= l;
  84.         return point(x * r, y * r);
  85.     }
  86.  
  87.     point rotleft() // Rotate 90 degrees counterclockwise
  88.     {
  89.         return point(-y, x);
  90.     }
  91.  
  92.     point rotright() // Rotate 90 degrees clockwise
  93.     {
  94.         return point(y, -x);
  95.     }
  96.  
  97.     point rotate(point p, double angle) // Rotate around point p by angle
  98.     {
  99.         point v = this->sub(p);
  100.         double c = cos(angle), s = sin(angle);
  101.         return point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
  102.     }
  103. };
  104.  
  105. struct line
  106. {
  107.     point a, b;
  108.  
  109.     line(point _a, point _b) : a(_a), b(_b) {} // Line from two points
  110.  
  111.     bool operator==(line v) // Check if two lines are equal
  112.     {
  113.         return (a == v.a) && (b == v.b);
  114.     }
  115.  
  116.     double length() // Length of the line segment
  117.     {
  118.         return a.distance(b);
  119.     }
  120.  
  121.     double angle() // Angle of the line in radians
  122.     {
  123.         double k = atan2(b.y - a.y, b.x - a.x);
  124.         if (dblcmp(k) < 0) k += pi;
  125.         if (dblcmp(k - pi) == 0) k -= pi;
  126.         return k;
  127.     }
  128.  
  129.     int relation(point p) // Relation of point to line (clockwise, counterclockwise, collinear)
  130.     {
  131.         int c = dblcmp(p.sub(a).det(b.sub(a)));
  132.         if (c < 0) return 1;
  133.         if (c > 0) return 2;
  134.         return 3;
  135.     }
  136.  
  137.     bool pointonseg(point p) // Check if point is on segment
  138.     {
  139.         return dblcmp(p.sub(a).det(b.sub(a))) == 0 && dblcmp(p.sub(a).dot(p.sub(b))) <= 0;
  140.     }
  141.  
  142.     bool parallel(line v) // Check if two lines are parallel
  143.     {
  144.         return dblcmp(b.sub(a).det(v.b.sub(v.a))) == 0;
  145.     }
  146.  
  147.     int segcrossseg(line v) // Check if segments cross
  148.     {
  149.         int d1 = dblcmp(b.sub(a).det(v.a.sub(a)));
  150.         int d2 = dblcmp(b.sub(a).det(v.b.sub(a)));
  151.         int d3 = dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
  152.         int d4 = dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
  153.         if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2;
  154.         return (d1 == 0 && dblcmp(v.a.sub(a).dot(v.a.sub(b))) <= 0 ||
  155.                 d2 == 0 && dblcmp(v.b.sub(a).dot(v.b.sub(b))) <= 0 ||
  156.                 d3 == 0 && dblcmp(a.sub(v.a).dot(a.sub(v.b))) <= 0 ||
  157.                 d4 == 0 && dblcmp(b.sub(v.a).dot(b.sub(v.b))) <= 0);
  158.     }
  159.  
  160.     int linecrossseg(line v) // Check if segment crosses line
  161.     {
  162.         int d1 = dblcmp(b.sub(a).det(v.a.sub(a)));
  163.         int d2 = dblcmp(b.sub(a).det(v.b.sub(a)));
  164.         if ((d1 ^ d2) == -2) return 2;
  165.         return (d1 == 0 || d2 == 0);
  166.     }
  167.  
  168.     point crosspoint(line v) // Intersection point of two lines
  169.     {
  170.         double a1 = v.b.sub(v.a).det(a.sub(v.a));
  171.         double a2 = v.b.sub(v.a).det(b.sub(v.a));
  172.         return point((a.x * a2 - b.x * a1) / (a2 - a1), (a.y * a2 - b.y * a1) / (a2 - a1));
  173.     }
  174.  
  175.     double dispointtoline(point p) // Distance from point to line
  176.     {
  177.         return fabs(p.sub(a).det(b.sub(a))) / length();
  178.     }
  179.  
  180.     double dispointtoseg(point p) // Distance from point to segment
  181.     {
  182.         if (dblcmp(p.sub(b).dot(a.sub(b))) < 0 || dblcmp(p.sub(a).dot(b.sub(a))) < 0)
  183.         {
  184.             return min(p.distance(a), p.distance(b));
  185.         }
  186.         return dispointtoline(p);
  187.     }
  188.  
  189.     point lineprog(point p) // Projection of point onto line
  190.     {
  191.         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a)) / b.sub(a).len2()));
  192.     }
  193.  
  194.     point symmetrypoint(point p) // Symmetry point across line
  195.     {
  196.         point q = lineprog(p);
  197.         return point(2 * q.x - p.x, 2 * q.y - p.y);
  198.     }
  199. };
  200.  
Advertisement
Add Comment
Please, Sign In to add comment