HalfPlaneIntersection.cpp 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // INTERSECTION DE DEMI-PLAN
  2. // demi-plan : à gauche de la ligne
  3. struct Line {
  4. PT P; // point
  5. PT v; // vecteur directeur
  6. double ang;
  7. Line() {}
  8. Line(PT P, PT v):P(P),v(v){ ang = atan2(v.y, v.x); }
  9. bool operator < (const Line& L) const {
  10. return ang < L.ang;
  11. }
  12. };
  13. bool OnLeft(const Line& L, const PT& p) {
  14. return cross(L.v, p-L.P) > 0;
  15. }
  16. PT GetLineIntersection(const Line& a, const Line& b) {
  17. return ComputeLineIntersection(a.P, a.P+a.v, b.P, b.P+b.v);
  18. }
  19. // INPUT : set of half-plane
  20. // OUPUT : polygon (if exists)
  21. // COMPLEXITY n log n ?
  22. vector<PT> HalfplaneIntersection(vector<Line> L) {
  23. int n = L.size();
  24. sort(L.begin(), L.end());
  25. int first, last;
  26. vector<PT> p(n);
  27. vector<Line> q(n);
  28. vector<PT> ans;
  29. q[first=last=0] = L[0];
  30. for(int i = 1; i < n; i++) {
  31. while(first < last && !OnLeft(L[i], p[last-1])) last--;
  32. while(first < last && !OnLeft(L[i], p[first])) first++;
  33. q[++last] = L[i];
  34. if(fabs(cross(q[last].v, q[last-1].v)) < EPS) {
  35. last--;
  36. if(OnLeft(q[last], L[i].P)) q[last] = L[i];
  37. }
  38. if(first < last) p[last-1] = GetLineIntersection(q[last-1], q[last]);
  39. }
  40. while(first < last && !OnLeft(q[first], p[last-1])) last--;
  41. if(last - first <= 1) return ans;
  42. p[last] = GetLineIntersection(q[last], q[first]);
  43. for(int i = first; i <= last; i++) ans.push_back(p[i]);
  44. return ans;
  45. }