DarkDevourer

Последняя версия курсовой (Экстренное сохранение)

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