DarkDevourer

ЯВУ курсач, 2 графики + сохранение в файл

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