Advertisement
facug91

Untitled

Nov 10th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.60 KB | None | 0 0
  1. struct point {
  2.     double x, y;
  3.     point() {x = y = 0.0;}
  4.     point(double x, double y) : x(x), y(y) {}
  5. };
  6.  
  7. struct line {
  8.     double a, b, c;
  9.     double f (double x) {return -a * x - c;}
  10. };
  11.  
  12. struct circle {
  13.     point c;
  14.     double r;
  15.     circle() {
  16.         r = 0.0;
  17.         c = point();
  18.     }
  19.     circle (point c, double r) : c(c), r(r) {}
  20. };
  21.  
  22. point to_vec (const point& a, const point& b) {
  23.     return point(b.x-a.x, b.y-a.y);
  24. }
  25.  
  26. point scale (const point& v, double s) {
  27.     return point(v.x * s, v.y * s);
  28. }
  29.  
  30. point translate (const point& p, const point& v) {
  31.     return point(p.x+v.x, p.y+v.y);
  32. }
  33.  
  34. double dot (const point& a, const point& b) {
  35.     return a.x * b.x + a.y * b.y;
  36. }
  37. double norm_sq (const point& v) {
  38.     return v.x * v.x + v.y * v.y;
  39. }
  40.  
  41. double norm (const point& v) {
  42.     return sqrt(norm_sq(v));
  43. }
  44.  
  45. double dist_point (const point& a, const point& b) {
  46.     return sqrt((a.x-b.x)*(a.x-b.x)*(a.y-b.y)*(a.y-b.y));
  47. }
  48.  
  49. double dist_to_line (const point& p, const point& a, const point& b, point& c) {
  50.     // formula: c = a + u * ab
  51.     point ap = to_vec(a, p), ab = to_vec(a, b);
  52.     double u = dot(ap, ab) / norm_sq(ab);
  53.     c = translate(a, scale(ab, u));
  54.     return dist_point(p, c);
  55. }
  56.  
  57. void points_to_line (const point& p1, const point& p2, line& l) {
  58.     if (fabs(p1.x - p2.x) < EPS) {
  59.         l.a = 1.0; l.b = 0.0; l.c = -p1.x;
  60.     } else {
  61.         l.a = -(p1.y - p2.y) / (p1.x - p2.x);
  62.         l.b = 1.0;
  63.         l.c = -(l.a * p1.x) - p1.y;
  64.     }
  65. }
  66.  
  67. int are_intersect (const circle& c, line& l, pair<point, point>& ans) {
  68.     point close;
  69.     dist_to_line(point(1.0, l.f(1.0)), point(2.0, l.f(2.0)), c.c, close);
  70.     double dis = dist_point(close, c.c);
  71.     if (dis > c.r) return 0;
  72.     if (fabs(dis - c.r) < EPS) {
  73.         ans.first = close;
  74.         return 1;
  75.     }
  76.     double cat = sqrt(c.r*c.r - dis*dis);
  77.     point vec = to_vec(point(1.0, l.f(1.0)), point(2.0, l.f(2.0)));
  78.     vec = scale(vec, cat/norm(vec));
  79.     ans.first = translate(close, vec);
  80.     ans.second = translate(close, scale(vec, -1.0));
  81.     return 2;
  82. }
  83.  
  84. bool in_box (const point& p1, const point& p2, const point& q) {
  85.     return min(p1.x, p2.x) <= q.x && q.x <= max(p1.x, p2.x) && min(p1.y, p2.y) <= q.y && q.y <= max(p1.y, p2.y);
  86. }
  87.  
  88. int are_intersect (const point& p, const point& q, const circle& c, pair<point, point>& ans) {
  89.     line l;
  90.     points_to_line(p, q, l);
  91.     int cnt = are_intersect(c, l, ans);
  92.     if (cnt == 0) return 0;
  93.     if (cnt == 1) {
  94.         if (in_box(p, q, ans.first)) return 1;
  95.         else return 0;
  96.     } else {
  97.         if (in_box(p, q, ans.first)) {
  98.             if (in_box(p, q, ans.second)) {
  99.                 ans.first = ans.second;
  100.                 return 1;
  101.             } else return 1;
  102.         } else if (in_box(p, q, ans.second)){
  103.             return 2;
  104.         } else {
  105.             return 0;
  106.         }
  107.     }
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement