2009-04-23 4 views
0
typedef pair<double, double> dd; 

    const double epsilon = 1e-6; 

    struct sort_by_polar_angle { 
    dd center; 
    // Constuctor of any type 
    // Just find and store the center 
    template<typename T> sort_by_polar_angle(T b, T e) { 
     int count = 0; 
     center = dd(0,0); 
     while(b != e) { 
        center.first += b->first; 
        center.second += b->second; 
       b++; 
      count++; 
     } 
       double k = count ? (1.0/count) : 0; 
     center.first *= k; 
       center.second *= k; 
    } 
    // Compare two points, return true if the first one is earlier 
    // than the second one looking by polar angle 
    // Remember, that when writing comparator, you should 
    // override not ‘operator <’ but ‘operator()’ 
    bool operator() (const dd& a, const dd& b) const { 
     double p1 = atan2(a.second-center.second, a.first-center.first); 
     double p2 = atan2(b.second-center.second, b.first-center.first); 
     return p1 + epsilon < p2; 
    } 
    }; 

// ... 

vector <dd> points; 

sort(all(points), sort_by_polar_angle(all(points))); 

Когда вызывается sort_by_polar_angle(), является ли он функцией construnctor? Как правильно используется перегруженный оператор()?Почему этот образец работает?

+0

что все(), sort_by_polar_angle - это конструктор, но не тот, который вы показывали, поскольку у них разное количество аргументов. – Patrick

+0

Это тоже неправильно. У вас не должно быть epsilon в заказе. если a == b и a == c, тогда b == c. – MSalters

+1

Хотя это явно уродливо, я уверен, что все (C) должны быть определены как #define для "C.begin(), C.end()" –

ответ

4

Когда вы вызываете sort_by_polar_angle() в функцию sort(), вы создаете временный объект типа sort_by_polar_angle (т. Е. Его конструктор называется). Внутри алгоритма сортировки объект-функтор, который вы передали, используется примерно как functor(), который будет переведен в functor.operator().

0

Он не будет работать для точек на прямой линии от центра. «Угол» их равен, поэтому их порядок не определен. Сортировка этих точек вернет неопределенные результаты.

Это потому, что любая операция сортировки должна быть «строгой»: если < b, то b> a. (На самом деле definition несколько сложнее.)

dd a0 = { 0, 1 }; 
dd b0 = { 0, 2 }; 

assert(sort_by_polar_angle()(a0, b0) && ! sort_by_polar_angle() (b0, a0)); 
Смежные вопросы