Advertisement
dmkozyrev

add_to_other_convex_hull

Jan 21st, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.14 KB | None | 0 0
  1. void add_to_other_convex_hull(Points & hull, const Point & p){
  2. //  Добавляет новую точку к выпуклой оболочке, состоящей больше, чем из двух точек
  3.  
  4.     int begin=-1, end=-1, len=0, i=0, j=1, n = hull.size();
  5.     double sq; 
  6.    
  7. //  Ищем минимальный отрезок [i, j] (i и j - соседние вершины) по следующим правилам:
  8. //  1) Ориентированная площадь треугольника с вершинами i-p-j не отрицательна
  9. //  2) Точка p не принадлежит отрезку, образованному вершинами i-j
  10.     do {
  11.         sq = square_triangle(hull[i], p, hull[j]);
  12.         if (sq == 0 && in_interval(hull[i], hull[j], p)) return; // (условие 2)     
  13.         if (sq >= 0) break; // (условие 1)
  14.         inc(i, n);
  15.         inc(j, n);
  16.     } while (i != 0);
  17.    
  18. //  Если отрезок не найден, то точку добавлять не нужно:
  19.     if (i == 0) return;
  20.        
  21. //  Затем необходимо расширить найденный отрезок из вершин выпуклой оболочки до максимально возможного
  22.    
  23. //  Расширение вправо
  24.     i = j = end; inc(j, n);
  25.     while (square_triangle(hull[i], p, hull[j]) >= 0){
  26.         end = j;
  27.         inc(i, n);
  28.         inc(j, n);
  29.     }  
  30.    
  31. //  Расширение влево
  32.     i = j = begin; dec(i, n);
  33.     while (square_triangle(hull[i], p, hull[j]) >= 0){
  34.         begin = i;
  35.         dec(i, n);
  36.         dec(j, n);
  37.     }  
  38.    
  39. //  Теперь найденный отрезок выпуклой оболочки необходимо модифицировать
  40.    
  41. //  Вычисляем длину отрезка [begin, end] по модулю n:
  42.     mod(len = end-begin, n);
  43.  
  44.     if (begin > end && end != 0) { // Если начало отрезка больше конца
  45.         shift_points_left(hull, end); // То сдвигаем все элементы оболочки влево на величину, равную концу отрезка
  46.         begin -= end;
  47.         end -= end;
  48.     }
  49.  
  50. //  Крайние точки мы должны оставить в покое, поэтому:
  51.     inc(begin, n); // Увеличиваем на единицу начало отрезка
  52.     dec(end, n); // Уменьшаем на единицу конец отрезка
  53.  
  54.     switch (len){ // В зависимости от длины отрезка
  55.         case 0: return; // Ничего не делаем, если длина отрезка равна 0
  56.         case 1: hull.emplace(hull.begin()+begin, p); break; // Вставляем новую точку, если длина отрезка равна 1
  57.         case 2: hull[begin] = p; break; // Заменяем точку, расположенную вначале отрезка, на новую точку
  58.         default:
  59.             hull[begin] = p; // Заменяем точку вначале отрезка на новую точку
  60.             inc(begin, n); // Увеличиваем начало отрезка
  61.             erase_from_points(hull, begin, end); // Вырезаем все остальные точки из отрезка [begin, end]
  62.             break;
  63.     }
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement