Advertisement
caioaao

Untitled

May 4th, 2014
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.91 KB | None | 0 0
  1.  
  2. inline double dist2(point a, point b){ return (a.first - b.first)*(a.first - b.first) + (a.second - b.second)*(a.second - b.second);}
  3.  
  4.  
  5. inline point toVec(point a, point b){ return point(b.first-a.first,b.second-a.second); }
  6.  
  7. inline double dot(point a, point b){ return a.first *b.first + a.second * b.second; }
  8.  
  9. inline double norm_sq(point v){ return v.first*v.first + v.second * v.second;}
  10.  
  11. inline double distToLine(point p, point a, point b){
  12.     point  c;
  13.     point ap = toVec(a, p), ab = toVec(a, b);
  14.     double u = dot(ap,ab) / (double)norm_sq(ab);
  15.     c.first  = (double)a.first + ab.first*u;
  16.     c.second = (double)a.second + ab.second*u;
  17.     return sqrt(dist2(a,c));
  18. }
  19. inline double orientation(point p, point q, point r){
  20.     return (q.second - p.second) * (r.first - p.first) - (q.first - p.first) * (r.second - p.second);
  21. }
  22. void convexHull(){ // Andrew's Monotone Chain Algorithm
  23.     up.assign(n,point()); dn.assign(n,point());
  24.    
  25.     int i = 0, j = 0;
  26.    
  27.     for(int k = 0; k < n; k++){
  28.         while(i > 1 && orientation(up[i-2], up[i-1], pts[k]) <= 0) i--;
  29.         while(j > 1 && orientation(dn[j-2], dn[j-1], pts[k]) >= 0) j--;
  30.        
  31.         up[i++] = pts[k];
  32.         dn[j++] = pts[k];
  33.     }
  34.     chPts.assign(i+j-2,point());
  35.     for(int k = 0; k < j; k++) chPts[k] = dn[k];
  36.     for(int k = i-2, l = j; k > 0; k--, l++) chPts[l] = up[k];
  37. }
  38.  
  39. inline int nxt(int id){ return (id+1)%chPts.size(); }
  40. inline int prev(int id){ return (id == 0 ? (int)chPts.size() : id) - 1;}
  41.  
  42. void rotatingCalipers(){
  43.     int maxX=0,minX=0,minY=0,maxY=0;
  44.     for(int i = 1; i < n; i++){ // extremos
  45.         if(chPts[maxX].first < chPts[i].first) maxX = i;
  46.         if(chPts[minX].first > chPts[i].first) minX = i;
  47.         if(chPts[maxY].second < chPts[i].second) maxY = i;
  48.         if(chPts[minY].second > chPts[i].second) minY = i;
  49.     }
  50.    
  51.     int p[4] = {minX, minY, maxX, maxY}, p0[4];
  52.     for(int i = 0; i < 4; i++){
  53.         p0[i] = prev(p[(i + 2)%4]);
  54.     }
  55.        
  56.     double ansAr = 1e8, ansPer = 1e8, l1, l2;
  57.     while(1){
  58.         bool ok = false;
  59.         for(int i = 0; i < 4; i++) if(p[i] != p0[i]){ ok = true; break;}
  60.         if(!ok)break;
  61.        
  62.         int incr = -1, ia, ib, ic, id, ie;
  63.         for(int i = 0; i < 4; i++){
  64.             if(p[i] == p0[i]) continue;
  65.             if(incr == -1) incr = i;
  66.             else{
  67.                 if((chPts[nxt(p[i])].second - chPts[p[i]].second) * (chPts[p[incr]].first - chPts[nxt(p[incr])].first )
  68.                     > (chPts[p[incr]].second - chPts[nxt(p[incr])].second) * (chPts[nxt(p[i])].first - chPts[p[i]].first))
  69.                     incr = i;
  70.             }
  71.         }
  72.         // ia e ib: line segment AB
  73.         ia = p[incr];
  74.         ib = p[incr] = nxt(p[incr]);
  75.         // ic e id: points that touch the sides orthogonal to AB
  76.         ic = p[(incr == 0 ? 4 : incr)-1];
  77.         id = p[(incr+1)%4];
  78.         // ie: opposite to the segment
  79.         ie = p[(incr+2)%4];
  80.         l1 = distToLine(chPts[ie],chPts[ia],chPts[ib]);
  81.        
  82.         point ab = toVec(chPts[ia], chPts[ib]), cd = toVec(chPts[ic], chPts[id]);
  83.  
  84.         // Projection of CD on AB
  85.         l2 = fabs(dot(ab,cd) / (double)norm_sq(ab));
  86.    
  87.         ansAr = min(ansAr, l1*l2);
  88.         ansPer = min(ansPer,2*(l1+l2));
  89.     }
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement