Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- //#define _PDF_DRAW_TO_BITMAP
- #include <iostream>
- #include <math.h>
- #include <string>
- #include <fstream>
- #include <GL/freeglut.h>
- #include <windows.h>
- using namespace std;
- double const pi = 4 * atan(1);
- 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); //Подпрограмма создания массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- 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 H); //Подпрограмма, сохраняющая графики 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[])
- {
- ifstream in;
- setlocale(LC_ALL, "RUSSIAN");
- string key, key1, N1, x, temps, w1, h1;
- int k, flag;
- int i;
- cout << "Программа для преобразования массива X[k] в массив H[u] по формуле дискретного преобразования Хартли и массива H[u] Xобр[k] по формуле обратного преобразования Хартли" << endl;
- while (1)
- {
- cout << "Выберите режим работы программы:\n1 - ввод элементов массива с клавиатуры.\n2 - создание массива на основе файла.\n0 - выход из программы.\nПримечание: название файла: \"C:\\test\\KursovayaInput.txt\"" << endl << "Выбрано ";
- getline(cin, key);
- if (key == "1")
- {
- flag = 0;
- k = 0;
- cout << "Введите размерность массива, который хотите заполнить" << endl << "N = ";
- cin >> N1;// Ввод размера массива
- size_t number1 = N1.find_first_not_of("0123456789");
- if (number1 != std::string::npos)// Если найдено что-то помимо цифр
- {
- cout << "Введённое значение не является числом целого типа. Возврат в последнее меню." << endl;
- cin.ignore();
- continue;
- }
- N = stoi(N1.c_str()); //Получение количества элементов массива
- X = new double[N]; //Создание динамических массивов (эта и две след. строки)
- Xobr = new double[N];
- H = new double[N];
- cout << "Введите с клавиатуры значения элементов массива X[k]. После введения числа нажмите Enter.\n";
- while ((k < N))// Заполнение массива X[k]
- {
- cin >> temps;
- From_String_To_Double(&flag, temps, &k, X, &N); //Вызов функции, создающей элемент массива X[k] на основе строки
- if (flag == 1)
- {
- cin.ignore();
- break;
- }
- }
- if (flag == 0)
- {
- Creating_Arrays_H_and_Xobr(X, H, Xobr, &N); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- }
- if (flag == 0)
- {
- Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
- /*cout << "Введите размеры окна, в котором будут показаны графики функций." << endl << "Окно не должно быть меньше чем 16x153, иначе оно не создастся." << endl << "Введённые данные должны быть целыми числами." << endl;;
- cout << "Ширина: ";
- cin >> w1; //Ввод ширины
- cout << "Высота: ";
- cin >> h1; //Ввод высоты
- size_t w_check = w1.find_first_not_of("0123456789");
- size_t h_check = h1.find_first_not_of("0123456789");
- if (w_check != std::string::npos || h_check != std::string::npos)// Если найдено что-то помимо цифр
- {
- cout << "Введённое значение не является числом целого типа. Возврат в последнее меню." << endl;
- cin.ignore();
- continue;
- }
- w = stoi(w1.c_str()); //Получения ширины
- h = stoi(h1.c_str()); //Получения высоты
- if (w < 16 || h < 153)
- {
- cout << "Введенные размеры меньше допустимых. Возврат в меню." << endl;
- cin.ignore();
- continue;
- }*/
- 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]
- glutMainLoop();
- //Создание окна для рисования частотного графика 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]
- glutMainLoop();
- cin.ignore();
- }
- delete[] X;//Очистка памяти от динамических массивов (эта и дву след. строки)
- delete[] H;
- delete[] Xobr;
- }
- else if (key == "2")
- {
- 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];
- 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;
- }
- getline(in, x);
- } while (x != "");
- if ((k < N)) //Если в файле оказалось чисел больше или меньше заявленного
- {
- cout << "В файле количество элементов, который нужно записать в массив X, меньше заявленного количества элементов.\n";
- }
- else if (flag == 0)
- {
- Creating_Arrays_H_and_Xobr(X, H, Xobr, &N); //Создание массивов H[u] из массива X[k] и массива X(обратное)[k] из массива H[u]
- }
- }
- in.close(); //Закрытие файла ввода
- Printing_Arrays_into_Files(X, H, Xobr, &N); //Вывод массивов в файл
- /*cout << "Введите размеры окна, в котором будут показаны графики функций." << endl << "Окно не должно быть меньше чем 16x153, иначе оно не создастся." << endl << "Введённые данные должны быть целыми числами." << endl;;
- cout << "Ширина: ";
- cin >> w1; //Ввод ширины
- cout << "Высота: ";
- cin >> h1; //Ввод высоты
- size_t w_check = w1.find_first_not_of("0123456789");
- size_t h_check = h1.find_first_not_of("0123456789");
- if (w_check != std::string::npos || h_check != std::string::npos)// Если найдено что-то помимо цифр
- {
- cout << "Введённое значение не является числом целого типа. Возврат в последнее меню." << endl;
- cin.ignore();
- continue;
- }
- w = stoi(w1.c_str()); //Получения ширины
- h = stoi(h1.c_str()); //Получения высоты
- if (w < 16 || h < 153)
- {
- cout << "Введенные размеры меньше допустимых. Возврат в меню." << endl;
- cin.ignore();
- continue;
- }*/
- 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);
- glutDisplayFunc(Graphics_Creation1); //Подпрограмма, рисующая графики массивов X[k], H[u] и X(обратное)[k]
- glutMainLoop();
- //Создание окна для рисования частотного графика 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]
- glutMainLoop();
- //cin.ignore(); - нужна только если размеры окна вводятся с клавиатуры
- delete[] X;//Очистка памяти от динамических массивов (эта и две след. строки)
- delete[] H;
- delete[] Xobr;
- }
- 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) //Подпрограмма создания массивов 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] * (sin(2 * pi*k*u / *N) + cos(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] * (sin(2 * pi*k*u / *N) + cos(2 * pi*k*u / *N));
- }
- Xobr[k] = Xobr[k] / sqrt(*N);
- if (fabs(Xobr[k] - X[k]) > 0.00001)
- {
- cout << "Произошла ошибка в вычислениях.\n";
- break;
- }
- cout << "Xobr[" << k << "] = " << Xobr[k] << "\n";
- }
- }
- 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 - 110) / 2);
- double y_max[2], y_min[2], length;
- int k, i, y[2];
- int mast_y[2];
- int 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();
- if (k == 1) //Находим наибольший и наименьший элементы X[k]
- {
- y_max[0] = 200;
- y_min[0] = -200;
- 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]
- {
- y_max[1] = 200;
- y_min[1] = -200;
- 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 = fabs(y_max[k - 1] - y_min[k - 1]);
- mast_y[k - 1] = floor(length_y / (length)); //Масштаб оси ординат по кол-ву точек
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length));
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length) - 5);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length) + 5);
- glEnd();
- y[k - 1] = h - 30 * k - length_y * (k - 1) - floor(length_y * y_max[k - 1] / length);
- }
- //Подписывание осей графиков
- 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++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[0] + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[0] - 5);
- glEnd();
- PrintText(5 + mast_x * k / N, y[0] - 17, 0, 0, 0, to_string(k));
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[1] + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y[1] - 5);
- glEnd();
- PrintText(5 + mast_x * k / N, y[1] - 17, 0, 0, 0, to_string(k));
- }
- //Построение штрихов на вертикальной оси
- //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
- //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
- for (k = 0; k <= 20; k++)
- {
- if (y[0] - k * length_y / 20 >= h - 30 - length_y)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[0] - k * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[0] - k * length_y / 20);
- glEnd();
- changer = to_string(-(y_max[0] - y_min[0]) / 20 * k);
- if (-(y_max[0] - y_min[0]) / 20 * k + floor(-(y_max[0] - y_min[0]) / 20 * k) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- if (k != 0)
- {
- PrintText(15, y[0] - k * length_y / 20-5, 0, 0, 0, changer);
- }
- }
- else
- {
- for (i = 1; i <= 20 - k; i++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[0] + i * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[0] + i * length_y / 20);
- glEnd();
- changer = to_string((y_max[0] - y_min[0]) / 20 * i);
- if ((y_max - y_min) / 20 * i - floor((y_max - y_min) / 20 * i) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- PrintText(15, y[0] + i * length_y / 20-5, 0, 0, 0, changer);
- }
- }
- if (y[1] - k * length_y / 20 >= h - 60 - 2 * length_y)
- {
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[1] - k * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[1] - k * length_y / 20);
- glEnd();
- changer = to_string(-(y_max[1] - y_min[1]) / 20 * k);
- if (-(y_max[1] - y_min[1]) / 20 * k + floor(-(y_max[1] - y_min[1]) / 20 * k) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- if (k != 0)
- {
- PrintText(15, y[1] - k * length_y / 20-5, 0, 0, 0, changer);
- }
- }
- else
- {
- for (i = 1; i <= 20 - k; i++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y[1] + i * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y[1] + i * length_y / 20);
- glEnd();
- changer = to_string((y_max[1] - y_min[1]) / 20 * i);
- if ((y_max[1] - y_min[1]) / 20 * i - floor((y_max[1] - y_min[1]) / 20 * i) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- PrintText(15, y[1] + i * length_y / 20-5, 0, 0, 0, changer);
- }
- break;
- }
- }
- //Построение графиков
- 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] + floor(X[k] * mast_y[0]));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (k + 1) * mast_x / N, y[0] + floor(X[k + 1] * mast_y[0]));
- glEnd();
- }
- if (k != N - 1)
- {
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + k * mast_x / N, y[1] + floor(Xobr[k] * mast_y[1]));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (k + 1) * mast_x / N, y[1] + floor(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] + floor(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] + floor(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;
- double y_max, y_min, length;
- int k, i, y;
- int mast_y;
- int 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 = fabs(y_max - y_min);
- mast_y = floor(length_y / (length)); //Масштаб оси ординат по кол-ву точек
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5, h - 30 - floor(length_y * y_max / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 - floor(length_y * y_max / length));
- glEnd();
- glBegin(GL_LINES); //Черчение стрелки
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 - floor(length_y * y_max / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, h - 30 - floor(length_y * y_max / length) - 5);
- glEnd();
- glBegin(GL_LINES);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w, h - 30 - floor(length_y * y_max / length));
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(w - 10, h - 30 - floor(length_y * y_max / length) + 5);
- glEnd();
- y = h - 30 - floor(length_y * y_max / length);
- //Подписывание осей графиков
- PrintText(15, h - 30, 0, 0, 0, "H[u]");
- PrintText(w - 10, y - 15, 0, 0, 0, "u");
- //Построение штрихов на горизонтальной оси
- for (k = 0; k < N; k++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y - 5);
- glEnd();
- PrintText(5 + mast_x * k / N, y - 17, 0, 0, 0, to_string(k));
- glBegin(GL_LINES); //X(обратный)[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y + 5);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y - 5);
- glEnd();
- PrintText(5 + mast_x * k / N, y - 17, 0, 0, 0, to_string(k));
- }
- //Построение штрихов на вертикальной оси
- //Количество штрихов фиксированно - 20. При -200<=y<=200 шаг равен 20. Иначе - меняется.
- //Если заменить 20 на N, число штрихов по вертикали станет равным числу штрихов по горизонтали
- for (k = 0; k <= 20; k++)
- {
- if (y - k * length_y / 20 >= h - 30 - length_y)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y - k * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y - k * length_y / 20);
- glEnd();
- if (k != 0)
- {
- changer = to_string(-(y_max - y_min) / 20 * k);
- if (-(y_max - y_min) / 20 * k + floor(-(y_max - y_min) / 20 * k) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length()-changer.find(","));
- }
- PrintText(15, y - k * length_y / 20 - 5, 0, 0, 0, changer);
- }
- }
- else
- {
- for (i = 1; i <= 20 - k; i++)
- {
- glBegin(GL_LINES); //X[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(0, y + i * length_y / 20);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(10, y + i * length_y / 20);
- glEnd();
- changer = to_string((y_max - y_min) / 20 * i);
- if ((y_max - y_min) / 20 * i - floor((y_max - y_min) / 20 * i) <= 0.000001)
- {
- changer.erase(changer.find(","), changer.length() - changer.find(","));
- }
- PrintText(15, y + i * length_y / 20 - 5, 0, 0, 0, changer);
- }
- break;
- }
- }
- //Построение графиков
- for (k = 0; k < N; k++)
- {
- glBegin(GL_LINES); //H[k]
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + k * mast_x / N, y);
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + (k) * mast_x / N, y + floor(H[k] * mast_y));
- glEnd();
- glPointSize(5);
- glBegin(GL_POINTS); //H[k] - выделение точек
- glColor3f(0.0, 0.0, 0.0);
- glVertex2i(5 + mast_x * k / N, y + floor(H[k] * 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)
- {
- const int imSize = W * H * 3;
- unsigned char *image = new unsigned char[imSize];
- memset(image, 0, imSize);
- glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- 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;
- FILE *F = fopen("C:\\test\\Graphs1.bmp", "w");
- int nBitsOffset = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- LONG lImageSize = imSize;
- LONG lFileSize = nBitsOffset + lImageSize;
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 'B' + ('M' << 8);
- bmfh.bfOffBits = nBitsOffset;
- bmfh.bfSize = lFileSize;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, sizeof(BITMAPFILEHEADER), F);
- UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, sizeof(BITMAPINFOHEADER), F);
- UINT nWrittenDIBDataSize = fwrite(image, 1, imSize, F);
- UINT total = nWrittenDIBDataSize + nWrittenInfoHeaderSize + nWrittenFileHeaderSize;
- delete[]image;
- fclose(F);
- }
- void ScreenShot2(int W, int H)
- {
- const int imSize = W * H * 3;
- unsigned char *image = new unsigned char[imSize];
- memset(image, 0, imSize);
- glReadPixels(0, 0, W, H, GL_RGB, GL_UNSIGNED_BYTE, image);
- BITMAPINFO bmi;
- memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- 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;
- FILE *F = fopen("C:\\test\\Graphs2.bmp", "w");
- int nBitsOffset = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- LONG lImageSize = imSize;
- LONG lFileSize = nBitsOffset + lImageSize;
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 'B' + ('M' << 8);
- bmfh.bfOffBits = nBitsOffset;
- bmfh.bfSize = lFileSize;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, sizeof(BITMAPFILEHEADER), F);
- UINT nWrittenInfoHeaderSize = fwrite(&bmi, 1, sizeof(BITMAPINFOHEADER), 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