Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <math.h>
- #include <string>
- #include <fstream>
- #include <GL/freeglut.h>
- #include <windows.h>
- #include <ctime>
- using namespace std;
- void From_String_To_Double(int *flag, string &x, int *k, double *X, int *N); //Подпрограмма для получения элементов массива X[k] из строки x
- void Creating_Arrays_H_and_Xobr(double *X, double *H, double *Xobr, int *N, double pi); //Подпрограмма создания массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- double cas(double x) {return (sin(x) + cos(x));}
- void Printing_Arrays_into_Files(double *X, double *H, double *Xobr, int *N); //Подпрограмма, записывающая массивы X[k], H[u] и X(обратное)[k] в файл
- void Graphics_Creation1(); //Подпрограмма, создающая графики массивов X[k], и X(обратное)[k]
- void Graphics_Creation2(); //Подпрограмма, создающая графики массивов X[k], и X(обратное)[k]
- void PrintText(float x, float y, int r, int g, int b, string string); //Подпрограмма, показывающая текст на экране (для расположения координат и названий осей графиков)
- void reshape(int w, int h);
- void ScreenShot1(int W, int Hz); //Подпрограмма, сохраняющая графики X[k] и X(обратное)[k] функции в bmp-файл
- void ScreenShot2(int W, int H); //Подпрограмма, сохраняющая частотный график функции H[u] в bmp-файл
- double *X, *H, *Xobr; //Указатели на будущие динамические массивы
- int N; //Размерность массива
- int w, h; //w - ширина будущего окна с графиками, h - его высота
- string changer; //Строка для рисования числа-масштаба на экран. Нужна для того, чтобы убрать 0 после ",", если дробная часть равна 0 или бесконечно мала
- int main(int argc, char * argv[])
- {
- double const pi = 4 * atan(1);
- ifstream in;
- setlocale(LC_ALL, "RUSSIAN");
- string key, key1, N1, x, temps, w1, h1;
- int k, flag;
- int i;
- double start, graph1, graph2;
- cout << "Программа для преобразования массива X[k] в массив H[u] по формуле дискретного преобразования Хартли и массива Xобр[k] по формуле обратного преобразования Хартли" << endl;
- while (1)
- {
- cout << "Выберите режим работы программы:\n1 - создание фиксированного массива.\n2 - создание массива на основе файла.\n0 - выход из программы.\nПримечание: название файла: \"C:\\test\\KursovayaInput.txt\"" << endl << "Выбрано ";
- getline(cin, key);
- if (key == "1")
- {
- start = clock();
- flag = 0;
- k = 0;
- N = 40;
- X = new double[N]; //Создание динамических массивов (эта и две след. строки)
- Xobr = new double[N];
- H = new double[N];
- if (!X || !H || !Xobr) //Проверка, выделилиась ли память
- {
- cout << "Не удалось выделить память под массивы." << endl;
- continue;
- }
- for (k = 0; k < 40; k++)
- {
- X[k] = 50 * sin(2*pi*k/40);
- }
- Creating_Arrays_H_and_Xobr(X, H, Xobr, &N, pi); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
- w = 1900;
- h = 1000; //Создание окна размером 1900x1000
- //Создание окна для рисования графиков X[k] и X(обратное)[k]
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE);
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(w, h);
- glutCreateWindow("Графики массивов");
- glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
- GLUT_ACTION_GLUTMAINLOOP_RETURNS);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
- glutDisplayFunc(Graphics_Creation1); //Подпрограмма, рисующая графики массивов X[k] и X(обратное)[k]
- graph1 = clock();
- glutMainLoop();
- graph1 = clock() - graph1; //Время существования 1 окна
- //Создание окна для рисования частотного графика H[u]
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE);
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(w, h);
- glutCreateWindow("Графики массивов");
- glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
- GLUT_ACTION_GLUTMAINLOOP_RETURNS);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
- glutDisplayFunc(Graphics_Creation2); //Подпрограмма, рисующая график массива H[u]
- graph2 = clock();
- glutMainLoop();
- graph2 = clock() - graph2; //Время существования 2 окна
- //cin.ignore();
- delete[] X;//Очистка памяти от динамических массивов (эта и дву след. строки)
- delete[] H;
- delete[] Xobr;
- cout << "Время выполнения алгоритма: " << clock() - graph2 - graph1 - start << endl;
- }
- else if (key == "2")
- {
- start = clock();
- flag = 0; //Флаг для проверки правильности ввода
- k = 0;
- N1 = "";
- in.open("C:\\test\\KursovayaInput.txt"); //Открытие файла
- if (!in.is_open()) //Проверка, открылся файл или нет
- {
- cout << "Файл открыть не удалось. Пожалуйста, проверьте, правильно ли введено имя файла и его наличие.\nИмя файла по умолчанию - C:\\test\\KursovayaInput.txt" << endl;
- cin.ignore();
- continue;
- }
- if (in.eof())
- {
- cout << "Файл пустой. Пожалуйста, заполните его.\nАдрес файла: C:\\test\\KursovayaInput.txt\n";
- in.close();
- cin.ignore();
- continue;
- }
- getline(in, x); //Чтение строки из файла
- if (x.find(" ") < x.find("\t") || x.find("\t") == -1) //Берем все символы до первого пробельного символа
- {
- N1.insert(0, x, 0, x.find(" "));
- }
- else
- {
- N1.insert(0, x, 0, x.find("\t"));
- }
- size_t number1 = N1.find_first_not_of("0123456789");
- if (number1 != std::string::npos) //Если найдено что-то помимо цифр
- {
- cout << "Не удалось создать массив, так как первая лексема в файле - не число целого типа. Возврат в последнее меню.\n" << endl;
- in.close();
- cin.ignore();
- break;
- }
- N = stoi(N1.c_str()); //Получения количества элементов массива
- X = new double[N]; //Создание динамических массивов (эта и две след. строки)
- Xobr = new double[N];
- H = new double[N];
- if (!X || !H || !Xobr) //Проверка, выделилась ли память
- {
- cout << "Не удалось выделить память под массивы." << endl;
- continue;
- }
- x.erase(0, N1.length()); //Удаляем в строке число - количество элементов массива
- while ((x.find("\t") == 0 || x.find(" ") == 0) && (x.find("\t") != -1 || x.find(" ") != -1)) //Двигаемся в строке до первого непробельного символа при его наличии
- {
- x.erase(0, 1);
- }
- k = 0;
- if (N > 0) //Если количество элементов массива больше 0
- {
- do
- {
- while (1)
- {
- temps = "";
- i = 0;
- while ((x.find(' ') != 0) && (x.find('\t') != 0) && (x.length() != 0)) //Получения из строки числа
- {
- temps.insert(i, x, 0, 1);
- i++;
- x.erase(0, 1);
- }
- From_String_To_Double(&flag, temps, &k, X, &N); //Вызов функции, создающей элемент массива X[k] на основе строки
- while ((x.find('\t') == 0 || x.find(' ') == 0) && (x.find("\t") != -1 || x.find(" ") != -1))
- {
- x.erase(0, 1);
- }
- if (x.length() == 0 || k == N) //Выход из цикла анализа строки, если дошли до конца строки
- {
- break;
- }
- }
- if (flag == 1 || k == N) //Если в файле не только числа или массив заполнен
- {
- break;
- }
- } while (getline(in, x)); //Цикл будт продолжаться, пока строки удачно считываются
- if (in.bad()) //Если не удалось считать строку из-за ошибки
- {
- cout << "Произошла ошибка чтения файла." << endl;
- in.close();
- continue;
- }
- if ((k < N)) //Если в файле оказалось чисел больше или меньше заявленного
- {
- cout << "В файле количество элементов, который нужно записать в массив X, меньше заявленного количества элементов.\n";
- in.close(); //Закрытие файла ввода
- continue;
- }
- else if (flag == 0)
- {
- Creating_Arrays_H_and_Xobr(X, H, Xobr, &N, pi); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- }
- }
- in.close(); //Закрытие файла ввода
- Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
- w = 1900;
- h = 1000; //Создание окна размером 1900x1000
- //Создание окна для рисования графиков
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE);
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(w, h);
- glutCreateWindow("Графики массивов");
- glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
- GLUT_ACTION_GLUTMAINLOOP_RETURNS);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
- glutDisplayFunc(Graphics_Creation1); //Подпрограмма, рисующая графики массивов X[k] и X(обратное)[k]
- graph1 = clock();
- glutMainLoop();
- graph1 = clock() - graph1; //Время существования 1 окна
- //Создание окна для рисования частотного графика H[u]
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE);
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(w, h);
- glutCreateWindow("Графики массивов");
- glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,
- GLUT_ACTION_GLUTMAINLOOP_RETURNS);
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
- glutReshapeFunc(reshape); //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работцу программы
- glutDisplayFunc(Graphics_Creation2); //Подпрограмма, рисующая график массива H[u]
- graph2 = clock();
- glutMainLoop();
- graph2 = clock() - graph2;
- //cin.ignore(); - нужна только если размеры окна вводятся с клавиатуры
- delete[] X;//Очистка памяти от динамических массивов (эта и две след. строки)
- delete[] H;
- delete[] Xobr;
- cout << "Время выполнения алгоритма: " << clock() - graph2 - graph1 - start << endl;
- }
- else if (key == "0")
- {
- cout << "Завершение работы программы." << endl;
- return 0;
- }
- else
- {
- cout << "Такой команды не существует в данной программе. Возврат в меню." << endl;
- }
- }
- }
- void From_String_To_Double(int *flag, string &x, int *k, double *X, int *N)
- {
- size_t number2 = x.find_first_not_of("-,.0123456789");
- size_t symbols = x.find_first_not_of("-,.");
- size_t point = x.find_first_not_of(".");
- if ((number2 != std::string::npos) || (symbols == std::string::npos) || (x.find(".") != x.rfind(".")))
- {
- cout << "Ошибка. Наличие постороннего символа (написано не число). Возврат в меню." << endl;
- *flag = 1;
- return;
- }
- while (x.find(".") != -1)
- {
- x.replace(x.find("."), 1, ",");
- }
- X[*k] = stod(x.c_str());
- *k += 1;
- }
- void Creating_Arrays_H_and_Xobr(double *X, double *H, double *Xobr, int *N, double pi) //Подпрограмма создания массивов H из массива X и массива X [обратное] из массива H
- {
- int k, u;
- for (k = 0; k < *N; k++)
- cout << "X[" << k << "] = " << X[k] << "\n";
- for (u = 0; u < *N; u++) // Заполнение массива H[u] по формуле дискретного преобразования Хартли
- {
- H[u] = 0;
- for (k = 0; k < *N; k++)
- {
- H[u] = H[u] + X[k] * (cas(2 * pi*k*u / *N) );
- }
- H[u] = H[u] / sqrt(*N);
- cout << "H[" << u << "] = " << H[u] << "\n";
- }
- for (k = 0; k < *N; k++) // Заполнение массива X обратный [k]
- {
- Xobr[k] = 0;
- for (u = 0; u < *N; u++)
- {
- Xobr[k] = Xobr[k] + H[u] * (cas(2 * pi*k*u / *N));
- }
- Xobr[k] = Xobr[k] / sqrt(*N);
- if (fabs(Xobr[k] - X[k]) > 0.00001)
- {
- cout << "Произошла ошибка в вычислениях.\n";
- break;
- }
- printf("Xobr[%d] = %19.15f\n",k ,Xobr[k]);
- printf("X[%d]-Xobr[%d] = %19.15f\n", k, k, X[k]-Xobr[k]);
- }
- }
- void Printing_Arrays_into_Files(double *X, double *H, double *Xobr, int *N) //Подпрограмма, записывающая массивы X[k], H[u] и X(обратное)[k] в файл
- {
- int k;
- std::ofstream out;
- out.open("C:\\test\\KursovayaOutput.txt"); //Открытие файла вывода
- if (!out.is_open()) //Если файл не открылся
- {
- cout << "Файл для записи массивов: C:\\test\\KursovayaOutput.txt - открыть не удалось." << endl;
- return;
- }
- out << "Изначальный массив X[k]:" << endl;
- for (k = 0; k < *N; k++) //Запись массива X[k]
- {
- out << "X[" << k << "] = " << X[k] << endl;
- }
- out << endl << "Массив, полученный после дискретного преобразования Хартли, H[u]:" << endl;
- for (k = 0; k < *N; k++) //Запись массива H[u]
- {
- out << "H[" << k << "] = " << H[k] << endl;
- }
- out << endl << "Массив, полученный после обратного дискретного преобразования Хартли, X(обратный)[k]:" << endl;
- for (k = 0; k < *N; k++) //Запись массива X(обратное)[k]
- {
- out << "X(обратный)[" << k << "] = " << X[k] << endl;
- }
- out.close(); //Закрытие файла вывода
- }
- void Graphics_Creation1() //Подпрограмма, создающая графики массивов X[k] и X(обратное)[k]
- {
- int length_x = w - 15; //Длина каждого графика по оси x
- int length_y = floor((h - 90) / 2);
- double y_max[2], y_min[2], length;
- int k, i, y[2];
- double mast_y[2];
- double mast_x = floor(w - 15 / N);
- glClear(GL_COLOR_BUFFER_BIT);
- //Создание вертикальных и горизонтальных осей двух графиков
- for (k = 1; k <= 2; k++)
- {
- glBegin(GL_LINES); //Построение вертикальной оси
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 * k - length_y * (k - 1));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 * k - length_y * k);
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 * k - length_y * (k - 1));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, h - 30 * k - length_y * (k - 1) - 10);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 * k - length_y * (k - 1));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, h - 30 * k - length_y * (k - 1) - 10);
- glEnd();
- y_max[k-1] = 200;
- y_min[k-1] = -200;
- if (k == 1) //Находим наибольший и наименьший элементы X[k]
- {
- for (i = 1; i < N; i++)
- {
- if (y_max[0] < X[i])
- {
- y_max[0] = X[i];
- }
- else if (y_min[0] > X[i])
- {
- y_min[0] = X[i];
- }
- }
- }
- if (k == 2) //Находим наибольший и наименьший элементы X(обратный)[k]
- {
- for (i = 1; i < N; i++)
- {
- if (y_max[1] < Xobr[i])
- {
- y_max[1] = Xobr[i];
- }
- else if (y_min[1] > Xobr[i])
- {
- y_min[1] = Xobr[i];
- }
- }
- }
- //Построение горизонтальной оси
- length = y_max[k - 1] - y_min[k - 1];
- mast_y[k - 1] = length_y / length; //Масштаб оси ординат по кол-ву точек
- y[k - 1] = h - 30 * k - length_y * (k - 1) - length_y * y_max[k - 1] / length;
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, y[k - 1]);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y[k - 1]);
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y[k - 1]);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, y[k - 1] - 5);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y[k - 1]);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, y[k - 1] + 5);
- glEnd();
- }
- //Подписывание осей графиков
- PrintText(15, h - 30, 0, 0, 0, "X[k]");
- PrintText(w - 10, y[0] - 15, 0, 0, 0, "k");
- PrintText(15, h - 60 - length_y, 0, 0, 0, "X(obr)[k]");
- PrintText(w - 10, y[1] - 15, 0, 0, 0, "k");
- //Построение штрихов на горизонтальной оси
- for (k = 0; k < N; k++)
- {
- for (i = 0; i <= 1; i++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[i] + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[i] - 5);
- glEnd();
- PrintText(5 + mast_x * k / N, y[i] - 17, 0, 0, 0, to_string(k));
- }
- }
- //Построение штрихов на вертикальной оси
- //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
- //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
- for (k = 1; k <= 19; k++)
- {
- for (int j = 0; j <= 1; j++)
- {
- if (y[j] - k * length_y / 20 >= h - 30 *(j+1) - (j+1)*length_y)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[j] - k * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[j] - k * length_y / 20);
- glEnd();
- changer = to_string(-(y_max[0] - y_min[0]) / 20 * k);
- if (-(y_max[j] - y_min[j]) / 20 * k + floor(-(y_max[j] - y_min[j]) / 20 * k) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- if (k != 0)
- {
- PrintText(15, y[j] - k * length_y / 20 - 5, 0, 0, 0, changer);
- }
- }
- else
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[j] + (20 - k) * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[j] + (20 - k) * length_y / 20);
- glEnd();
- changer = to_string((y_max[j] - y_min[j]) / 20 * (20 - k));
- if ((y_max - y_min) / 20 * (20 - k) - floor((y_max - y_min) / 20 * (20 - k)) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- PrintText(15, y[j] + (20 - k) * length_y / 20 - 5, 0, 0, 0, changer);
- }
- }
- }
- //Построение графиков
- for (k = 0; k < N; k++)
- {
- if (k != N - 1)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + k * mast_x / N, y[0] + X[k] * mast_y[0]);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (k + 1) * mast_x / N, y[0] + X[k + 1] * mast_y[0]);
- glEnd();
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + k * mast_x / N, y[1] + Xobr[k] * mast_y[1]);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (k + 1) * mast_x / N, y[1] + Xobr[k + 1] * mast_y[1]);
- glEnd();
- }
- glPointSize(5);
- glBegin(GL_POINTS); //X[k] - выделение точек
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[0] + X[k] * mast_y[0]);
- glEnd();
- glBegin(GL_POINTS); //X(обратный)[k] - выделение точек
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[1] + Xobr[k] * mast_y[1]);
- glEnd();
- }
- ScreenShot1(w, h);
- glutSwapBuffers();
- }
- //Подпрограмма, рисующая частотный график функции H[u]
- void Graphics_Creation2()
- {
- int length_x = w - 15; //Длина оси x
- int length_y = h - 60; //Длина оси y
- double y_max, y_min, length;
- int u, i, y;
- double mast_y;
- double mast_x = floor(w - 15 / N);
- glClear(GL_COLOR_BUFFER_BIT);
- //Создание вертикальных и горизонтальных осей графика
- glBegin(GL_LINES); //Построение вертикальной оси
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 - length_y);
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, h - 40);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, h - 40);
- glEnd();
- y_max = 200;
- y_min = -200;
- for (i = 1; i < N; i++)
- {
- if (y_max < H[i])
- {
- y_max = H[i];
- }
- else if (y_min > H[i])
- {
- y_min = H[i];
- }
- }
- //Построение горизонтальной оси
- length = y_max - y_min;
- mast_y = length_y / length; //Масштаб оси ординат по кол-ву точек
- y = h - 30 - length_y * y_max / length;
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, y);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y);
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, y - 5);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, y);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, y + 5);
- glEnd();
- //Подписывание осей графиков
- PrintText(15, h - 30, 0, 0, 0, "H[u]");
- PrintText(w - 10, y - 15, 0, 0, 0, "u");
- //Построение штрихов на горизонтальной оси
- for (u = 0; u < N; u++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * u / N, y + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * u / N, y - 5);
- glEnd();
- PrintText(5 + mast_x * u / N, y - 17, 0, 0, 0, to_string(u));
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * u / N, y + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * u / N, y - 5);
- glEnd();
- PrintText(5 + mast_x * u / N, y - 17, 0, 0, 0, to_string(u));
- }
- //Построение штрихов на вертикальной оси
- //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
- //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
- for (u = 1; u <= 19; u++)
- {
- if (y - u * length_y / 20 >= h - 30 - length_y)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y - u * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y - u * length_y / 20);
- glEnd();
- if (u != 0)
- {
- changer = to_string(-(y_max - y_min) / 20 * u);
- if (-(y_max - y_min) / 20 * u + floor(-(y_max - y_min) / 20 * u) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length()-changer.find(","));
- }
- PrintText(15, y - u * length_y / 20 - 5, 0, 0, 0, changer);
- }
- }
- else
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y + (20 - u) * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y + (20 - u) * length_y / 20);
- glEnd();
- changer = to_string((y_max - y_min) / 20 * (20 - u));
- if ((y_max - y_min) / 20 * (20 - u) - floor((y_max - y_min) / 20 * (20 - u)) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- PrintText(15, y + (20 - u) * length_y / 20 - 5, 0, 0, 0, changer);
- }
- }
- //Построение графиков
- for (u = 0; u < N; u++)
- {
- glBegin(GL_LINES); //H[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + u * mast_x / N, y);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (u) * mast_x / N, y + H[u] * mast_y);
- glEnd();
- glPointSize(5);
- glBegin(GL_POINTS); //H[k] - выделение точек
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * u / N, y + H[u] * mast_y);
- glEnd();
- }
- ScreenShot2(w, h);
- glutSwapBuffers();
- }
- //Подпрограмма, показывающая текст на экране (для расположения координат и названий осей графиков)
- void PrintText(float x, float y, int r, int g, int b, string string)
- {
- char *text = new char[string.length()];
- glColor3f(r, g, b);
- glRasterPos2f(x, y);
- for (int i = 0; i < string.length(); i++)
- text[i] = string[i];
- for (int i = 0; i < string.length(); i++)
- {
- glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[i]);
- x += 2;
- }
- delete[] text;
- }
- void reshape(int w, int h) //TODO: понять, почему только при её наличии появляется графика и как после закрытия графики продолжить работу программы
- {
- glViewport(0, 0, w, h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0, w, 0, h);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- void ScreenShot1(int W, int H)
- {
- FILE *F = fopen("C:\\test\\Graphs1.bmp", "w");
- if (F == NULL)
- {
- cout << "Файл для записи частотного графика массива H[u] открыть/создать не удалось." << endl;
- return;
- }
- const int imSize = W * H * 3;
- unsigned char *image = new unsigned char[imSize];
- if (!image) //Проверка, выделилиась ли память
- {
- cout << "Не удалось выделить память под массивы." << endl;
- return;
- }
- memset(image, 0, imSize);
- glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- BITMAPINFO bmi;
- unsigned char BMI = sizeof(BITMAPINFOHEADER);
- unsigned char BMF = sizeof(BITMAPFILEHEADER);
- memset(&bmi, 0, BMI);
- bmi.bmiHeader.biSize = BMI;
- bmi.bmiHeader.biHeight = H;
- bmi.bmiHeader.biWidth = W;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 24;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = imSize;
- int nBitsOffset = BMF + BMI;
- LONG lImageSize = imSize;
- LONG lFileSize = nBitsOffset + lImageSize;
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 0x4D42;
- bmfh.bfOffBits = nBitsOffset;
- bmfh.bfSize = lFileSize;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, BMF, F);
- UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, BMI, F);
- UINT nWrittenDIBDataSize = fwrite(image, 1, imSize, F);
- UINT total = nWrittenDIBDataSize + nWrittenInfoHeaderSize + nWrittenFileHeaderSize;
- delete[]image;
- fclose(F);
- }
- void ScreenShot2(int W, int H)
- {
- FILE *F = fopen("C:\\test\\Graphs2.bmp", "w");
- if (F == NULL)
- {
- cout << "Файл для записи частотного графика массива H[u] открыть/создать не удалось." << endl;
- return;
- }
- const int imSize = W * H * 3;
- unsigned char *image = new unsigned char[imSize];
- if (!image) //Проверка, выделилиась ли память
- {
- cout << "Не удалось выделить память под массивы." << endl;
- return;
- }
- memset(image, 0, imSize);
- glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- BITMAPINFO bmi;
- unsigned char BMI = sizeof(BITMAPINFOHEADER);
- unsigned char BMF = sizeof(BITMAPFILEHEADER);
- memset(&bmi, 0, BMI);
- bmi.bmiHeader.biSize = BMI;
- bmi.bmiHeader.biHeight = H;
- bmi.bmiHeader.biWidth = W;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biBitCount = 24;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biSizeImage = imSize;
- int nBitsOffset = BMF + BMI;
- LONG lImageSize = imSize;
- LONG lFileSize = nBitsOffset + lImageSize;
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 0x4D42;
- bmfh.bfOffBits = nBitsOffset;
- bmfh.bfSize = lFileSize;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, BMF, F);
- UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, BMI, F);
- UINT nWrittenDIBDataSize = fwrite(image, 1, imSize, F);
- UINT total = nWrittenDIBDataSize + nWrittenInfoHeaderSize + nWrittenFileHeaderSize;
- delete[]image;
- fclose(F);
- }
Add Comment
Please, Sign In to add comment