uses crt, graph;
const n=5; {Кол-во точек. n>1 иначе задача не имеет смысла}
Rad2Grad=180/pi; {Если не нужно преобразовывать радианы в
градусы заменяем 180/pi на 1}
BGI_path='c:\bp\bgi'; {путь к каталогу графических драйверов, при несовпадении указанного и реального его расположения, работа в графическом режиме невозможна}
var
 zoom,drive,mode,i,j:integer;
 x,y:real;
 points:array [1..n,1..4] of real; {здесь хранятся координаты}
 P_order:array [1..n] of integer; {Вспомогательный массив. Хранит индексы
точек в основном массиве. Определяет порядок обхода точек}
Function CalcZoom:integer; {определение коэф-та увеличения при построении линии}
var
 max_X, max_Y:real;
begin
 max_X:=abs(points[1,1]); {находим макс. по модулю значение Х и Y}
 max_Y:=abs(points[1,2]); {простым сравнением}
 for i:=2 to n do
  begin
   if abs(points[i,1])>max_X then max_X:=abs(points[i,1]);
   if abs(points[i,2])>max_Y then max_Y:=abs(points[i,2]);
  end;  
   if (GetMaxX-10) div round(2*max_X) < (GetMaxY-10) div round(2*max_Y) then
    CalcZoom:=(GetMaxX-10) div round(2*max_X) else
    CalcZoom:=(GetMaxY-10) div round(2*max_Y);
{оставляем поля по 5 пикселов по краям экрана, 5+5=10, поэтому вместо
GetMaxX и GetMaxY используем GetMaxX-10 и GetMaxY-10 соответственно
Т.к. каждая четверть построенной координатной плоскости равна половине ширины и половине
высоты экрана, делим макс. широту и высоту (за вычетом полей) на 2, и затем на max_Y или max_Х
соответственно. А потом выбираем меньшее из значений. Таким образом избавляемся от
возможности выскочить за пределы экрана и одновременно получаем автоматическое
масштабирование построенной линии}
end;
procedure XY2Polar(t:integer); {Перевод декартовых координат в полярные}
{Обозначим буквами r и ф полярные координаты
(расстояние до объекта от начала координат и
угол направления на объект соответственно)}
var
 r,phi:real;
begin
 x:=points[t,1]; {в принципе, переменные х и у вводить необязательно}
 y:=points[t,2]; {однако это повышает наглядность}
 r:=sqrt(sqr(x)+sqr(y));{вычисляем r по т.Пифагора, как гипотенузу
				 треугольника с катетами x и y}
 {т.к. x = r*cosф, y = r*sinф, -> y/x = sinф/cosф = tgф}
 phi:=arctan(y/x); {а из tgф, через arctg(tgф) получим угол ф}
 points[t,3]:=r; {и занесем преобразованные координаты}
 points[t,4]:=phi; {в ту же строку массива точек}
end;
function ComparePoints(a,b:integer):boolean;
{Функция сравнивает две точки по их координатам.
"Больше" та точка, угол которой больше,
а при одинаковом значении угла -
сравнивает по расстоянию. Возвращает True,
 если первая точка "больше" второй}
var t1,t2:integer;
begin
 t1:=P_order[a];
 t2:=P_order[b];
 ComparePoints:=(points[t1,4]>points[t2,4])
  or
 ((points[t1,4]=points[t2,4]) and (points[t1,3]>points[t2,3]));
end;
procedure Swap(a,b:integer);
{Процедура меняет местами индексы двух точек в массиве,
изменяя тем самым порядок их обхода}
var
 t:integer;
begin
 t:=P_order[a];
 P_order[a]:=P_order[b];
 P_order[b]:=t;
end;
begin
 For i:=1 to n do {вводим координаты n точек}
  begin
   Write('Точка ');
   Write(i);
   Writeln(' -  X:');
   readln(points[i,1]);
   Write('Точка ');
   Write(i);
   Writeln(' -  Y:');
   readln(points[i,2]);
   P_order[i]:=i; {заносим индекс очередной точки в массив}
   XY2Polar(i); {и преобразуем введенные координаты в полярные}
  end;
 For i:=1 to n-1 do {сортируем массив введенных координат
(а точнее - его индекс) методом простого выбора}
  begin
   For j:=i+1 to n do
    begin
     if ComparePoints(i,j) then
      Swap(i,j);
    end;
  end;
 WriteLn('Порядок обхода точек:'); {начинаем вывод результатов}
 For i:=1 to n do
  begin
   Write('Точка N:');
   Write((P_order[i]):3);
   Write(', Угол Ф:');
   Write((points[P_order[i],4]*Rad2Grad):6:2);
   Write(', Расстояние R:');
   Write(points[P_order[i],3]:6:2);
   Write(', X:');
   Write(points[P_order[i],1]:6:2);
   Write(', Y:');
   WriteLn(points[P_order[i],2]:6:2);
  end;
 WriteLn('Нажмите Enter...'); 	{Делаем паузу, чтобы можно было увидеть}
 ReadLn;		 	{результаты работы программы}
 {а теперь строим замкнутую ломаную в графическом режиме}
 drive:=detect;
 initgraph(drive,mode,BGI_path);
 zoom:=CalcZoom; {вычисляем масштаб}
 line(10,240,630,240); {Проводим ось Х}
 line(320,10,320,470); {и ось Y}
 line(630,240,610,235); {Стрелка на оси Х}
 line(630,240,610,245);
 line(320,10,315,30); {Стрелка на оси Y}
 line(320,10,325,30);
 For i:=1 to n do
  begin 
   x:=points[P_order[i],1]*zoom + (GetMaxX div 2);
   y:=(GetMaxY div 2) - points[P_order[i],2]*zoom;
{ставим точки, взяв за начало координат середину экрана, в масштабе 1:zoom
Т.к. на экране ось Y идет сверху вниз, координата по оси у берется с
противоположным знаком, или, проще говоря, отнимается от начала координат}
   if i>1 then LineTo(round(x),round(y));
{если точка не первая - проводим к ней линию от предыдущей} 
   Circle(round(x),round(y),1);
{обводим точку маленьким кружком для заметности}
  end;
   x:=points[P_order[1],1]*zoom + (GetMaxX div 2);
   y:=(GetMaxY div 2) - points[P_order[1],2]*zoom;
   LineTo(round(x),round(y)); {замыкаем линию}
 repeat until keypressed; {и ждем нажатия клавиши для завершения работы}
 closegraph;
end.