Важная информация
Показано с 1 по 2 из 2

Тема: Объясните пожалуйста, как работает программа

  1. #1 Объясните пожалуйста, как работает программа 
    Новичок
    Регистрация
    05.06.2015
    Сообщений
    1
    Сказал(а) спасибо
    0
    Поблагодарили 0 раз(а) в 0 сообщениях
    Помогите! Нужно понять, как устроена работа данной программы, а именно, как происходит поиск точек для построения выпуклой оболочки. Если можно, то в виде комментарий к отдельным строкам кода
    Pascal Code:
    1. uses crt,graphABC;
    2. type TPoint=record
    3. x,y: real;
    4. end;
    5. Tvyp=record
    6. x,y:real;
    7. k:integer;{номер точки}
    8. end;
    9. const maxn=1000;
    10. {находится ли точка левее луча}
    11. function IsLeft(p,p1,p2:TPoint):boolean;
    12. begin
    13. IsLeft:=(p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x)>0;
    14. end;
    15. var n,m,i,t1,t,newt:integer;
    16. x0,y0:integer;
    17. ms,a,b:real;
    18. g,z:text;
    19. p:array of TPoint; {Точки множества}
    20. p1:array [1..maxn] of TVyp; {Точки выпуклой оболочки}
    21. used:array [1..maxn] of boolean;{Принадлежит-не принадлежит оболочке}
    22. begin
    23. writeln('Задайте количество точек, а также их координаты в текстовом файле Points (координаты в формате: Х У)');
    24. readln;
    25. writeln('Множество точек:');
    26. assign(g, 'D:\Points.txt');
    27. reset(g);
    28. read(g, n);
    29. setlength(p,n+1);
    30. for i :=1 to n do
    31. begin
    32. read(g, a);
    33. p[i].x :=a;
    34. read(g, b);
    35. p[i].y :=b;
    36. write('P[',i:2,'](',p[i].x:5:2,';',p[i].y:5:2,') ');
    37. if i mod 4=0 then writeln;
    38. end;
    39. t1:=1;{первая точка}
    40. for i:=1 to n do
    41. begin
    42. if (p[i].y<p[t1].y) then t1:=i else
    43. if (p[i].y=p[t1].y) and (p[i].x<p[t1].x) then t1:=i;
    44. end;
    45. for i:=1 to n do
    46. used[i]:=false;
    47. writeln;
    48. writeln('Выпуклая оболочка идет через вершины: ');
    49. t:=t1;
    50. m:=0;
    51. repeat
    52. m:=m+1;
    53. p1[m].x:=p[t].x;p1[m].y:=p[t].y;p1[m].k:=t;
    54. used[t]:=true;
    55. newt:=0;
    56. { Поиск следующей вершины }
    57. for i:=1 to n do
    58. if i<>t then
    59. if (newt=0) or (IsLeft(p[t], p[i], p[newt]))then newt:=i;
    60. t:=newt;
    61. until t=t1;
    62. assign(z,'D:\Koordinati.txt');
    63. rewrite(z);
    64. write(z,'Вершины многоугольника:');
    65. for i:=1 to m do
    66. write(z,'P[',p1[i].k:2,'](',p1[i].x:5:2,';',p1[i].y:5:2,') ');
    67. if i mod 4=0 then writeln;
    68. m:=m+1;
    69. p1[m].x:=p1[1].x;p1[m].y:=p1[1].y;
    70. close(z);
    71. for i:=1 to m do
    72. write('P[',p1[i].k:2,'](',p1[i].x:5:2,';',p1[i].y:5:2,') ');
    73. if i mod 4=0 then writeln;
    74. m:=m+1;
    75. p1[m].x:=p1[1].x;p1[m].y:=p1[1].y;{замкнем оболочку}
    76. writeln;
    77. write('Нажмите Enter для проверки результата графически');
    78. readln;
    79. clearwindow;
    80. setwindowsize(1200,1100);
    81. x0:=windowwidth div 2;
    82. y0:=windowheight div 2;
    83. ms:=(y0-20)/10;
    84. line(x0-y0-1000,y0,x0+y0+1000,y0);
    85. textout(x0+y0+250,y0-17,'X');
    86. line(x0,-1000,x0,windowheight+1000);
    87. textout(x0+5,10,'Y');
    88. textout(x0+5,y0+10,'0');
    89. for i:=1 to 100 do
    90. begin
    91. line(x0-3,y0-round(i*ms),x0+3,y0-round(i*ms));{засечки на оси У}
    92. line(x0-3,y0+round(i*ms),x0+3,y0+round(i*ms));
    93. line(x0+round(i*ms),y0-3,x0+round(i*ms),Y0+3); {засечки на оси Х}
    94. line(x0-round(i*ms),y0-3,x0-round(i*ms),Y0+3);
    95. {подпись оси У}
    96. textout(x0-20,y0-round(i*ms),inttostr(i));{соответственно засечкам}
    97. textout(x0-30,y0+round(i*ms),inttostr(-i));
    98. {подпись оси Х}
    99. textout(x0+round(i*ms),y0+10,inttostr(i));
    100. textout(x0-round(i*ms),y0+10,inttostr(-i));
    101. end;
    102. setpencolor(clBlue);
    103. moveto(x0+round(p1[1].x*ms),y0-round(p1[1].y*ms));
    104. for i:=1 to m do
    105. lineto(x0+round(p1[i].x*ms),y0-round(p1[i].y*ms));
    106. setpencolor(clRed);
    107. setfontcolor(clRed);
    108. for i:=1 to n do
    109. begin
    110. circle(x0+round(p[i].x*ms),y0-round(p[i].y*ms),2);
    111. textout(x0+round(p[i].x*ms)+5,y0-round(p[i].y*ms),inttostr(i));
    112. end;
    113. end.
    Ответить с цитированием  
     

  2. #2  
    Профи Аватар для Сионист
    Регистрация
    21.01.2016
    Адрес
    Галактика Млечный Путь
    Сообщений
    509
    Сказал(а) спасибо
    11
    Поблагодарили 21 раз(а) в 20 сообщениях
    Я пока прогнал.

    Pascal Code:
    1. uses crt,graphABC; {Это просто декларация исспользования двух модулей}
    2. type {Заголовок раздела типов}
    3.      TPoint=record {Здесь начинается описание типа составной величины, в данном случае записи, а завот его TPoint}
    4.                   x, y: real; {Здесь декларированы два поля типа real, зовут их x и y, поля - это данные, из которых состоит запись}
    5.             end;
    6.      Tvyp=record {Здесь начинается описание типа составной величины, в данном случае записи, а завот его Tvyp}
    7.                   x, y:real; {Здесь декларированы два поля типа real, зовут их x и y, поля - это данные, из которых состоит запись}
    8.                   k:integer;{А здесь декларировано пле типа integer, зовут его k. Данное поле - номер точки}
    9.             end;
    10. const {Заголовок раздела констант}
    11.       maxn=1000; {Декларация именованной константы, зовут её maxn, а равна она 1000}
    12. {находится ли точка левее луча}
    13. function IsLeft(p, p1, p2:TPoint):boolean; {Просто заголовок функции. Зовут её IsLeft, она принимает три параметра типа TPoint с внутренними (для самой функции) именами p, p1 и p2, а возвращает значение типа boolean}
    14. begin{Здесь начинается раздел операций функции IsLeft}
    15.      IsLeft:=(p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x)>0; {А здесь сказано вернуть в качестве значения функии IsLeft true в том и только в том случае, если выражение (p1.x-p.x)*(p2.y-p.y)-(p1.y-p.y)*(p2.x-p.x) строго больше ноля. Геометрический смысл этого условия - точка p определённым образом расположена относительно прямой p1p2. Построй на бумажке и посмотри}
    16. end;{Здесь раздел операций функции IsLeft заканчивается}
    17. var {Заголовок раздела переменных самой программы}
    18.     n, m, i, t1, t, newt:integer; {Декларация переменных типа nteger, а зовут их n, m, i, t1, t и newt}
    19.     x0,y0:integer; {Декларация ещё двух переменных типа nteger, а зовут их x0 и y0}
    20.     ms, a, b:real; {Деларация переменных типа real, а зовут их ms, a и b}
    21.     g, z:text; {Деларация переменных типа text, а зовут их g и z}
    22.     p:array of TPoint; {Дакларация динамического массива элементов типа TPoint, массив зовут p (в самой программе, не в функции)}
    23.     p1:array [1..maxn] of TVyp; {Дакларация статического массива элементов типа Tvyp, массив зовут p1 (в самой программе, не в функции), массив одномерен, то есть у
    24. элементов по одному индексу, индексы могут иметь значения от 1 до maxn}
    25.     used:array [1..maxn] of boolean; {Декларация статического массива элементов типа boolean, массив зовут used, массив одномерен, то есть у
    26. элементов по одному индексу, индексы могут иметь значения от 1 до maxn, какждый элемент равен true в том и только в том случае, если нечто с тем же индексом принадлежит некой оболочке}
    27. begin {Здесь начинается раздел операций самой программы}
    28.      writeln('Задайте количество точек, а также и координаты в текстовом файле Points (координаты в формате: Х У)'); {Данная строка программы выводи на экран строку "Задайте количество точек, а также и координаты в текстовом файле Points (координаты в формате: Х У)"}
    29.      readln; {А здесь происходит ожидание нажатия кнопки enter и потом переход на следующую экранную строку}
    30.      writeln('Множество точек:'); {Данная строка программы выводи на экран строку "Множество точек:"}
    31.      assign(g, 'D:\Points.txt'); {Здесь переменная g связывается с файлом D:\Points.txt}
    32.      reset(g); {Позиция чтения переменной g, а значит и файла D:\Points.txt устанавливается на начало}
    33.      read(g, n); {Из переменной g, а значит и из файла D:\Points.txt читается переменная n}
    34.      setlength(p, n+1); {После этого массив p состоит из n+1 элементов}
    35.      for i :=1 to n do {Заголовок цикла со счётчиком, счётчик последовательно принимает значения от 1 до n, а зовут его i, для каждого значения счётчика один раз выполняется тело цикла}
    36.      begin {Начало тела цикла}
    37.           read(g, a); {Из переменной g, а значит и из файла D:\Points.txt читается переменная a}
    38.           p[i].x :=a; {Переменная a копируется в поле x i-го элемента p}
    39.           read(g, b); {Из переменной g, а значит и из файла D:\Points.txt читается переменная b}
    40.           p[i].y :=b; {Переменная b копируется в поле y i-го элемента p}
    41.           write('P[',i:2,'](',p[i].x:5:2,';',p[i].y:5:2,') '); {На экран выводится буква P, потом в квадратных скобках значение переменной i (счётчика цикла), причём, на него отводися два имвола, потом в круглых скобках через запятую поля x и y i-го элемента p, на каждое поле отводится 5 символов, из них два на дробную часть}
    42.           if i mod 4=0 then writeln; {Если i кратно 4, то происходит переход на следующую экранную строку}
    43.      end; {Конец тела цикла}
    44.      t1:=1;{Переменной t1 присваивается 1, что значит, что что то - первая точка}
    45.      for i:=1 to n do {Заголовок цикла со счётчиком, счётчик последовательно принимает значения от 1 до n, а зовут его i, для каждого значения счётчика один раз выполняется тело цикла}
    46.      begin {Начало тела цикла}
    47.           if (p[i].y<p[t1].y) then t1:=i else if (p[i].y=p[t1].y) and (p[i].x<p[t1].x) then t1:=i; {Если поле y i-го элемента p меньше поля y t1-го элемента p, то переменной t1 присвается значение пемеенной i, инае проверяется второе условие, оно здесь составное: поле y в i-том и t1-м элемнтах p имеет одно значение и поле x i-го элемента p меньше поля x t1-го элемента p, если это условие соблюдается, то переменной t1 присваивается значение i строка эквивалентна следующей}
    48.   if ((p[i].y<p[t1].y) or ((p[i].y=p[t1].y) and (p[i].x<p[t1].x))) then t1:=i;
    49.      end; {Конец тела цикла}
    50.      for i:=1 to n do {Заголовок цикла со счётчиком, счётчик последовательно принимает значения от 1 до n, а зовут его i, для каждого значения счётчика один раз выполняется тело цикла, состоящего только из следующей строки}
    51.           used[i]:=false; {i-му элементу used присваивается значение fale}
    52.      writeln; {Переход на следующую экранную строку}
    53.      writeln('Выпуклая оболочка идет через вершины: '); {На экран выводится строка "Выпуклая оболочка идет через вершины: " (зачем то с пробелом на конце), после чего происходит переход на следующую экранную строку}
    54.      t:=t1; {Переменной t присваивается значение переменной t1}
    55.      m:=0; {Переменная m обнуляется}
    56.      repeat {Здесь начинается тело цикла с условием, проверяемым после выполнения тела цикла}
    57.            m:=m+1; {Переменная m увеличивается на 1}
    58.            p1[m].x:=p[t].x; {Полю x m-го элемента p1 присваивается поле x t-го элемента p}
    59.    p1[m].y:=p[t].y; {Полю y m-го элемента p1 присваивается поле y t-го элемента p}
    60.    p1[m].k:=t; {Полю k m-го элемента p1 присваивается значение пеменной t}
    61.            used[t]:=true; {t-му элементу used присваивается значение true}
    62.            newt:=0; {Переменная newt обнуляется}
    63.            {Поиск следующей вершины}
    64.            for i:=1 to n do {Заголовок цикла со счётчиком, вложенного в цикл с условием, счётчик последовательно принимает значения от 1 до n, а зовут его i, для каждого значения счётчика один раз выполняется тело цикла, состоящего только из следующей строки}
    65.                if i<>t then if (newt=0) or (IsLeft(p[t], p[i], p[newt])) then newt:=i; {Если i не равно t, то проверяется второе условие, оно здесь составное: newt равно 0, или IsLeft(p[t], p[i], p[newt]) возвращает true, если соблюдается хотябы одно из условий, входящийх в составное условие, то оно целиком соблюдается и переменной newt присваивается значение переменной i}
    66.            t:=newt; {Переменной t присваивается значение переменной newt}
    67.      until t=t1; {Конец тела цикла, оно будет выполнено в том и только в том случае, если t не равно t1}
    68.      assign(z,'D:\Koordinati.txt'); {Переменная z связывается с файлом D:\Koordinati.txt}
    69.      rewrite(z); {Позиция записи в переменной z, а значит и в файле D:\Koordinati.txt устанавливается на начало, переменная z, а значит файл D:\Koordinati.txt очищаются, но без разрыва связи между ними}
    70.      write(z,'Вершины многоугольника:'); {В переменную z, а значит и в файл D:\Koordinati.txt выводися строка "Вершины многоугольника:"}
    71.      for i:=1 to m do {Заголовок цикла со счётчиком, счётчик последовательно принимает значения от 1 до m, а зовут его i, для каждого значения счётчика один раз выполняется тело цикла, состоящего только из следующей строки}
    72.          write(z,'P[',p1[i].k:2,'](',p1[i].x:5:2,';',p1[i].y:5:2,') '); {В переменную z, значит и в файл D:\Koordinati.txt выводится сначала буква P, потом в квадратных скобках значение поля k i-го элемента p1, при этом на него отводится два символа, потом в крулых скобках через запятую поля x и y i-го элемента p1, при этом на них отвоится по 5 символов, из них 2 на дробную часть}
    73.      if i mod 4=0 then writeln; {Если i кратно 4, то зачем то происходит переход на следующую экранную строку}
    74.      m:=m+1; {m увеличивается на 1}
    75.      p1[m].x:=p1[1].x; {Поле x 1-го элемента p1 присваивается полю x m-того элемента p1}
    76. p1[m].y:=p1[1].y; {Поле y 1-го элемента p1 присваивается полю y m-того элемента p1}
    77.      close(z); {Разрвывется связь переменной z и файла D:\Koordinati.txt, больше с этим файлом ничего делаться не будет}
    78.      for i:=1 to m do {Заголовок цикла со счётчиком, счётчик последовательно принимает значения от 1 до m, а зовут его снова i, для каждого значения счётчика один раз выполняется тело цикла, состоящего только из следующей строки}
    79.          write('P[',p1[i].k:2,'](',p1[i].x:5:2,';',p1[i].y:5:2,') '); {На экран выводися сначала буква p, потом в квадратных скобках значение поля k i-го элемета p1, на которое отводится два символа, потом в круглых скобках через запятую поля x и y i-го элемента p1, на них отводится по 5 символов, из них 2 на дробную часть}
    80.      if i mod 4=0 then writeln; {Если i кратно 4, то происходит переход на следующую экранную строку}
    81.      m:=m+1; {m увеличивается на 1}
    82.      p1[m].x:=p1[1].x; {Полю x m-го элемента p1 присваивается значение поля x 1-го элемента p1}
    83. p1[m].y:=p1[1].y; {Полю y m-го элемента p1 присваивается значение поля y 1-го элемента p1, таким образом программа пытается замкнуть оболочку}
    84.      writeln; {Переход на следующую экранную строку}
    85.      write('Нажмите Enter для проверки результата графически'); {На экран выводися стока "Нажмите Enter для проверки результата графически"}
    86.      readln; {Ожидание нажатия enter и зачем то переход на следующую экранную стоку}
    87.      clearwindow; {Видимо очистка экрана}
    88.      setwindowsize(1200, 1100); {Видимо задаются размеры вьюпорта}
    89.      x0:=windowwidth div 2; {Переменной x0 присваивается округлённая вниз до целого половина windowwidth}
    90.      y0:=windowheight div 2; {Переменной y0 присваивается округлённая вниз до целого половина windowheight}
    91.      ms:=(y0-20)/10; {Переменной ms присваивается значение (y0-20)/10}
    92.      line(x0-y0-1000, y0, x0+y0+1000, y0); {Видимо строистчя линия из точки с абсциссой x0-y0-1000 и ординатой y0 до точки с абсциссой x0+y0+1000 и ординатой y0}
    93.      textout(x0+y0+250, y0-17, 'X'); {Видимо выводися буква X возле точки с абсциссой x0+y0+250 и ординатой y0-17}
    94.      line(x0, -1000, x0, windowheight+1000); {Видимо строистчя линия из точки с абсциссой x0 и ординатой -1000 до точки с абсциссой x0 и ординатой windowheight+1000}
    95.      textout(x0+5, 10, 'Y'); {Видимо выводися буква Y возле точки с абсциссой x0+5 и ординатой 10}
    96.      textout(x0+5, y0+10,'0'); {Видимо выводися цифра 0 возле точки с абсциссой x0+5 и ординатой y0+10}
    97.      for i:=1 to 100 do {Заголовок цикла со счётчиком, счётчик, который зовут i, последовательно принимает значения от 1 до 100, для каждого значения один раз выполняется тело цикла}
    98.      begin {Начало тела цикла}
    99.           line(x0-3, y0-round(i*ms), x0+3, y0-round(i*ms));{Видимо проводится линия от точки с абсциссой x0-3 и ординатой y0-i*ms до точки с абсциссой x0+3 и той же ординатой, сказано, что эти линии - засечки на оси У}
    100.           line(x0-3, y0+round(i*ms), x0+3, y0+round(i*ms)); {Видимо проводится линия от точки с абсциссой x0-3 и ординатой y0+i*ms до точки с абсциссой x0+3 и той же ординатой}   
    101.           line(x0+round(i*ms), y0-3, x0+round(i*ms), Y0+3); {Видимо проводится линия от точки с абсциссой x0+i*ms и ординатой y0-3 до точки с той же абсциссой и ординатой y0+3, сказано, что эти линии - засечки на оси Х}
    102.           line(x0-round(i*ms), y0-3, x0-round(i*ms), Y0+3); {Видимо проводится линия от точки с абсциссой x0-i*ms и ординатой y0-3 до точки с той же абсциссой и ординатой y0+3}
    103.           {подпись оси У}
    104.           textout(x0-20, y0-round(i*ms), inttostr(i));{Видимо выводится на экран в графическом режиме возле точки с абсциссой x0-20 и ординатой y0-i*ms значение i, сказано, что соответственно засечкам}
    105.           textout(x0-30, y0+round(i*ms), inttostr(-i)); {Видимо выводится на экран в графическом режиме возле точки с абсциссой x0-30 и ординатой y0+i*ms значение -i}
    106.           {подпись оси Х}
    107.           textout(x0+round(i*ms), y0+10, inttostr(i)); {Видимо выводится на экран в графическом режиме возле точки с абсциссой x0+i*ms и ординатой y0+10 значение i}
    108.           textout(x0-round(i*ms), y0+10, inttostr(-i)); {Видимо выводится на экран в графическом режиме возле точки с абсциссой x0-i*ms и ординатой y0+10 значение -i}
    109.      end; {Конец тела цикла}
    110.      setpencolor(clBlue); {Видимо после этого построения на экране будут выполняться синим}
    111.      moveto(x0+round(p1[1].x*ms), y0-round(p1[1].y*ms)); {Видимо в точку с абсциссой x0+p1[1].x*ms и ординатой y0-p1[1].y*ms перемещается перо, p1[1].x - поле x 1-го элемента p1, p1[1].y - поле y 1-го элемента p1}
    112.      for i:=1 to m do {Заголовок тела цикла со счётчиком, счётчик, который зовут i последовательно принимает значения от 1 до m, для каждого значения один раз выполняется тело цикла из следующей строки}
    113.          lineto(x0+round(p1[i].x*ms), y0-round(p1[i].y*ms)); {Видимо от положения пера до точки с абсциссой x0+p1[i].x*ms и ординатой y0-p1[i].y*ms проводится линия и в эту же точку перемещается перо, p1[i].x - поле x i-го элемента p1, p1[i].y - поле y i-го элемента p1}
    114.      setpencolor(clRed); {Видимо теперь построения будут выполняться красным}
    115.      setfontcolor(clRed); {Видимо и вывод текста в графическом режиме теперь тоже будет выполняться красным}
    116.      for i:=1 to n do {Заголовок тела цикла со счётчиком, счётчик, который зовут i последовательно принимает значения от 1 до n, для каждого значения один раз выполняется тело цикла}
    117.      begin {Начало тела цикла}
    118.           circle(x0+round(p[i].x*ms), y0-round(p[i].y*ms), 2); {Видимо строится окружность радиусом 2 с центром в точке с абсциссой x0+p[i].x*ms и ординатой y0-p[i].y*ms, p[i].x - поле x i-го элемента p, p[i].y - поле y i-го элемента p}
    119.           textout(x0+round(p[i].x*ms)+5, y0-round(p[i].y*ms), inttostr(i)); {Видимо вывод на экран в графическом режиме значения i возле точки с абсциссой x0+p[i].x*ms и ординатой y0-p[i].y}
    120.      end; {Конец тела цикла}
    121. end. {Конец раздела операций программы, а значит и конец программы}


    А вообще привыкай выделять в begin/end каждое тело цикла со счётчиком, тогда читать будет легче. Ну и язык учи. Тогда можно будет читать исходники без комментариев, кроме относящихся сразу к большим кускам текста.
    Последний раз редактировалось >Quiet Snow<; 14.12.2016 в 18:39. Причина: Объединение сообщений.
    Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на си.
    Ответить с цитированием  
     

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Не работает тег SQL
    от The trick в разделе Архив
    Ответов: 6
    Последнее сообщение: 24.12.2014, 18:45
  2. Ответов: 1
    Последнее сообщение: 04.03.2014, 04:46
  3. Ответов: 0
    Последнее сообщение: 03.03.2014, 23:06
  4. Программа не верно работает
    от Smoke Veka в разделе C/C++
    Ответов: 0
    Последнее сообщение: 23.03.2013, 14:03
  5. программа работает, но есть вопрос
    от чес в разделе Turbo Pascal
    Ответов: 9
    Последнее сообщение: 15.04.2011, 20:25
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •