DarkDevourer

Курсовая работа - финальная версия

Dec 24th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.03 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. #include <math.h>
  4. #include <string>
  5. #include <fstream>
  6. #include <GL/freeglut.h>
  7. #include <windows.h>
  8. #include <ctime>
  9.  
  10. using namespace std;
  11.  
  12. void From_String_To_Double(int *flag, string &x, int *k, double *X, int *N); //Подпрограмма для получения элементов массива X[k] из строки x
  13.  
  14. void Creating_Arrays_H_and_Xobr(double *X, double *H, double *Xobr, int *N, double pi); //Подпрограмма создания массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
  15.  
  16. double cas(double x) {return (sin(x) + cos(x));}
  17.  
  18. void Printing_Arrays_into_Files(double *X, double *H, double *Xobr, int *N); //Подпрограмма, записывающая массивы X[k], H[u] и X(обратное)[k] в файл
  19.  
  20. void Graphics_Creation1(); //Подпрограмма, создающая графики массивов X[k], и X(обратное)[k]
  21.  
  22. void Graphics_Creation2(); //Подпрограмма, создающая графики массивов X[k], и X(обратное)[k]
  23.  
  24. void PrintText(float x, float y, int r, int g, int b, string string); //Подпрограмма, показывающая текст на экране (для расположения координат и названий осей графиков)
  25.  
  26. void reshape(int w, int h);
  27.  
  28. void ScreenShot1(int W, int Hz); //Подпрограмма, сохраняющая графики X[k] и X(обратное)[k] функции в bmp-файл
  29.  
  30. void ScreenShot2(int W, int H); //Подпрограмма, сохраняющая частотный график функции H[u] в bmp-файл
  31.  
  32. double *X, *H, *Xobr; //Указатели на будущие динамические массивы
  33. int N; //Размерность массива
  34.  
  35. int w, h; //w - ширина будущего окна с графиками, h - его высота
  36.  
  37. string changer; //Строка для рисования числа-масштаба на экран. Нужна для того, чтобы убрать 0 после ",", если дробная часть равна 0 или бесконечно мала
  38.  
  39. int main(int argc, char * argv[])
  40. {
  41. double const pi = 4 * atan(1);
  42.  
  43. ifstream in;
  44. setlocale(LC_ALL, "RUSSIAN");
  45. string key, key1, N1, x, temps, w1, h1;
  46. int k, flag;
  47. int i;
  48. double start, graph1, graph2;
  49.  
  50. cout << "Программа для преобразования массива X[k] в массив H[u] по формуле дискретного преобразования Хартли и массива Xобр[k] по формуле обратного преобразования Хартли" << endl;
  51. while (1)
  52. {
  53. cout << "Выберите режим работы программы:\n1 - создание фиксированного массива.\n2 - создание массива на основе файла.\n0 - выход из программы.\nПримечание: название файла: \"C:\\test\\KursovayaInput.txt\"" << endl << "Выбрано ";
  54. getline(cin, key);
  55.  
  56. if (key == "1")
  57. {
  58. start = clock();
  59. flag = 0;
  60. k = 0;
  61. N = 40;
  62.  
  63. X = new double[N]; //Создание динамических массивов (эта и две след. строки)
  64. Xobr = new double[N];
  65. H = new double[N];
  66.  
  67. if (!X || !H || !Xobr) //Проверка, выделилиась ли память
  68. {
  69. cout << "Не удалось выделить память под массивы." << endl;
  70. continue;
  71. }
  72.  
  73. for (k = 0; k < 40; k++)
  74. {
  75. X[k] = 50 * sin(2*pi*k/40);
  76. }
  77.  
  78. Creating_Arrays_H_and_Xobr(X, H, Xobr, &N, pi); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
  79.  
  80. Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
  81.  
  82. w = 1900;
  83. h = 1000; //Создание окна размером 1900x1000
  84.  
  85. //Создание окна для рисования графиков X[k] и X(обратное)[k]
  86.  
  87. glutInit(&argc, argv);
  88. glutInitDisplayMode(GLUT_DOUBLE);
  89. glutInitWindowPosition(0, 0);
  90. glutInitWindowSize(w, h);
  91. glutCreateWindow("Графики массивов");
  92.  
  93. glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
  94. GLUT_ACTION_GLUTMAINLOOP_RETURNS);
  95.  
  96. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  97.  
  98. glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
  99.  
  100. glutDisplayFunc(Graphics_Creation1); //Подпрограмма, рисующая графики массивов X[k] и X(обратное)[k]
  101.  
  102. graph1 = clock();
  103.  
  104. glutMainLoop();
  105.  
  106. graph1 = clock() - graph1; //Время существования 1 окна
  107.  
  108. //Создание окна для рисования частотного графика H[u]
  109. glutInit(&argc, argv);
  110. glutInitDisplayMode(GLUT_DOUBLE);
  111. glutInitWindowPosition(0, 0);
  112. glutInitWindowSize(w, h);
  113. glutCreateWindow("Графики массивов");
  114.  
  115. glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
  116. GLUT_ACTION_GLUTMAINLOOP_RETURNS);
  117.  
  118. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  119.  
  120. glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
  121.  
  122. glutDisplayFunc(Graphics_Creation2); //Подпрограмма, рисующая график массива H[u]
  123.  
  124. graph2 = clock();
  125.  
  126. glutMainLoop();
  127.  
  128. graph2 = clock() - graph2; //Время существования 2 окна
  129. //cin.ignore();
  130.  
  131.  
  132. delete[] X;//Очистка памяти от динамических массивов (эта и дву след. строки)
  133. delete[] H;
  134. delete[] Xobr;
  135.  
  136. cout << "Время выполнения алгоритма: " << clock() - graph2 - graph1 - start << endl;
  137.  
  138. }
  139.  
  140. else if (key == "2")
  141. {
  142. start = clock();
  143.  
  144. flag = 0; //Флаг для проверки правильности ввода
  145. k = 0;
  146. N1 = "";
  147.  
  148. in.open("C:\\test\\KursovayaInput.txt"); //Открытие файла
  149. if (!in.is_open()) //Проверка, открылся файл или нет
  150. {
  151. cout << "Файл открыть не удалось. Пожалуйста, проверьте, правильно ли введено имя файла и его наличие.\nИмя файла по умолчанию - C:\\test\\KursovayaInput.txt" << endl;
  152. cin.ignore();
  153. continue;
  154. }
  155. if (in.eof())
  156. {
  157. cout << "Файл пустой. Пожалуйста, заполните его.\nАдрес файла: C:\\test\\KursovayaInput.txt\n";
  158. in.close();
  159. cin.ignore();
  160. continue;
  161. }
  162.  
  163. getline(in, x); //Чтение строки из файла
  164. if (x.find(" ") < x.find("\t") || x.find("\t") == -1) //Берем все символы до первого пробельного символа
  165. {
  166. N1.insert(0, x, 0, x.find(" "));
  167. }
  168. else
  169. {
  170. N1.insert(0, x, 0, x.find("\t"));
  171. }
  172. size_t number1 = N1.find_first_not_of("0123456789");
  173. if (number1 != std::string::npos) //Если найдено что-то помимо цифр
  174. {
  175. cout << "Не удалось создать массив, так как первая лексема в файле - не число целого типа. Возврат в последнее меню.\n" << endl;
  176. in.close();
  177. cin.ignore();
  178. break;
  179. }
  180. N = stoi(N1.c_str()); //Получения количества элементов массива
  181.  
  182. X = new double[N]; //Создание динамических массивов (эта и две след. строки)
  183. Xobr = new double[N];
  184. H = new double[N];
  185.  
  186. if (!X || !H || !Xobr) //Проверка, выделилась ли память
  187. {
  188. cout << "Не удалось выделить память под массивы." << endl;
  189. continue;
  190. }
  191.  
  192. x.erase(0, N1.length()); //Удаляем в строке число - количество элементов массива
  193. while ((x.find("\t") == 0 || x.find(" ") == 0) && (x.find("\t") != -1 || x.find(" ") != -1)) //Двигаемся в строке до первого непробельного символа при его наличии
  194. {
  195. x.erase(0, 1);
  196. }
  197.  
  198. k = 0;
  199. if (N > 0) //Если количество элементов массива больше 0
  200. {
  201. do
  202. {
  203. while (1)
  204. {
  205. temps = "";
  206. i = 0;
  207.  
  208. while ((x.find(' ') != 0) && (x.find('\t') != 0) && (x.length() != 0)) //Получения из строки числа
  209. {
  210. temps.insert(i, x, 0, 1);
  211. i++;
  212. x.erase(0, 1);
  213. }
  214.  
  215. From_String_To_Double(&flag, temps, &k, X, &N); //Вызов функции, создающей элемент массива X[k] на основе строки
  216.  
  217. while ((x.find('\t') == 0 || x.find(' ') == 0) && (x.find("\t") != -1 || x.find(" ") != -1))
  218. {
  219. x.erase(0, 1);
  220. }
  221.  
  222. if (x.length() == 0 || k == N) //Выход из цикла анализа строки, если дошли до конца строки
  223. {
  224. break;
  225. }
  226.  
  227. }
  228. if (flag == 1 || k == N) //Если в файле не только числа или массив заполнен
  229. {
  230. break;
  231. }
  232. } while (getline(in, x)); //Цикл будт продолжаться, пока строки удачно считываются
  233.  
  234. if (in.bad()) //Если не удалось считать строку из-за ошибки
  235. {
  236. cout << "Произошла ошибка чтения файла." << endl;
  237. in.close();
  238. continue;
  239. }
  240.  
  241. if ((k < N)) //Если в файле оказалось чисел больше или меньше заявленного
  242. {
  243. cout << "В файле количество элементов, который нужно записать в массив X, меньше заявленного количества элементов.\n";
  244. in.close(); //Закрытие файла ввода
  245. continue;
  246. }
  247. else if (flag == 0)
  248. {
  249. Creating_Arrays_H_and_Xobr(X, H, Xobr, &N, pi); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
  250. }
  251. }
  252.  
  253. in.close(); //Закрытие файла ввода
  254.  
  255. Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
  256.  
  257. w = 1900;
  258. h = 1000; //Создание окна размером 1900x1000
  259.  
  260. //Создание окна для рисования графиков
  261. glutInit(&argc, argv);
  262. glutInitDisplayMode(GLUT_DOUBLE);
  263. glutInitWindowPosition(0, 0);
  264. glutInitWindowSize(w, h);
  265. glutCreateWindow("Графики массивов");
  266.  
  267. glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
  268. GLUT_ACTION_GLUTMAINLOOP_RETURNS);
  269.  
  270. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  271.  
  272. glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
  273.  
  274. glutDisplayFunc(Graphics_Creation1); //Подпрограмма, рисующая графики массивов X[k] и X(обратное)[k]
  275.  
  276. graph1 = clock();
  277.  
  278. glutMainLoop();
  279.  
  280. graph1 = clock() - graph1; //Время существования 1 окна
  281.  
  282. //Создание окна для рисования частотного графика H[u]
  283. glutInit(&argc, argv);
  284. glutInitDisplayMode(GLUT_DOUBLE);
  285. glutInitWindowPosition(0, 0);
  286. glutInitWindowSize(w, h);
  287. glutCreateWindow("Графики массивов");
  288.  
  289. glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
  290. GLUT_ACTION_GLUTMAINLOOP_RETURNS);
  291.  
  292. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
  293.  
  294. glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
  295.  
  296. glutDisplayFunc(Graphics_Creation2); //Подпрограмма, рисующая график массива H[u]
  297.  
  298. graph2 = clock();
  299.  
  300. glutMainLoop();
  301.  
  302. graph2 = clock() - graph2;
  303.  
  304. //cin.ignore(); - нужна только если размеры окна вводятся с клавиатуры
  305.  
  306. delete[] X;//Очистка памяти от динамических массивов (эта и две след. строки)
  307. delete[] H;
  308. delete[] Xobr;
  309.  
  310. cout << "Время выполнения алгоритма: " << clock() - graph2 - graph1 - start << endl;
  311. }
  312.  
  313. else if (key == "0")
  314. {
  315. cout << "Завершение работы программы." << endl;
  316. return 0;
  317. }
  318.  
  319. else
  320. {
  321. cout << "Такой команды не существует в данной программе. Возврат в меню." << endl;
  322. }
  323. }
  324. }
  325.  
  326. void From_String_To_Double(int *flag, string &x, int *k, double *X, int *N)
  327. {
  328. size_t number2 = x.find_first_not_of("-,.0123456789");
  329. size_t symbols = x.find_first_not_of("-,.");
  330. size_t point = x.find_first_not_of(".");
  331. if ((number2 != std::string::npos) || (symbols == std::string::npos) || (x.find(".") != x.rfind(".")))
  332. {
  333. cout << "Ошибка. Наличие постороннего символа (написано не число). Возврат в меню." << endl;
  334. *flag = 1;
  335. return;
  336. }
  337.  
  338. while (x.find(".") != -1)
  339. {
  340. x.replace(x.find("."), 1, ",");
  341. }
  342.  
  343. X[*k] = stod(x.c_str());
  344.  
  345. *k += 1;
  346. }
  347.  
  348. void Creating_Arrays_H_and_Xobr(double *X, double *H, double *Xobr, int *N, double pi) //Подпрограмма создания массивов H из массива X и массива X [обратное] из массива H
  349. {
  350. int k, u;
  351.  
  352. for (k = 0; k < *N; k++)
  353. cout << "X[" << k << "] = " << X[k] << "\n";
  354.  
  355. for (u = 0; u < *N; u++) // Заполнение массива H[u] по формуле дискретного преобразования Хартли
  356. {
  357. H[u] = 0;
  358. for (k = 0; k < *N; k++)
  359. {
  360. H[u] = H[u] + X[k] * (cas(2 * pi*k*u / *N) );
  361. }
  362. H[u] = H[u] / sqrt(*N);
  363. cout << "H[" << u << "] = " << H[u] << "\n";
  364. }
  365.  
  366. for (k = 0; k < *N; k++) // Заполнение массива X обратный [k]
  367. {
  368. Xobr[k] = 0;
  369. for (u = 0; u < *N; u++)
  370. {
  371. Xobr[k] = Xobr[k] + H[u] * (cas(2 * pi*k*u / *N));
  372. }
  373. Xobr[k] = Xobr[k] / sqrt(*N);
  374. if (fabs(Xobr[k] - X[k]) > 0.00001)
  375. {
  376. cout << "Произошла ошибка в вычислениях.\n";
  377. break;
  378. }
  379. printf("Xobr[%d] = %19.15f\n",k ,Xobr[k]);
  380.  
  381. printf("X[%d]-Xobr[%d] = %19.15f\n", k, k, X[k]-Xobr[k]);
  382. }
  383. }
  384.  
  385. void Printing_Arrays_into_Files(double *X, double *H, double *Xobr, int *N) //Подпрограмма, записывающая массивы X[k], H[u] и X(обратное)[k] в файл
  386. {
  387. int k;
  388. std::ofstream out;
  389. out.open("C:\\test\\KursovayaOutput.txt"); //Открытие файла вывода
  390. if (!out.is_open()) //Если файл не открылся
  391. {
  392. cout << "Файл для записи массивов: C:\\test\\KursovayaOutput.txt - открыть не удалось." << endl;
  393. return;
  394. }
  395. out << "Изначальный массив X[k]:" << endl;
  396. for (k = 0; k < *N; k++) //Запись массива X[k]
  397. {
  398. out << "X[" << k << "] = " << X[k] << endl;
  399. }
  400. out << endl << "Массив, полученный после дискретного преобразования Хартли, H[u]:" << endl;
  401. for (k = 0; k < *N; k++) //Запись массива H[u]
  402. {
  403. out << "H[" << k << "] = " << H[k] << endl;
  404. }
  405. out << endl << "Массив, полученный после обратного дискретного преобразования Хартли, X(обратный)[k]:" << endl;
  406. for (k = 0; k < *N; k++) //Запись массива X(обратное)[k]
  407. {
  408. out << "X(обратный)[" << k << "] = " << X[k] << endl;
  409. }
  410. out.close(); //Закрытие файла вывода
  411. }
  412.  
  413.  
  414. void Graphics_Creation1() //Подпрограмма, создающая графики массивов X[k] и X(обратное)[k]
  415. {
  416. int length_x = w - 15; //Длина каждого графика по оси x
  417. int length_y = floor((h - 90) / 2);
  418. double y_max[2], y_min[2], length;
  419. int k, i, y[2];
  420. double mast_y[2];
  421. double mast_x = floor(w - 15 / N);
  422. glClear(GL_COLOR_BUFFER_BIT);
  423.  
  424. //Создание вертикальных и горизонтальных осей двух графиков
  425.  
  426. for (k = 1; k <= 2; k++)
  427. {
  428. glBegin(GL_LINES); //Построение вертикальной оси
  429. glColor3f(0.0, 0.0, 0.0);
  430. glVertex2i(5, h - 30 * k - length_y * (k - 1));
  431. glColor3f(0.0, 0.0, 0.0);
  432. glVertex2i(5, h - 30 * k - length_y * k);
  433. glEnd();
  434.  
  435. glBegin(GL_LINES); //Черчение стрелки
  436. glColor3f(0.0, 0.0, 0.0);
  437. glVertex2i(5, h - 30 * k - length_y * (k - 1));
  438. glColor3f(0.0, 0.0, 0.0);
  439. glVertex2i(0, h - 30 * k - length_y * (k - 1) - 10);
  440. glEnd();
  441. glBegin(GL_LINES);
  442. glColor3f(0.0, 0.0, 0.0);
  443. glVertex2i(5, h - 30 * k - length_y * (k - 1));
  444. glColor3f(0.0, 0.0, 0.0);
  445. glVertex2i(10, h - 30 * k - length_y * (k - 1) - 10);
  446. glEnd();
  447.  
  448. y_max[k-1] = 200;
  449. y_min[k-1] = -200;
  450.  
  451. if (k == 1) //Находим наибольший и наименьший элементы X[k]
  452. {
  453.  
  454. for (i = 1; i < N; i++)
  455. {
  456. if (y_max[0] < X[i])
  457. {
  458. y_max[0] = X[i];
  459. }
  460. else if (y_min[0] > X[i])
  461. {
  462. y_min[0] = X[i];
  463. }
  464. }
  465. }
  466. if (k == 2) //Находим наибольший и наименьший элементы X(обратный)[k]
  467. {
  468. for (i = 1; i < N; i++)
  469. {
  470. if (y_max[1] < Xobr[i])
  471. {
  472. y_max[1] = Xobr[i];
  473. }
  474. else if (y_min[1] > Xobr[i])
  475. {
  476. y_min[1] = Xobr[i];
  477. }
  478. }
  479. }
  480.  
  481. //Построение горизонтальной оси
  482. length = y_max[k - 1] - y_min[k - 1];
  483. mast_y[k - 1] = length_y / length; //Масштаб оси ординат по кол-ву точек
  484. y[k - 1] = h - 30 * k - length_y * (k - 1) - length_y * y_max[k - 1] / length;
  485. glBegin(GL_LINES);
  486. glColor3f(0.0, 0.0, 0.0);
  487. glVertex2i(5, y[k - 1]);
  488. glColor3f(0.0, 0.0, 0.0);
  489. glVertex2i(w, y[k - 1]);
  490. glEnd();
  491.  
  492. glBegin(GL_LINES); //Черчение стрелки
  493. glColor3f(0.0, 0.0, 0.0);
  494. glVertex2i(w, y[k - 1]);
  495. glColor3f(0.0, 0.0, 0.0);
  496. glVertex2i(w - 10, y[k - 1] - 5);
  497. glEnd();
  498. glBegin(GL_LINES);
  499. glColor3f(0.0, 0.0, 0.0);
  500. glVertex2i(w, y[k - 1]);
  501. glColor3f(0.0, 0.0, 0.0);
  502. glVertex2i(w - 10, y[k - 1] + 5);
  503. glEnd();
  504. }
  505.  
  506. //Подписывание осей графиков
  507. PrintText(15, h - 30, 0, 0, 0, "X[k]");
  508. PrintText(w - 10, y[0] - 15, 0, 0, 0, "k");
  509. PrintText(15, h - 60 - length_y, 0, 0, 0, "X(obr)[k]");
  510. PrintText(w - 10, y[1] - 15, 0, 0, 0, "k");
  511.  
  512. //Построение штрихов на горизонтальной оси
  513. for (k = 0; k < N; k++)
  514. {
  515. for (i = 0; i <= 1; i++)
  516. {
  517. glBegin(GL_LINES); //X[k]
  518. glColor3f(0.0, 0.0, 0.0);
  519. glVertex2i(5 + mast_x * k / N, y[i] + 5);
  520. glColor3f(0.0, 0.0, 0.0);
  521. glVertex2i(5 + mast_x * k / N, y[i] - 5);
  522. glEnd();
  523. PrintText(5 + mast_x * k / N, y[i] - 17, 0, 0, 0, to_string(k));
  524. }
  525. }
  526.  
  527. //Построение штрихов на вертикальной оси
  528. //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
  529. //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
  530. for (k = 1; k <= 19; k++)
  531. {
  532. for (int j = 0; j <= 1; j++)
  533. {
  534. if (y[j] - k * length_y / 20 >= h - 30 *(j+1) - (j+1)*length_y)
  535. {
  536. glBegin(GL_LINES); //X[k]
  537. glColor3f(0.0, 0.0, 0.0);
  538. glVertex2i(0, y[j] - k * length_y / 20);
  539. glColor3f(0.0, 0.0, 0.0);
  540. glVertex2i(10, y[j] - k * length_y / 20);
  541. glEnd();
  542. changer = to_string(-(y_max[0] - y_min[0]) / 20 * k);
  543. if (-(y_max[j] - y_min[j]) / 20 * k + floor(-(y_max[j] - y_min[j]) / 20 * k) <= 0.000001)
  544. {
  545. changer.erase(changer.find(","), changer.length() - changer.find(","));
  546. }
  547. if (k != 0)
  548. {
  549. PrintText(15, y[j] - k * length_y / 20 - 5, 0, 0, 0, changer);
  550. }
  551. }
  552. else
  553. {
  554. glBegin(GL_LINES); //X[k]
  555. glColor3f(0.0, 0.0, 0.0);
  556. glVertex2i(0, y[j] + (20 - k) * length_y / 20);
  557. glColor3f(0.0, 0.0, 0.0);
  558. glVertex2i(10, y[j] + (20 - k) * length_y / 20);
  559. glEnd();
  560. changer = to_string((y_max[j] - y_min[j]) / 20 * (20 - k));
  561. if ((y_max - y_min) / 20 * (20 - k) - floor((y_max - y_min) / 20 * (20 - k)) <= 0.000001)
  562. {
  563. changer.erase(changer.find(","), changer.length() - changer.find(","));
  564. }
  565. PrintText(15, y[j] + (20 - k) * length_y / 20 - 5, 0, 0, 0, changer);
  566. }
  567. }
  568. }
  569.  
  570. //Построение графиков
  571.  
  572. for (k = 0; k < N; k++)
  573. {
  574. if (k != N - 1)
  575. {
  576. glBegin(GL_LINES); //X[k]
  577. glColor3f(0.0, 0.0, 0.0);
  578. glVertex2i(5 + k * mast_x / N, y[0] + X[k] * mast_y[0]);
  579. glColor3f(0.0, 0.0, 0.0);
  580. glVertex2i(5 + (k + 1) * mast_x / N, y[0] + X[k + 1] * mast_y[0]);
  581. glEnd();
  582.  
  583. glBegin(GL_LINES); //X(обратный)[k]
  584. glColor3f(0.0, 0.0, 0.0);
  585. glVertex2i(5 + k * mast_x / N, y[1] + Xobr[k] * mast_y[1]);
  586. glColor3f(0.0, 0.0, 0.0);
  587. glVertex2i(5 + (k + 1) * mast_x / N, y[1] + Xobr[k + 1] * mast_y[1]);
  588. glEnd();
  589. }
  590.  
  591. glPointSize(5);
  592.  
  593. glBegin(GL_POINTS); //X[k] - выделение точек
  594. glColor3f(0.0, 0.0, 0.0);
  595. glVertex2i(5 + mast_x * k / N, y[0] + X[k] * mast_y[0]);
  596. glEnd();
  597.  
  598. glBegin(GL_POINTS); //X(обратный)[k] - выделение точек
  599. glColor3f(0.0, 0.0, 0.0);
  600. glVertex2i(5 + mast_x * k / N, y[1] + Xobr[k] * mast_y[1]);
  601. glEnd();
  602.  
  603. }
  604.  
  605. ScreenShot1(w, h);
  606. glutSwapBuffers();
  607. }
  608.  
  609. //Подпрограмма, рисующая частотный график функции H[u]
  610. void Graphics_Creation2()
  611. {
  612. int length_x = w - 15; //Длина оси x
  613. int length_y = h - 60; //Длина оси y
  614. double y_max, y_min, length;
  615. int u, i, y;
  616. double mast_y;
  617. double mast_x = floor(w - 15 / N);
  618. glClear(GL_COLOR_BUFFER_BIT);
  619.  
  620. //Создание вертикальных и горизонтальных осей графика
  621.  
  622. glBegin(GL_LINES); //Построение вертикальной оси
  623. glColor3f(0.0, 0.0, 0.0);
  624. glVertex2i(5, h - 30);
  625. glColor3f(0.0, 0.0, 0.0);
  626. glVertex2i(5, h - 30 - length_y);
  627. glEnd();
  628.  
  629. glBegin(GL_LINES); //Черчение стрелки
  630. glColor3f(0.0, 0.0, 0.0);
  631. glVertex2i(5, h - 30);
  632. glColor3f(0.0, 0.0, 0.0);
  633. glVertex2i(0, h - 40);
  634. glEnd();
  635. glBegin(GL_LINES);
  636. glColor3f(0.0, 0.0, 0.0);
  637. glVertex2i(5, h - 30);
  638. glColor3f(0.0, 0.0, 0.0);
  639. glVertex2i(10, h - 40);
  640. glEnd();
  641.  
  642. y_max = 200;
  643. y_min = -200;
  644. for (i = 1; i < N; i++)
  645. {
  646. if (y_max < H[i])
  647. {
  648. y_max = H[i];
  649. }
  650. else if (y_min > H[i])
  651. {
  652. y_min = H[i];
  653. }
  654. }
  655. //Построение горизонтальной оси
  656. length = y_max - y_min;
  657. mast_y = length_y / length; //Масштаб оси ординат по кол-ву точек
  658. y = h - 30 - length_y * y_max / length;
  659.  
  660. glBegin(GL_LINES);
  661. glColor3f(0.0, 0.0, 0.0);
  662. glVertex2i(5, y);
  663. glColor3f(0.0, 0.0, 0.0);
  664. glVertex2i(w, y);
  665. glEnd();
  666.  
  667. glBegin(GL_LINES); //Черчение стрелки
  668. glColor3f(0.0, 0.0, 0.0);
  669. glVertex2i(w, y);
  670. glColor3f(0.0, 0.0, 0.0);
  671. glVertex2i(w - 10, y - 5);
  672. glEnd();
  673. glBegin(GL_LINES);
  674. glColor3f(0.0, 0.0, 0.0);
  675. glVertex2i(w, y);
  676. glColor3f(0.0, 0.0, 0.0);
  677. glVertex2i(w - 10, y + 5);
  678. glEnd();
  679.  
  680.  
  681. //Подписывание осей графиков
  682. PrintText(15, h - 30, 0, 0, 0, "H[u]");
  683. PrintText(w - 10, y - 15, 0, 0, 0, "u");
  684.  
  685. //Построение штрихов на горизонтальной оси
  686. for (u = 0; u < N; u++)
  687. {
  688. glBegin(GL_LINES); //X[k]
  689. glColor3f(0.0, 0.0, 0.0);
  690. glVertex2i(5 + mast_x * u / N, y + 5);
  691. glColor3f(0.0, 0.0, 0.0);
  692. glVertex2i(5 + mast_x * u / N, y - 5);
  693. glEnd();
  694. PrintText(5 + mast_x * u / N, y - 17, 0, 0, 0, to_string(u));
  695.  
  696. glBegin(GL_LINES); //X(обратный)[k]
  697. glColor3f(0.0, 0.0, 0.0);
  698. glVertex2i(5 + mast_x * u / N, y + 5);
  699. glColor3f(0.0, 0.0, 0.0);
  700. glVertex2i(5 + mast_x * u / N, y - 5);
  701. glEnd();
  702. PrintText(5 + mast_x * u / N, y - 17, 0, 0, 0, to_string(u));
  703. }
  704.  
  705. //Построение штрихов на вертикальной оси
  706. //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
  707. //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
  708. for (u = 1; u <= 19; u++)
  709. {
  710. if (y - u * length_y / 20 >= h - 30 - length_y)
  711. {
  712. glBegin(GL_LINES); //X[k]
  713. glColor3f(0.0, 0.0, 0.0);
  714. glVertex2i(0, y - u * length_y / 20);
  715. glColor3f(0.0, 0.0, 0.0);
  716. glVertex2i(10, y - u * length_y / 20);
  717. glEnd();
  718. if (u != 0)
  719. {
  720. changer = to_string(-(y_max - y_min) / 20 * u);
  721. if (-(y_max - y_min) / 20 * u + floor(-(y_max - y_min) / 20 * u) <= 0.000001)
  722. {
  723. changer.erase(changer.find(","), changer.length()-changer.find(","));
  724. }
  725. PrintText(15, y - u * length_y / 20 - 5, 0, 0, 0, changer);
  726. }
  727. }
  728. else
  729. {
  730. glBegin(GL_LINES); //X[k]
  731. glColor3f(0.0, 0.0, 0.0);
  732. glVertex2i(0, y + (20 - u) * length_y / 20);
  733. glColor3f(0.0, 0.0, 0.0);
  734. glVertex2i(10, y + (20 - u) * length_y / 20);
  735. glEnd();
  736. changer = to_string((y_max - y_min) / 20 * (20 - u));
  737. if ((y_max - y_min) / 20 * (20 - u) - floor((y_max - y_min) / 20 * (20 - u)) <= 0.000001)
  738. {
  739. changer.erase(changer.find(","), changer.length() - changer.find(","));
  740. }
  741. PrintText(15, y + (20 - u) * length_y / 20 - 5, 0, 0, 0, changer);
  742. }
  743. }
  744.  
  745. //Построение графиков
  746.  
  747. for (u = 0; u < N; u++)
  748. {
  749. glBegin(GL_LINES); //H[k]
  750. glColor3f(0.0, 0.0, 0.0);
  751. glVertex2i(5 + u * mast_x / N, y);
  752. glColor3f(0.0, 0.0, 0.0);
  753. glVertex2i(5 + (u) * mast_x / N, y + H[u] * mast_y);
  754. glEnd();
  755.  
  756. glPointSize(5);
  757.  
  758. glBegin(GL_POINTS); //H[k] - выделение точек
  759. glColor3f(0.0, 0.0, 0.0);
  760. glVertex2i(5 + mast_x * u / N, y + H[u] * mast_y);
  761. glEnd();
  762.  
  763. }
  764.  
  765. ScreenShot2(w, h);
  766. glutSwapBuffers();
  767. }
  768.  
  769. //Подпрограмма, показывающая текст на экране (для расположения координат и названий осей графиков)
  770. void PrintText(float x, float y, int r, int g, int b, string string)
  771. {
  772. char *text = new char[string.length()];
  773. glColor3f(r, g, b);
  774. glRasterPos2f(x, y);
  775. for (int i = 0; i < string.length(); i++)
  776. text[i] = string[i];
  777. for (int i = 0; i < string.length(); i++)
  778. {
  779. glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[i]);
  780. x += 2;
  781. }
  782. delete[] text;
  783. }
  784.  
  785.  
  786. void reshape(int w, int h) //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работу программы
  787. {
  788. glViewport(0, 0, w, h);
  789.  
  790. glMatrixMode(GL_PROJECTION);
  791. glLoadIdentity();
  792. gluOrtho2D(0, w, 0, h);
  793.  
  794. glMatrixMode(GL_MODELVIEW);
  795. glLoadIdentity();
  796. }
  797.  
  798. void ScreenShot1(int W, int H)
  799. {
  800. FILE *F = fopen("C:\\test\\Graphs1.bmp", "w");
  801. if (F == NULL)
  802. {
  803. cout << "Файл для записи частотного графика массива H[u] открыть/создать не удалось." << endl;
  804. return;
  805. }
  806.  
  807. const int imSize = W * H * 3;
  808. unsigned char *image = new unsigned char[imSize];
  809.  
  810. if (!image) //Проверка, выделилиась ли память
  811. {
  812. cout << "Не удалось выделить память под массивы." << endl;
  813. return;
  814. }
  815.  
  816. memset(image, 0, imSize);
  817. glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
  818. BITMAPINFO bmi;
  819. unsigned char BMI = sizeof(BITMAPINFOHEADER);
  820. unsigned char BMF = sizeof(BITMAPFILEHEADER);
  821. memset(&bmi, 0, BMI);
  822. bmi.bmiHeader.biSize = BMI;
  823. bmi.bmiHeader.biHeight = H;
  824. bmi.bmiHeader.biWidth = W;
  825. bmi.bmiHeader.biPlanes = 1;
  826. bmi.bmiHeader.biBitCount = 24;
  827. bmi.bmiHeader.biCompression = BI_RGB;
  828. bmi.bmiHeader.biSizeImage = imSize;
  829.  
  830. int nBitsOffset = BMF + BMI;
  831. LONG lImageSize = imSize;
  832. LONG lFileSize = nBitsOffset + lImageSize;
  833. BITMAPFILEHEADER bmfh;
  834. bmfh.bfType = 0x4D42;
  835. bmfh.bfOffBits = nBitsOffset;
  836. bmfh.bfSize = lFileSize;
  837. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  838.  
  839. UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, BMF, F);
  840. UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, BMI, F);
  841. UINT nWrittenDIBDataSize = fwrite(image, 1, imSize, F);
  842. UINT total = nWrittenDIBDataSize + nWrittenInfoHeaderSize + nWrittenFileHeaderSize;
  843. delete[]image;
  844. fclose(F);
  845. }
  846.  
  847. void ScreenShot2(int W, int H)
  848. {
  849. FILE *F = fopen("C:\\test\\Graphs2.bmp", "w");
  850. if (F == NULL)
  851. {
  852. cout << "Файл для записи частотного графика массива H[u] открыть/создать не удалось." << endl;
  853. return;
  854. }
  855.  
  856. const int imSize = W * H * 3;
  857. unsigned char *image = new unsigned char[imSize];
  858.  
  859. if (!image) //Проверка, выделилиась ли память
  860. {
  861. cout << "Не удалось выделить память под массивы." << endl;
  862. return;
  863. }
  864.  
  865. memset(image, 0, imSize);
  866. glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
  867. BITMAPINFO bmi;
  868. unsigned char BMI = sizeof(BITMAPINFOHEADER);
  869. unsigned char BMF = sizeof(BITMAPFILEHEADER);
  870. memset(&bmi, 0, BMI);
  871. bmi.bmiHeader.biSize = BMI;
  872. bmi.bmiHeader.biHeight = H;
  873. bmi.bmiHeader.biWidth = W;
  874. bmi.bmiHeader.biPlanes = 1;
  875. bmi.bmiHeader.biBitCount = 24;
  876. bmi.bmiHeader.biCompression = BI_RGB;
  877. bmi.bmiHeader.biSizeImage = imSize;
  878.  
  879. int nBitsOffset = BMF + BMI;
  880. LONG lImageSize = imSize;
  881. LONG lFileSize = nBitsOffset + lImageSize;
  882. BITMAPFILEHEADER bmfh;
  883. bmfh.bfType = 0x4D42;
  884. bmfh.bfOffBits = nBitsOffset;
  885. bmfh.bfSize = lFileSize;
  886. bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
  887.  
  888. UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, BMF, F);
  889. UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, BMI, F);
  890. UINT nWrittenDIBDataSize = fwrite(image, 1, imSize, F);
  891. UINT total = nWrittenDIBDataSize + nWrittenInfoHeaderSize + nWrittenFileHeaderSize;
  892. delete[]image;
  893. fclose(F);
  894. }
Add Comment
Please, Sign In to add comment