(B) Как мне реализовать этап сортировки с использованием библиотеки C ++ STL (функция сортировки в алгоритме)? Особенно я имею в виду сортировку (P + 1, P + N, компаратор). Как мне определить функцию компаратора?
Я предлагаю вам избегать беспорядочной арифметики с плавающей запятой. Как показано в упражнении 33.1-3 той же книги, вы можете просто отсортировать по полярному углу с помощью перекрестных произведений. Вот как это сделать:
struct Point {int x,y;}
int operator^(Point p1, Point p2) {return p1.x*p2.y - p1.y*p2.x;}
Point p0; //set this separately
bool operator<(Point p1, Point p2)
{
p1=p1-p0; p2=p2-p0;
if(p1.y==0&&p1.x>0) return true; //angle of p1 is 0, thus p2>p1
if(p2.y==0&&p2.x>0) return false; //angle of p2 is 0 , thus p1>p2
if(p1.y>0&&p2.y<0) return true; //p1 is between 0 and 180, p2 between 180 and 360
if(p1.y<0&&p2.y>0) return false;
return (p1^p2)>0; //return true if p1 is clockwise from p2
}
(A) Что это означает, что мне делать, если несколько точек имеют одинаковый полярный угол относительно Po?
Если p0, pi и pj коллинеарны, только самый дальний от p0 может быть частью выпуклой оболочки. Таким образом, мы должны убрать остальные точки. Мы можем сделать это на C ++. Начнем с определения скалярного произведения,
int operator*(Point p1, Point p2) {return p1.x*p2.x + p1.y*p2.y;}
и добавив эту строку в компаратор:
if((p1^p2)==0&&p1*p2>0) return p1*p1<p2*p2;
Теперь при одинаковом угле точки будут отсортированы по расстоянию от p0. Теперь мы можем использовать функцию unique
из STL, чтобы удалить точки, как требуется, из vector<Point> P
:
sort(P.begin(),P.end());
P.erase(unique(P.begin(),P.end(),eq),P.end());
Здесь функция eq
возвращает истину, если точки имеют одинаковый угол.
bool eq(Point p1, Point p2)
{
p1=p1-p0; p2=p2-p0;
return ((p1^p2)==0&&p1*p2>0);
}
person
akshat
schedule
11.06.2013